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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11198026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:11:37  来源:igfitidea点击:

Android: Multiple view children for custom view with existing layout

javaandroidxmlandroid-layoutandroid-custom-view

提问by mreichelt

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

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

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

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

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

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

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...

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

Thanks a lot in advance for your help! :)

非常感谢您的帮助!:)

回答by Devunwired

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

创建自定义容器视图是绝对可能的,并且受到鼓励。这就是 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);
        }
    }
}

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.

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

And then modify the XML as such:

然后像这样修改 XML:

res/layout/custom_layout.xml

res/layout/custom_layout.xml

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

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 RelativeLayoutattached to another RelativeLayoutattached to all the children, which can cause issues.

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

HTH

HTH

回答by Nirali

you can use include tag

你可以使用包含标签

<?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>