自定義View冷知識之動態替換layout.xml中的View

Android - 自定義View冷知識之動態替換layout.xml中的View

在開發迭代中,有這麼一個場景:

我們給 TextView 定製了不少功能,在下一個版本,需要把程序中的所有 TextView 都替換成我自己的 CustomTextView,這個時候你會怎麼做?有沒有一種方法在不改動佈局文件的情況下就能實現動態替換呢?

原理:layout.xml -> Java 對象

首先我們知道一個 layout.xml 轉成 Java 對象,使用的是 LayoutInflater#inflate 方法。

其內部是通過 xml 解析器,解析到標籤比如: Linearlayout

  1. inflate() 會調用 createViewFromTag() 實例化 Linearlayout 對象;
  2. createViewFromTag() 方法內部使用了一個 Factory 對象;
  3. Factory 會調用 Factory#onCreateView() 來實例化這個 Linearlayout

僞代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
...
final String name = parser.getName();
...
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
}
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, boolean ignoreThemeAttr) {
...
View view;
if (mFactory2 != null) {
view = mFactory2.onCreateView(parent, name, context, attrs);
} else if (mFactory != null) {
view = mFactory.onCreateView(name, context, attrs);
} else {
view = null;
}
...
view = createView(name, null, attrs);
}

所以我只要給 LayoutInflater 設置一個我們自定義的 Factory 就可以實現動態替換View。

1
2
3
4
5
public void setFactory(Factory factory) {
}
public void setFactory2(Factory2 factory) {
}

替換方法

其實在 Activity 本身就是一個 LayoutInflater$Factory

1
2
3
4
5
6
7
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback {
}

所以我們只需要實現 Activity 的 onCreateView 就可以實現 View 的動態替換。

1
2
3
4
5
6
7
8
9
public class MyActivity extends Activity {
public View onCreateView(String name, Context context, AttributeSet attrs) {
if (name.equals("TextView")) {
return new CustomTextView(context, attrs);
}
return suqer.onCreateView(name, context, attrs);
}
}

插播廣告:OTCBTC 是目前最流暢、最靠譜、最好用的場外交易平臺,支持支付寶、微信、銀行卡支付購買BTC、ETH、EOS、USDT、QTUM、ZEC、GXS、BCH 等數字幣。現在註冊,即可領取比特幣紅包! https://otcbtc.com/referrals/904529093


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章