Android自定义组件不显示其子项

时间:2016-12-08 22:52:07

标签: android android-custom-view custom-component layout-inflater

大家好我想在Android中创建一个FieldSet组件。 (类似于html),类似于that。所以我希望我的自定义组件有孩子和有一个板。电路板部分已经完成,但是我在显示组件时遇到了一些问题。我正在关注this回答。这是我的部分:

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上面的布局预览(看起来组件的布局完全没问题):

enter image description here

以下是我添加的方式

<?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工作室预览如下。 (因此布局占用了孩子们需要的所有空间。另请注意,组件树显示组件TextView被添加为布局,因为它应该。但是,子项的高度和宽度为0:< / p>

enter image description here

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 : 什么都不是:(,没有评论)

enter image description here

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

非常感谢任何形式的帮助。

致以最诚挚的问候,

1 个答案:

答案 0 :(得分:3)

直接延长ViewGroup时,您需要自己处理孩子View的测量和布局,或者他们的尺寸或定位不正确。通常,扩展已经处理过这些东西的ViewGroup子类更简单。在这种情况下,你也可以扩展RelativeLayout,因为它实际上持有内部View,而ViewGroup包裹它是相当不必要的。

内部布局XML中的父RelativeLayout是多余的,可以使用<merge>标记替换,这会导致将子View直接添加到您的{{} 1}}膨胀时的子类。

RelativeLayout

我们可以通过在构造函数中设置内部结构来进一步简化事情,并将子<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()