我想在我的案例中实现自定义 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
- 没有添加到他们的父 ViewGroup
与 addView(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/