Android自定义组件不显示其子级 [英] Android custom component doesn't display its children

查看:114
本文介绍了Android自定义组件不显示其子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我想在Android中创建一个FieldSet组件. (类似于html),例如.因此,我希望我的自定义组件有孩子并有一块木板.电路板零件已经完成,但是在显示组件时遇到一些问题.我正在关注答案.这是我的部分:

Hi guys I want to create a FieldSet component in Android. (similar to html) so something like that. So I want my custom component to have children and to have a board. The board part is done already, but I have some issues with display the component. I'm following this answer. Here're my parts:

FieldSet.java :

public class FieldSet extends ViewGroup {

  //... 3 constructors

  @Override
  protected void onFinishInflate()
    int index = getChildCount();
    // Collect children declared in XML.
    View[] children = new View[index];
    while(--index >= 0) {
      children[index] = getChildAt(index);
    }
    // Pressumably, wipe out existing content (still holding reference to it).
    this.detachAllViewsFromParent();
    // Inflate new "template".
    final View template = LayoutInflater.from(getContext()).inflate(R.layout.field_set, this, true);
    // Obtain reference to a new container within "template".
    final ViewGroup vg = (ViewGroup)template.findViewById(R.id.field_set_content);
    index = children.length;
    // Push declared children into new container.
    while(--index >= 0) {
      vg.addView(children[index]);
    }
  }

field_set.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:duplicateParentState    ="true"
    android:layout_height="wrap_content">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:id="@+id/field_set_content"
        android:duplicateParentState    ="true"
        android:background="@drawable/field_set_frame"
        android:orientation="vertical"
        android:padding="20dp">
    </RelativeLayout>
    <!--  This is the title label -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:paddingLeft="50dp"
        android:paddingRight="50dp"
        android:layout_marginRight="50dp"
        android:layout_centerHorizontal="true"
        android:text="Label"
        android:background="@color/colorLoginBlue"
        android:padding="5dp"
        android:id="@+id/field_set_label"
        android:textColor="@color/colorSmallTxt" />
</RelativeLayout>

Android Studio上方的布局预览(似乎组件的布局完全没问题):

Android studio above's layout preview (seems like component's layout is completely fine):

这是我的添加方式:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:fs="http://schemas.android.com/apk/res-auto"
    tools:context="my.package.DeleteThis">
    <my.package.FieldSet
        android:layout_width="match_parent"
        fs:label="Injected Label"
        android:layout_height="wrap_content"
        android:gravity="bottom">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50sp"
            android:text="Inner text" />
    </my.package.FieldSet>
<TextView
    android:layout_width="match_parent"
    android:text="BELOW"
    android:layout_height="wrap_content" />
</RelativeLayout>

Android Studio预览在下面. (因此,布局占用了孩子所需的所有空间.还请注意,组件树显示组件TextView已添加到布局中,应按其原样.尽管如此,孩子的高度和宽度为0:

Android studio preview is below. (So the layout takes all space that children need. Also note that component tree shows that component TextView is added as to Layout as it should be . Nevertheless children have 0 height and width:

field_set_frame.xml :

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle" >
            <corners android:radius="7dp" />
            <padding android:bottom="2dp"/>
            <padding android:right="2dp"/>
            <padding android:left="2dp"/>
            <padding android:top="2dp"/>
            <stroke android:width="1dp" android:color="@color/colorFieldSetBorder" />
        </shape>
    </item>
</selector>

结果: 只是一无所有:(,没有评论)

RESULT: Just nothing:(, no comments)

我还阅读了答案,并尝试了它,但是addView并没有帮助-它会导致递归,而当我使用addToRoot=True时则不需要.我尝试使用LinearLayout而不是Relative-不会更改任何内容.我想我在LayoutInflater.from(getContext()) .inflate(R.layout.field_set, this, true);中的某个地方搞砸了.还值得指出的是,孩子们占据了地方.因此,基本上,如果我增加放入FieldSet组件中的内容的高度,它将占用更多的高度,并将下面的所有组件向下推.我感到这种Visibility问题.或某层低于另一层,孩子的高度和宽度仍为零.有什么建议吗?

I also read this answer and tried it, but addView didnt help - it causes recursion and it's not needed when I use addToRoot=True. I tried LinearLayout, instead of Relative - doesnt change anything. I think I screw up somewhere in LayoutInflater.from(getContext()) .inflate(R.layout.field_set, this, true);. It's also worth to point out that children occupy place. So basically if I increase the height of content that I put into my FieldSet component, it will take more height and push all components that are beneath down. I smeel this kinda of Visibility issue. Or some layer goes below another one, still height and width of chidren are zeros. Any suggestions?

任何帮助都将不胜感激.

Any kind of help is greatly appreciated.

最诚挚的问候,

推荐答案

直接扩展ViewGroup时,您需要自己测量和布置孩子View的布局,否则他们的尺寸或位置永远不会正确.通常,扩展已经处理了这些内容的ViewGroup子类更为简单.在这种情况下,您最好扩展RelativeLayout,因为这实际上是保存内部View的内容,而ViewGroup包装它是不必要的.

When extending ViewGroup directly, you need to handle measuring and laying out the child Views yourself, or they never get sized or positioned correctly. Oftentimes, it's simpler to extend a ViewGroup subclass that already handles that stuff. In this case, you might as well extend RelativeLayout, since that's what's actually holding the internal Views, and the ViewGroup wrapping it is rather unnecessary.

内部布局XML中的父级RelativeLayout然后是多余的,并且可以替换为<merge>标记,这将导致子级View在膨胀时直接添加到您的RelativeLayout子类中. /p>

The parent RelativeLayout in the internal layout XML is then redundant, and can be replaced with <merge> tags, which will cause the child Views to be added directly to your RelativeLayout subclass when inflated.

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <RelativeLayout
        android:id="@+id/field_set_content"
        ... />

    <TextView
        android:id="@+id/field_set_label"
        ... />

</merge>

我们可以通过在构造函数中设置内部结构,并在添加子级View时将其放置在正确的位置来进一步简化事情,而不是在onFinishInflate()中将所有内容混为一谈.例如:

We can further simplify things by setting up the internal structure in the constructor(s), and putting the child Views in the right place as they're added, rather than juggling all of that around in onFinishInflate(). For example:

public class FieldSet extends RelativeLayout {

    final ViewGroup vg;

    public FieldSet(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater.from(context).inflate(R.layout.field_set, this, true);
        vg = (ViewGroup) findViewById(R.id.field_set_content);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        final int id = child.getId();
        if (id == R.id.field_set_content || id == R.id.field_set_label) {
            super.addView(child, index, params);
        }
        else {
            vg.addView(child, index, params);
        }
    }
}

这篇关于Android自定义组件不显示其子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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