天天看點

繼承于Layout的自定義View減少布局層次

不管是為了封裝也好,實作特殊的效果也好,大家或多或少都會進行自定義View的實踐,這中間又主要有兩種:一種是繼承于View或ViewGroup,還有一個是繼承于各種已存在的Layout使用XML來寫。

今天要來讨論的是第二種,實踐就不詳細說了,這裡主要是針對這種方式帶來的布局層次過深的問題提出兩個方案。

第一種,注意在布局xml中使用merge,千萬不要誤解這個隻在FrameLayout時候才能用哦,這個的準确作用是在解析XML布局時由此标志位就不解析直接将這一層忽略,将下面層次的view直接添加到上一級中。是以用完之後理所當然的會布局層次會少一層。當然了,你用來封裝它的Layout需要和你本來布局XML檔案想用的容器一緻。

但是,注意了,忽略這裡的同時,關于這一級的屬性描述也會丢失,比如LinearLayout的orientation屬性,比如gravity也會被還原成預設的,還有很多關鍵的屬性哦,這就需要在封裝類中通過代碼來進行設定(為什麼封裝它的Layout需要和你本來布局XML檔案想用的容器一緻也是這個原因),千萬不要忘記咯,不然出來的效果會很有問題的。

第二種,和上面的思想差不多,隻不過是在代碼中将多餘的這一層去掉,先将一個封裝類中的第一個子View擷取出來,然後将封裝類子View清空,最後将這個子View添加到上一級的ViewGroup中去,這樣View層次就減少了,但是作為接口封裝特性的封裝類接口依然可以保持。

最後呢,一些情況下上面兩種方法可以同時使用的哦,效果很明顯。

舉一個例子吧,把這兩種情況都用上。

WrapperView.java
public class WrapperView extends FrameLayout {

    public WrapperView(Context context) {
        super(context);
        mContext = context;
//        setGravity(Gravity.CENTER_HORIZONTAL);
        init();
    }

    /**
     * @Description<br>初始化
     */
    private void init() {
        inflate(mContext, R.layout.info, this);
    }

    public void Fun1(Object o) {
        
    }
    
    public void Fun2(Object o) {
        
    }
}
           
info.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            .................
        </LinearLayout>
    </ScrollView>

</merge>  
           
DemoActivity.java
public class DemoActivity extends Activity {
	private WrapperView mFView;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mFView = new WrapperView(this);
		View view = mFView.getChildAt(0);
		mFView.removeView(view);
		setContentView(view);
	}
}
           

這個例子比較簡單的,不巧的是正好都是用的FrameLayout,希望沒有給大家造成隻能用這個的誤解。其他的Layout隻是需要代碼動态設定布局屬性來保證顯示的正确。

這兩個方法在我目前為止的實踐中沒有什麼問題,希望大家多多用發現問題多拍磚,拍完一起讨論更好的解決辦法。