首页 > 代码库 > 继承于Layout的自定义View减少布局层次

继承于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只是需要代码动态设置布局属性来保证显示的正确。

这两个方法在我目前为止的实践中没有什么问题,希望大家多多用发现问题多拍砖,拍完一起讨论更好的解决办法。

继承于Layout的自定义View减少布局层次