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 above's layout preview (seems like component's layout is completely fine):
Here's how I add it:
<?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 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)
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.
Best regards,
When extending
ViewGroup
directly, you need to handle measuring and laying out the childView
s yourself, or they never get sized or positioned correctly. Oftentimes, it's simpler to extend aViewGroup
subclass that already handles that stuff. In this case, you might as well extendRelativeLayout
, since that's what's actually holding the internalView
s, and theViewGroup
wrapping it is rather unnecessary.The parent
RelativeLayout
in the internal layout XML is then redundant, and can be replaced with<merge>
tags, which will cause the childView
s to be added directly to yourRelativeLayout
subclass when inflated.We can further simplify things by setting up the internal structure in the constructor(s), and putting the child
View
s in the right place as they're added, rather than juggling all of that around inonFinishInflate()
. For example: