How to properly populate XML-Layout-File inside CustomGroupGroup?

I want to inflate an XML-Layout-File in a custom ViewGroup class, my problem is that it only creates a blank screen. Performing the same action in an activity class works fine. Here is my simple XML-Layout-File:

shownumberlayout.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FFFFFF" android:id="@+id/layoutForNumber"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvNumber" android:layout_centerHorizontal="true" android:textColor="#000000" android:text="Test" android:layout_centerVertical="true" android:textSize="30dip"> </TextView> </RelativeLayout> 

Here is a working version, fanning shownumberlayout.xml in an Activity ShowNumber :

 ShowNumber.class public class ShowNumber extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); ViewGroup vg = (ViewGroup) inflater.inflate(R.layout.shownumberlayout, null); setContentView(vg); } } 

It shows a white background with black text "Test" centered.

Now the version inflates the xml in a custom ViewGroup -Class:

 ViewGroup.class public class ViewNumber extends ViewGroup { private LayoutInflater inflater; public ViewNumber(Context context) { super(context); // TODO Auto-generated constructor stub initView(context); } public ViewNumber(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub initView(context); } public ViewNumber(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub initView(context); } private void initView(Context context){ inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.shownumberlayout, null); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub } } 

ShowNumber.class public class ShowNumber extends the action {/ ** Called when the action is first created. * /

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup vg = new ViewNumber(this); setContentView(vg); } 

}

I do this basically as in this. The answer is explained. It just creates a blank black screen. What am I doing wrong?

UPDATE 1

@Konstantin I applied your changes, but still just a blank screen, I also made a log-ouput to get the number of children. It always remains 1, even I add another Textview to the XML-Layout-File. Before changes always remains 0.

 public class ViewNumber extends RelativeLayout { ... private void initView(Context context){ //inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //inflater.inflate(R.layout.shownumberlayout, null); View.inflate(context, R.layout.shownumberlayout,this); Log.v("ViewNumber", "Number of Child: " + this.getChildCount());//output is 1,before it remains 0 } ... } 

@Sankar This is Logcat after changes from Constantine:

 12-16 09:24:23.606: DEBUG/AndroidRuntime(8951): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 12-16 09:24:23.606: DEBUG/AndroidRuntime(8951): CheckJNI is OFF 12-16 09:24:23.606: DEBUG/dalvikvm(8951): creating instr width table 12-16 09:24:23.656: DEBUG/AndroidRuntime(8951): --- registering native functions --- 12-16 09:24:23.916: DEBUG/AndroidRuntime(8951): Shutting down VM 12-16 09:24:23.916: DEBUG/dalvikvm(8951): Debugger has detached; object registry had 1 entries 12-16 09:24:23.916: INFO/AndroidRuntime(8951): NOTE: attach of thread 'Binder Thread #3' failed 12-16 09:24:24.076: DEBUG/AndroidRuntime(8960): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 12-16 09:24:24.076: DEBUG/AndroidRuntime(8960): CheckJNI is OFF 12-16 09:24:24.076: DEBUG/dalvikvm(8960): creating instr width table 12-16 09:24:24.126: DEBUG/AndroidRuntime(8960): --- registering native functions --- 12-16 09:24:24.376: INFO/ActivityManager(78): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=org.customview.harold/.ShowNumber } 12-16 09:24:24.426: DEBUG/AndroidRuntime(8960): Shutting down VM 12-16 09:24:24.426: DEBUG/jdwp(8960): Got wake-up signal, bailing out of select 12-16 09:24:24.426: DEBUG/dalvikvm(8960): Debugger has detached; object registry had 1 entries 12-16 09:24:24.456: INFO/AndroidRuntime(8960): NOTE: attach of thread 'Binder Thread #3' failed 12-16 09:24:24.456: VERBOSE/ViewNumber(8923): Number of Child: 1 12-16 09:24:24.496: VERBOSE/RenderScript_jni(164): surfaceDestroyed 12-16 09:24:24.526: INFO/ActivityManager(78): Displayed activity org.customview.harold/.ShowNumber: 104 ms (total 104 ms) 12-16 09:24:24.576: DEBUG/dalvikvm(158): GC_FOR_MALLOC freed 10631 objects / 526248 bytes in 52ms 12-16 09:24:34.606: DEBUG/dalvikvm(164): GC_EXPLICIT freed 1776 objects / 106960 bytes in 91ms 

UPDATE 2

The content is finally displayed correctly. The downside was overriding the onLayout method (thanks to Franco ) in RelativeLayout-Sublcass:

 public class ViewNumber extends RelativeLayout { ... @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub for(int i = 0 ; i < getChildCount() ; i++){ getChildAt(i).layout(l, t, r, b); } } ... } 

Note. Later, you must also override the onMeasurement() method, but currently the content is also displayed correctly without overriding it.

Now the solution for Franco's initView method does not align the TextView in the Center, but places it in the upper left corner. The solution from Konstantin correctly places it in the Viewing Center:

 public class ViewNumber extends RelativeLayout { ... private void initView(Context context){ View.inflate(context, R.layout.shownumberlayout,this); } ... } 
+53
android android-layout
Dec 15 '10 at 10:10
source share
5 answers

Have you tried this?

 private void initView(Context context){ inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.addView(inflater.inflate(R.layout.shownumberlayout, null)); } 

EDIT: I answer quickly ... ViewGroup is responsible for preparing the layout for their children, in the layout method, try this:

  @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub for(int i = 0 ; i < getChildCount() ; i++){ getChildAt(i).layout(l, t, r, b); } } 
+28
Dec 16 '10 at 2:10
source share

I do not know what is going on in these answers. I think manually calling onLayout little crazy.

The function LayoutInflater.inflate pretty simple. If you use one that takes a third boolean argument (attachToRoot) and true , it will add the views from your XML to the parent view (second argument). If you use one that takes only 2 arguments, it will pass true to attachToRoot by default if you provide a parent that is not null .

In any case, most of the clutter you experience is due to the views from your XML being added to your custom view. Since your XML has a RelativeLayout root, and your custom view is also RelativeLayout - you get a relative layout inside a relative layout.

This is probably not what you want.

The answer given by Konstantin makes sense, but you lose FrameLayout because you place the RelativeLayout inside a FrameLayout . Since Android cannot contain too many nested views, it is recommended to optimize and not add extra FrameLayout .

I suggest saving your custom view as RelativeLayout and changing your XML root to <merge> . Then use a puff form that adds the XML views to your parent - e.g. View.inflate(context,int,this)

The purpose of the <merge> is to skip the root of the node in XML. Take a look at it.

+40
Jun 18 '13 at 14:19
source share

Your layout is not overpriced anywhere .. make your ViewNumber a continuation of FrameLayout and strangle it:

 public class ViewNumber extends FrameLayout { public ViewNumber(Context context) { super(context); initView(context); } public ViewNumber(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public ViewNumber(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(context); } private void initView(Context context){ View.inflate(context, R.layout.shownumberlayout, this); //correct way to inflate.. } } 

UPD: Also, you do not need to override the onLayout method, which looks very incorrect .. at least call super.onLayout () at the very beginning:

 @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } 
+31
Dec 15 '10 at 11:18
source share

Try the following:

  LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); inflater.inflate( R.layout.login_view_layout, null ); 
+1
Jun 22 '15 at 14:25
source share

Priority onLayout needed. When you create a ViewNumber object ( ViewGroup vg = new ViewNumber(this) ), it looks like an xml bloat below:

 <ViewNumber I have no child :( </ViewNumber> 

therefore, if you do not override onLayout , ViewNumber onLayout cannot find any child, then it will be empty.

 @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } 

after overriding, it will use the onLayout method of the ViewNumber parent if your codes are:

 public class ViewNumber extends RelativeLayout { ... private void initView(Context context){ View.inflate(context, R.layout.shownumberlayout,this); } ... } 

then it is like xml bloat below

  <RelativeLayout <RelativeLayout your xml file /> </RelativeLayout> 

there is another RelativeLayout.To sovle this, you can write:

 public class ViewNumber extends RelativeLayout { ... private void initView(Context context){ inflater.inflate( R.layout.login_view_layout, null ); //change (..,this) to (..,null) } ... } 

However, something unexpected will happen. android:layout_xxx=".." your xml file may change (this is why your text is placed in the upper left corner). To know more and better solution, you can see talkol and fgeorgiew answer :)

+1
Aug 6
source share



All Articles