標籤:
關於自訂屬性,我們用的比較多的時候就是在自訂view的時候了,其實自訂屬性還有一些其餘的妙用。
這裡講解一個利用自訂的屬性為應用程式全域的替換背景的例子。1.Android裡面使用自訂屬性的執行個體
可能我們在使用ToolBar的時候見過很多次的這種使用方式了。
<android.support.v7.widget.Toolbar style="@style/ToolBarStyle"xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" />
在確定ToolBar的寬度和背景色的時候,並沒有在xml檔案裡面去寫死,而是讀取的Google自訂的屬性值。
我們會好奇,這樣怎麼就能擷取到值呢,這個屬性是在哪裡有定義的呢,關於怎麼拿到值是另外一個問題了,現在來說一下這個值是在哪裡定義的,並且在哪裡賦的初始值的。
首先找到我們當前項目的Theme,我的當前的項目的Theme的parent是Theme.AppCompat.Light.DarkActionBar,找到它的parent,點進去,這裡面就是Android內部的res\values裡面的一些主題,屬性等等。
在裡面搜尋actionBarSize和colorPrimary這個屬性。
然後再看這個屬性的declare-styleable的名字
好吧,其實不需要知道declare-styleable的名字,跟這個沒什麼關係。
這裡我們知道Android的values裡面確實有這些屬性的定義,並不是憑空想象出來的,然後有了定義我們使用之前肯定要對這些屬性賦值啊,指望開發人員對其賦值有可能開發人員並不知道這個東西的呢,所以呢,values裡面肯定有賦值的操作,我們繼續找。
從哪找起呢,當然是從我們的Theme的parent找起了,前面說了當前的程式的主題是繼承Theme.AppCompat.Light.DarkActionBar的。
我們就去找到對應的賦值操作。最終發現主題是繼承Theme.Light,當然中間還繼承了很多層,可以自行查看。
可以看到這裡面是對colorPrimary進行了賦值操作的。
actionBarSize的賦值在Base.V7.Theme.AppCompat.Light裡面。
所以綜上所述的一些知識我們知道,如果我們想在xm裡面像android:background=”?attr/colorPrimary”這樣的使用自訂的一些屬性做一些操作的話也非常簡單,只需要三步就可以了。
步驟:
第一步,定義屬性第二步,給自訂的屬性賦值第三步,使用自訂的屬性值2.執行個體講解一個關於自訂屬性的妙用
現在有一個需求是這樣的,當前的程式為了風格統一,所有的介面需要一個統一的背景圖或者背景色,並且這個背景圖或者背景色是可以自由定製的,就是說可以在style檔案裡面自由配置。那這個時候自訂屬性就非常方便的可以完成這個效果了。
三個步驟:
2.1.定義自訂的屬性
在values裡面建立attrs.xml檔案,裡面定義自訂屬性。
代碼也貼這裡:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="App_Attrs"> <!-- 預設背景圖 --> <attr name="baseBackground" format="color|reference"/> </declare-styleable></resources>
2.2.給自訂的屬性賦值
需要我們在當前程式的Theme裡面對這個屬性賦值。
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="baseBackground">@android:color/holo_green_light</item> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style></resources>
賦值也完成了。
2.3.使用自訂的屬性值
由於我們當前的程式的所有的介面都需要使用這樣的背景色,那麼我們可以定義一個自己的baseActivity,裡面對setContentView作一個簡單的處理。
2.3.1.建立base_layout的xml布局
base_layout.xml
<?xml version="1.0" encoding="utf-8"?><FrameLayout android:id="@+id/base_layout_container"xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?attr/baseBackground"></FrameLayout>
裡面引用了自訂的屬性值。
2.3.2.baseActivity的代碼:
public class BaseActivity extends AppCompatActivity { FrameLayout mBaseContainerView; @Override public void setContentView(@LayoutRes int layoutResID) {setContentView(getLayoutInflater().inflate(layoutResID, null)); } @Override public void setContentView(View view) { setContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { mBaseContainerView = (FrameLayout) getLayoutInflater().inflate(R.layout.base_layout, null); Drawable bg = view.getBackground(); if (bg != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { findViewById(R.id.base_layout_container).setBackground(bg); view.setBackground(null); } else { findViewById(R.id.base_layout_container).setBackgroundDrawable(bg); view.setBackgroundDrawable(null); } } FrameLayout.LayoutParams p = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); mBaseContainerView.addView(view, p); super.setContentView(mBaseContainerView, params); }}
代碼裡面對setContentView方法作了簡單的處理。
2.3.3.MainActivity裡面直接使用就可以看到背景色已經發生改變
public class MainActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
有圖有真相:
Demo地址:http://download.csdn.net/detail/qy274770068/9499356
Android自訂屬性為應用程式設定全域背景