Android:具有现有布局的自定义视图的多个视图子项

时间:2012-06-25 22:02:42

标签: java android xml android-layout android-custom-view

我必须在Android中构建更复杂的自定义视图。最终布局应如下所示:

<RelativeLayout>
  <SomeView />
  <SomeOtherView />
  <!-- maybe more layout stuff here later -->
  <LinearLayout>
    <!-- the children -->
  </LinearLayout>
</RelativeLayout>

但是,在XML文件中我只想定义它(不定义SomeView,SomeOtherView等):

<MyCustomView>
  <!-- the children -->
</MyCustomView>

这在Android中是否可行,如果是的话:最干净的方法是什么? 我想到的可能的解决方案是“覆盖addView()方法”和“删除所有视图并在以后再次添加它们”,但我不确定要走哪条路......

非常感谢您的帮助! :)

2 个答案:

答案 0 :(得分:50)

绝对可以并且鼓励创建自定义容器视图。这就是Android所谓的复合控件。所以:

public class MyCustomView extends RelativeLayout {
    private LinearLayout mContentView;

    public MyCustomView(Context context) {
        this(context, null);
    }

    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        //Inflate and attach your child XML
        LayoutInflater.from(context).inflate(R.layout.custom_layout, this);
        //Get a reference to the layout where you want children to be placed
        mContentView = (LinearLayout) findViewById(R.id.content);

        //Do any more custom init you would like to access children and do setup
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        if(mContentView == null){
            super.addView(child, index, params);
        } else {
            //Forward these calls to the content view
            mContentView.addView(child, index, params);
        }
    }
}

您可以根据需要覆盖addView()的多个版本,但最后它们都会回调我放在示例中的版本。覆盖此方法将使框架将在其XML标记内找到的所有子项传递给特定的子容器。

然后修改XML:

<强> RES /布局/ custom_layout.xml

<merge>
  <SomeView />
  <SomeOtherView />
  <!-- maybe more layout stuff here later -->
  <LinearLayout
      android:id="@+id/content" />
</merge>

使用<merge>的原因是为了简化层次结构。所有子视图都将附加到您的自定义类,即RelativeLayout。如果您不使用<merge>,则最终会将RelativeLayout附加到与所有孩子相关联的另一个RelativeLayout,这可能会导致问题。

HTH

答案 1 :(得分:-3)

您可以使用包含标记

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical">
    <include android:id="@+id/nav_bar_layout" layout="@layout/nav_bar" android:layout_above="@+id/web_view" />
    <WebView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/web_view" android:layout_centerInParent="true" />
    <include android:id="@+id/admob_layout" layout="@layout/admob_layout" android:layout_below="@+id/web_view" />
</RelativeLayout>