Android:具有现有布局的自定义视图的多个视图子级 [英] Android: Multiple view children for custom view with existing layout

查看:98
本文介绍了Android:具有现有布局的自定义视图的多个视图子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to build a more complex custom view in Android. The final layout should look like this:

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

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

However, in the XML files I just want do define this (without defining SomeView, SomeOtherView etc.):

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

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

Is this possible in Android, and if yes: What would be the cleanest way to do it? The possible solutions that came to my mind were 'override the addView() methods' and 'remove all views and add them again later', but I am unsure which way to go...

非常感谢您的帮助! :)

Thanks a lot in advance for your help! :)

推荐答案

创建自定义容器视图是绝对可能的,也是鼓励这样做的方法.这就是Android所谓的复合控件.所以:

It's absolutely possible, and encouraged, to create custom container views. This is what Android would call a compound control. So:

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标记内找到的所有子代传递给特定的子代容器.

You can override as many versions of addView() as you feel are necessary, but in the end they all call back to the version I placed in the sample. Overriding just this method will have the framework pass all children found inside its XML tag to a specific child container.

然后像这样修改XML:

And then modify the XML as such:

res/layout/custom_layout.xml

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

使用<merge>的原因是为了简化层次结构.所有子视图都将附加到您的自定义类(RelativeLayout).如果不使用<merge>,最终会导致RelativeLayout附加到另一个RelativeLayout附加到所有子项上,这可能会引起问题.

The reason for using <merge> is to simplify the hierarchy. All the child views will get attached to your custom class, which is a RelativeLayout. If you don't use <merge>, you end up with a RelativeLayout attached to another RelativeLayout attached to all the children, which can cause issues.

HTH

这篇关于Android:具有现有布局的自定义视图的多个视图子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆