Android自定义 View 组委托(delegate)addView

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

我想在我的案例中实现自定义 ViewGroup 派生自 FrameLayout 但我希望从 xml 添加的所有 subview 不直接添加到此 View 中,而是添加到 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>

并且我想将所有 subview 重定向到 FrameLayout,id 为 frame_layout_child_container

所以我当然会像这样覆盖方法 addView()

  @Override
    public void addView(View child) {
        this.mFrameLayoutChildViewsContainer.addView(child);
    }

但这肯定行不通,因为这次 mFrameLayoutChildViewsContainer 没有添加到根自定义 View 。

我的想法是始终在这个容器的顶部保留一些 View frame_layout_top 并且添加到自定义组件中的所有 subview 都应该转到 frame_layout_child_container

使用自定义 View 的例子

   <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

是否可以像我描述的那样委托(delegate)将所有 View 添加到子 ViewGroup 中。

我还有其他想法,比如每次添加 View 时都使用 bringToFront() 方法以保持它们在正确的 z 轴顺序中,或者例如添加 View 时,将其保存到数组中,然后在膨胀后保存自定义 View 将所有 View 添加到此 subview FrameLayout

建议在这种情况下该怎么做,以便在每次添加新 View 时都重新展开所有布局(如果可以以其他方式实现)时不影响性能。

最佳答案

View 从布局中膨胀 - 就像你的例子 TextView - 没有添加到他们的父 ViewGroupaddView(View child),这就是为什么仅覆盖该方法对您不起作用的原因。您想要覆盖 addView(View child, int index, ViewGroup.LayoutParams params),所有其他 addView() 重载最终都会调用它。

在该方法中,检查添加的子项是否是您的两个特殊 FrameLayout 之一。如果是,让 super 类处理添加。否则,将 child 添加到您的容器 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);
        }
    }
}

关于Android自定义 View 组委托(delegate)addView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36946173/

相关文章:

c++ - 考虑到干净代码的性能,什么更好

android - 以编程方式将 View 添加到屏幕底部

android - 创建一个安卓智能应用横幅

单击操作按钮时,Android TV 如何更改 detailsFragment 数据?

android - EditText setCompoundDrawablesWithIntrinsicBounds() 在 setError() 之后不工作

java - Android:在不影响电池生命周期的情况下将数据保存在 RAM 中

android - Material Complex UI with Coordinate layout + Tablayout + Viewpager +recyclerview

Android Camera Intent 创建两个文件

python - 如何一次快速设置 Django 模型的所有实例的字段?

java - 开发人员计算机的防病毒(Symantec Endpoint)配置