Make a child view match the width of a parent scrollview - android

I have a horizontal scrollview with many EditText children. I want each of these children to be the same width of the visible area of the parent scrollview. Is this possible in XML?

You can do it writing a small helper class:
We are creating a very small class that extends EditText called FullWidthEditText like this:
package com.YOURPACKAGENAME;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import android.widget.HorizontalScrollView;
public class FullWidthEditText extends EditText {
public FullWidthEditText(Context context) { super(context);}
public FullWidthEditText(Context context, AttributeSet attrs) { super(context, attrs); }
public FullWidthEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
View parentScrollView=((View)(getParent().getParent()));
if (parentScrollView!=null) {
// check the container of the container is an HorizontallScrollView
if (parentScrollView instanceof HorizontalScrollView) {
// Yes it is, so change width to HSV's width
widthMeasureSpec=parentScrollView.getMeasuredWidth();
}
}
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
Now you have this class created, you can use it in your XML just like a normal EditText:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/horizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffff0000" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginRight="5dp"
android:orientation="horizontal" >
<com.YOURPACKAGENAME.FullWidthEditText
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/yourEditTextId">
</com.YOURPACKAGENAME.FullWidthEditText>
<com.YOURPACKAGENAME.FullWidthEditText
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</com.YOURPACKAGENAME.FullWidthEditText>
.
.
.
</LinearLayout>
</HorizontalScrollView>
You can also create it programmatically, add handlers, listeners, change text, findViewById ... etc ... just like a normal EditText.
EditText editText=new EditText(context);
FullWidthEditText fullWidthEditText=new FullWidthEditText(context);
Note that this solution works for any other Widget as well. If you need ie. a full-width button, just change extends EditText for extends Button and you got it.
You can easily customize the size, the key line is: widthMeasureSpec=parentScrollView.getMeasuredWidth(); so you can ie. make full width minus 10 or 20px, make half width, etc.
Hope it helps !

I think ViewPager should be more appropriate but maybe you can try this view hierarchy:
HorizontalScrollView (width = MATCH_PARENT, weightSum = 1)
LinearLayout (orientation = HORIZONTAL, weight = 3, weightSum = 3)
LinearLayout (page 1, orientation = VERTICAL, weight = 1)
EditText (width = MATCH_PARENT)
LinearLayout (page 2, orientation = VERTICAL, weight = 1)
EditText (width = MATCH_PARENT)
LinearLayout (page 3, orientation = VERTICAL, weight = 1)
EditText (width = MATCH_PARENT)
Note: I have not tested it.

For your EditTexts, when you set layout_width or height to match_parent, they'll match whatever size their parent is set to. But their dimensions will expand once their content will be filled with text, hence having the same width / height than the ScrollView.

Although it can be done using horizontal scrollview. I have found it is much much easier to use a view pager instead. Its also cleaner and allows for a smoother swipe in my opinion.
Add the xml
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="70dp"/>
set the pager up
mPager =(ViewPager)getActivity().findViewById(R.id.pager);
mPager .setAdapter(new CustomPagerAdapter());
mPager .setOffscreenPageLimit(6);
Adapter
public class CustomPagerAdapter extends PagerAdapter {
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View page= inflater.inflate(R.layout.page_item, container, false);
TextView textView =(TextView)page.findViewById(R.id.textView);
textView.setText("Text");
container.addView(page);
return(page);
}
#Override
public void destroyItem(ViewGroup container, int position,
Object object) {
container.removeView((View)object);
}
#Override
public int getCount() {
return 16;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals( object );
}
}

I found some edge cases where the FullWidthEditText posted by rupps didn't work, so I modified it to work in all the cases I've found:
public class FullWidthTextView extends android.support.v7.widget.AppCompatTextView
{
public FullWidthTextView( final Context context )
{
super( context );
}
public FullWidthTextView( final Context context, #Nullable final AttributeSet attrs )
{
super( context, attrs );
}
public FullWidthTextView( final Context context, #Nullable final AttributeSet attrs, final int defStyleAttr )
{
super( context, attrs, defStyleAttr );
}
#Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
{
View parentScrollView = ((View) (getParent().getParent()));
boolean needsRemeassure = false;
if( parentScrollView != null )
{
// check the container of the container is an HorizontallScrollView
if( parentScrollView instanceof HorizontalScrollView )
{
// Yes it is, so change width to HSV's width
int parentWidth = parentScrollView.getMeasuredWidth();
if( parentWidth > 0 )
{
widthMeasureSpec = parentWidth;
}
// It's possible for the parent to still have ZERO width
// in this case we must request to be remeassured
else
{
needsRemeassure = true;
}
}
}
super.onMeasure( widthMeasureSpec, heightMeasureSpec );
setMeasuredDimension( View.MeasureSpec.makeMeasureSpec( widthMeasureSpec, MeasureSpec.EXACTLY ),
View.MeasureSpec.makeMeasureSpec( getMeasuredHeight(), MeasureSpec.EXACTLY ) );
if( needsRemeassure )
{
post( new Runnable()
{
#Override
public void run()
{
requestLayout();
}
} );
}
}
}

Related

Android 1 Parent ScrollView, 3 TextView with vertical scrolling

I have a question with the android programming.
I have a parent scrollview for whole activity, and there are three textviews with scrolling function. However, when I used the following code it seems to be not working at all. Only the parent scrolling is available.
final View view = inflater.inflate(R.layout.activity_register_terms_fragment, container, false);
TextView basicTermView = (TextView) view.findViewById(R.id.register_terms_basic_info);
TextView purposeTermView = (TextView) view.findViewById(R.id.register_terms_purpose_info);
TextView provideTermView = (TextView) view.findViewById(R.id.register_terms_provide_info);
TextView previous = (TextView) view.findViewById(R.id.register_terms_pre);
TextView next = (TextView) view.findViewById(R.id.register_terms_next);
basicTermView.setMovementMethod(new ScrollingMovementMethod());
purposeTermView.setMovementMethod(new ScrollingMovementMethod());
provideTermView.setMovementMethod(new ScrollingMovementMethod());
How should I change the codes?
Thank you for helping me!
You can't have a scrollable View, like TextView or ListView or RecyclerView, inside a ScrollView. So use your simple TextView inside a normal layout and add android:scrollbars property to it or you can use view's customised class which will calculate view's width/height programatically and use ScrollView as it's parent.
As an example, to use Listview inside scrollview, we need to use following customised class of Listview which will calculate list items height and set it.
public class ExpandedListView extends ListView {
private ViewGroup.LayoutParams params;
private int old_count = 0;
public ExpandedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExpandedListView(Context context) {
super(context);
}
public ExpandedListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
#Override
protected void onDraw(Canvas canvas) {
if (getCount() != old_count) {
this.setScrollContainer(false);
old_count = getCount();
params = getLayoutParams();
params.height = getCount()
* (old_count > 0 ? getChildAt(0).getHeight() : 0);
setLayoutParams(params);
}
super.onDraw(canvas);
}
}

issue in listview size small when it is inside scrollview android

I want to integrate listview inside scrollview so below is my code
xml file
<ScrollView
android:id="#+id/scl_add_task"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" >
<RelativeLayout
android:id="#+id/rel_hjistory"
android:layout_width="fill_parent"
android:layout_below="#+id/img_save"
android:visibility="gone"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/list_history"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:dividerHeight="2dp"
android:layout_marginTop="5dp"
android:cacheColorHint="#android:color/transparent"
android:divider="#f2f2f2"
android:layerType="software"
android:numColumns="1"
android:verticalSpacing="5dp"
android:visibility="visible" />
<TextView
android:id="#+id/img_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/list_history"
android:layout_centerHorizontal="true"
android:text="POST"
android:padding="10dp"
android:background="#drawable/rect_orange"
android:textStyle="bold"
android:textColor="#android:color/white"
android:textSize="#dimen/text_15"
android:visibility="visible" />
</RelativeLayout>
</ScrollView>
When i run my code it look like below images
list view getting very small in height i want to it full height with full screen scroll.
public class ExpandableHeightListView extends ListView {
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
hope this works for you..
use this method.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup) {
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
this method will calculate total item hieght of view from adapter and set it to the listview
i dont remember from where i had got this solution or else i would have posted link of that answer. anyways thanx to that guy.
Replace the Listview with linearlayout<LinearLayout
android:id="#+id/listdemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"></LinearLayout>
in your code you u have to addd this method
private void customListview() {
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.listdemo);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i <20 ; i++) {
View view = inflater.inflate(R.layout.item_recyclerview,null);
linearLayout.addView(view);
}
}`
item_recycleview is your layout of a single item of the list
count now set as 20 u can set as your wish
You should use a LinearLayout set to vertical orientation instead of a ListView.
Normally a ListView is used for displaying a dynamic number of items given to it by an Adapter and the ListView will handle the scrolling for the items. When you put a ListView inside a ScrollView then both widgets will be in conflict over who handles the scrolling.
Setting the height of a ListView to WRAP_CONTENT doesn't work, because it has a dynamic number of items. The ListView wants to have a static height (such as MATCH_PARENT or 400dp) and will scroll when needed and even create the item views on the fly when they become visible.
So use a LinearLayout and load it with child views yourself.
<LinearLayout
android:id="#+id/list_history"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
... snipped other attribs ... />
Since you already have an adapter that provides the views for the ListView you can use that to populate your LinearLayout:
adapter = new YourAdapter();
LinearLayout historyList = (LinearLayout) findViewById(R.id.list_history);
for (int position = 0; position < adapter.getCount(); position += 1) {
View itemView = adapter.getView(position, null, historyList);
historyList.addView(itemView);
}
Note: this is only a good solution if you know that your adapter will never provide a large number of items because you would then load your LinearLayout with a large number of views and things will grind to a halt or even crash.
If you cannot have a small number of items at all times then you will need to change your user interface. Perhaps you can just display the first 10 items only and when clicked go to a new activity that shows them all in a proper listview.
Okay, another answer based on your comment: "I want to display list item data without scrolling problem both scroll should be separate."
Set your ListView's height to a fixed amount:
<ListView
android:id="#+id/list_history"
android:layout_width="fill_parent"
android:layout_height="200dp"
... snipped other attribs ... />
This will allow the ScrollView to actually scroll the ListView and the ListView to scroll its own children.
Putting listview in scrollview is not a good idea.
Add a listview header instead.
create new layout and put everything you have on top of listview in there.
Then inflate the layout and add it as listview header:
listView = view.FindViewById<ListView> (R.Id.ListView);
var header = inflater.inflate(R.layout.header, null);
listView.AddHeaderView (header);
The only solution that worked for me was here:
londatiga.net/it/programming/android/make-android-listview-gridview-expandable-inside-scrollview/
which says (quotes):
package net.londatiga.android.widget;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
import android.content.Context;
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
and then use it
myExpandableHeightListView.setExpanded(true);

Proper way to implement custom View and dynamically added children

I'm extending a HorizontalScrollView. This layout will add children to a LinearLayout when the public setItems method is called. These children views are dynamically inflated and their widths depend on the parent (fill parent when only one view, and 1/2 parent when >= 2 items).
<!-- custom_layout.xml -->
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/container"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
</LinearLayout>
</merge>
Sometimes, setItems is called in a callback of a network request, so the layout might already be fully inflated. Where should I be calling updateView which needs the parent's width and to add inflated children? I put the call in both onSizeChanged and setItems like below.
public class CustomLayout extends HorizontalScrollView {
private LinearLayout container;
private List<Item> items;
public void setItems(List<Item> items) {
this.items = items;
updateView();
}
public CustomLayout(Context context) {
super(context);
init();
}
public CustomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
View v = inflate(getContext(), R.layout.custom_layout, this);
container = (LinearLayout) v.findViewById(R.id.container);
updateView();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
updateView();
}
public void updateView() {
if (items == null) {
return;
}
container.removeAllViews();
int width = getWidth();
if (items.size() > 1) {
width = width * 1 / 2;
}
for (final Item item : items) {
View child = LayoutInflator.from(getContext(), R.layout.custom_item, container, false);
child.setLayoutParams(new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.MATCH_PARENT));
container.addView(child);
}
}
}
I don't know why this way does not always work. Sometimes, the child, container just fails to render for some reason. Seeing the layout hierarchy shows that HorizontalScrollView has no children. What happened to container?
Also, it seems that even when placed in a network call, setItems is called before onSizeChanged, which makes me think that onSizeChanged is the wrong place to do updateView?
Try to place the updateView() method inside onMeasure instead of onSizeChanged, and use getMeasuredWidth() instead of getWidth():
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
updateView();
}
public void updateView() {
if (items == null) {
return;
}
container.removeAllViews();
int width = getMeasuredWidth();
if (items.size() > 1) {
width = width * 1 / 2;
}
for (final Item item : items) {
View child = LayoutInflator.from(getContext(), R.layout.custom_item, container, false);
child.setLayoutParams(new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.MATCH_PARENT));
container.addView(child);
}
}
Also, if you call setItems() method from callback of async request, dont forget to run it on UI thread by using runOnUiThread method of Activity.

Get all height at listview with custom adapter and scrollview

I'd like to use listview with custom adapter and it dynamically changing.
There is that i want (element above ListView must be scrolled):
I found two main ways to do it:
use ScrollView and code with listView.measure(0,0); to dynamically set up the listview height (but it doesn't work, listview is cropped);
For example: listView have 3 items, but it height is for 2 items (1 item is hidden);
don't use ScrollView, use a setHeaderView (but it doesn't work too, ListView don't have a scrolling)
Any idea?
Use custom ListView ExpandableHeightListView here
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ListView;
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs,int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// But do not use the highest 2 bits of this integer; those are
// reserved for the MeasureSpec mode.
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
use
list.setExpanded(true);
in onCreate() method.
i have a fragment in one of my apps who looks pretty much the same..
and I had the same problem as you, what I did in my case was set up the size for each of my list view cells at a fixed size. and measure the height by that logic.
not sure if that's considered the best way to achieve that, but it worked for me.
filterListView.getLayoutParams().height = (searchLabelsList.size() * (int) (43 * getScale() + 0.5f)) + (filterListView.getDividerHeight() * (searchLabelsList.size() - 1));
filterListView.setAdapter(searchLabelsAdapter);
and in the formula, 43 is the height for each cell, in dp's of course.
getScale is a method I wrote to get the scale of the screen size of the current user phone:
private float scale;
private float getScale() {
if (scale == 0) {
if (getActivity() != null) {
scale = getActivity().getResources().getDisplayMetrics().density;
}
}
return scale;
}
hope this will help, any question feel free to ask :)
good luck
You can try this:
First : In your xml put all other views inside ScrollView including ListView
<ScrollView
android:id="#+id/scrollViewId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
// Add your other views over here....
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
Second : In your java file,
Just use this custom method setListViewHeightBasedOnChildren(listview)
How ??
list = (ListView) findViewById(R.id.listview);
list.setAdapter(YOUR CUSTOM ADAPTER);
setListViewHeightBasedOnChildren(list);
Here is your custom method.
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
int totalHeight=0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++)
{
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
LayoutParams.MATCH_PARENT));
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + ((listView.getDividerHeight()) * (listAdapter.getCount()));
listView.setLayoutParams(params);
listView.requestLayout();
}
Hope this helps you somehow.

Inflating a custom layout view into a Layout extending class in Android

I have a custom layout defined in XML file which has a RelativeLayout root with a bunch of child view.
Now, I defined the following class:
public class MyCustomView extends RelativeLayout {
public MyCustomView(Context context) {
super(context);
init();
}
public MyCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_custom_view, this, true);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d("Widget", "Width spec: " + MeasureSpec.toString(widthMeasureSpec));
Log.d("Widget", "Height spec: " + MeasureSpec.toString(heightMeasureSpec));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else {
return getPreferredSize();
}
}
private int getPreferredSize() {
return 400;
}
}
As you can see I'm setting the root to MyCustomView instance and the attach flag to true.
What I want to achieve is that when I will add this custom view in another layout's xml, it will instantiate the MyCustomView class which will have the layout defined in the XML.
I already tries to use <merge> tag, but that way I lose the ability to arrange my child views in the XML as I want.
I also tried to inflate the XML and add it as a view to MyCustomView, but that way I get redundant RelativeLayout.
Last thing, I added the onMeasure() just for completeness.
the inflation occurs but the child view are not shown
The RelativeLayout does a bit more(a lot) than what you've done in the onMeasure layout(basically the children aren't measured at all with your code so they don't have something to show). If you extend a ViewGroup like RelativeLayout you need to let that class to do its callbacks(onMeasure, onLayout) or at least, very carefully replicate the methods and modify it like you want (if you want to see something).
So, remove the onMeasure method to see the children or explain better why did you override it.

Categories

Resources