Android自定义视图组委托addView

时间:2016-04-29 19:32:04

标签: android performance android-layout android-view android-custom-view

我希望在我的案例中实现从ViewGroup派生的自定义FrameLayout,但我希望从xml添加的所有子视图不会直接添加到此视图中,而是添加到此FrameLayout中自定义ViewGroup。 让我举例说明一下。

<?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"
       android:orientation="vertical">
    <FrameLayout
        android:id="@+id/frame_layout_child_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <FrameLayout
        android:id="@+id/frame_layout_top"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</merge>

我想将所有子视图重定向到标识为FrameLayout的{​​{1}}。

所以当然我像这样覆盖方法frame_layout_child_container

addView()

但是可以肯定这不起作用,因为此时 @Override public void addView(View child) { this.mFrameLayoutChildViewsContainer.addView(child); } 未添加到根自定义视图中。

我的想法是始终在此容器mFrameLayoutChildViewsContainer的顶部保留一些视图,并且添加到自定义组件中的所有子视图都应转到frame_layout_top

使用自定义视图的示例

frame_layout_child_container

因此,在这种情况下, <CustomFrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!"/> </CustomFrameLayout> 应添加到TextView

是否可以像我描述的那样委托将所有视图添加到子frame_layout_child_container中。

我还有其他一些想法,例如每次添加视图时都使用ViewGroup方法以保持正确的z轴顺序,或者例如添加视图时,将其保存到数组中,然后在膨胀自定义视图后添加所有视图给这个孩子bringToFront()

建议在这种情况下做什么,以便在每次添加新视图时都不会通过重新填充所有布局来达到性能,如果可以以其他方式实现的话。

1 个答案:

答案 0 :(得分:7)

View从布局中膨胀 - 就像您的示例TextView - 未添加到父ViewGroup addView(View child),这就是为什么覆盖该方法并没有&# 39;为你工作。您要覆盖addView(View child, int index, ViewGroup.LayoutParams params),其他所有addView()重载最终都会调用。

在该方法中,检查被添加的孩子是否是您的两个特殊FrameLayout之一。如果是,请让super类处理添加。否则,将子项添加到容器FrameLayout

public class CustomFrameLayout extends FrameLayout {

    private final FrameLayout topLayout;
    private final FrameLayout containerLayout;

    ...

    public CustomFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater.from(context).inflate(R.layout.custom, this, true);
        topLayout = (FrameLayout) findViewById(R.id.frame_layout_top);
        containerLayout = (FrameLayout) findViewById(R.id.frame_layout_child_container);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        final int id = child.getId();
        if (id == R.id.frame_layout_top || id == R.id.frame_layout_child_container) {
            super.addView(child, index, params);
        }
        else {
            containerLayout.addView(child, index, params);
        }
    }
}