Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android xml merge layout error on inflate

Tags:

I have a CustomView class and I want to use xml layout for it. So, my class extends RelativeLayout, inflates xml layout and tries to attach it to self.

public class CustomView extends RelativeLayout {   public CustomView (Context context)   {      super(context);      LayoutInflater.from(context).inflate(R.layout.layers_list_item, this, true);   } } 

If my xml layout has some layout (Linear, for example) as root element it works fine. But when I try to use <merge> tag according to this response I got this error:

<merge /> can be used only with a valid ViewGroup root and attachToRoot=true

My xml layout is like:

<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"      ... >       <CheckBox         ... />       <TextView         ... />  </merge> 

I also tried to remove all attributes from <merge... > tag, got the same result. What's wrong?

UPDATE: The code above is correct. As secretlm mentioned, problem was that <merge> was used as a root element and inflated in another piece od code:

ArrayAdapter<String> adapter =      new ArrayAdapter<String>(this,                               R.layout.layers_list_item,                               R.id.layers_list_item_text); 

And with every element added adapter tried to inflate R.layout.layers_list_item which have <merge> as root.

like image 242
Frederic Blase Avatar asked Dec 26 '12 10:12

Frederic Blase


People also ask

What does it mean to inflate a layout Android?

"Inflating" a view means taking the layout XML and parsing it to create the view and viewgroup objects from the elements and their attributes specified within, and then adding the hierarchy of those views and viewgroups to the parent ViewGroup.

What is Inflater inflate in Android?

Inflating means reading the XML file that describes a layout (or GUI element) and to create the actual objects that correspond to it, and thus make the object visible within an Android app.

What is inflate XML?

In this context, Inflate means reading a layout XML (often given as parameter) to translate them in Java code.

What is merge tag in Android XML?

Android Essentials: <merge> tag The merge tag does exactly that – it merges its contents into the parent layout. This allows us to avoid duplicated layouts and flattens the view hierarchy.


1 Answers

you can't use <merge> as a root element in your final layout without container element. "Using this as the root element is useful when you know that this layout will be placed into a layout that already contains the appropriate parent View to contain the children of the element. This is particularly useful when you plan to include this layout in another layout file using and this layout doesn't require a different ViewGroup container" -- from "developer.android.com"

This example show that how to work with <merge>: http://www.coderzheaven.com/2011/06/26/merge-two-layout-xml-in-android/

Updated:

You should try with Constructor(Context, AttributeSet) from this example. I think it will solve your problem.

file test.xml:

<?xml version="1.0" encoding="utf-8"?> <merge  xmlns:android="http://schemas.android.com/apk/res/android">       <CheckBox         android:id="@+id/layers_list_item_switch"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignRight="@id/layers_list_item_root"             android:layout_alignParentRight="true"         android:layout_marginLeft="15dp"                 android:button="@drawable/ic_launcher" />       <TextView         android:id="@+id/layers_list_item_text"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="left|center_vertical"         android:layout_toLeftOf="@id/layers_list_item_switch"         android:selectAllOnFocus="true"         android:text="tret"         android:ellipsize="marquee"         android:focusable="true"         android:focusableInTouchMode="true"         android:marqueeRepeatLimit="marquee_forever"         android:singleLine="true"         android:scrollHorizontally="true"         android:textColor="@android:color/black"         android:textSize="16sp"         android:textStyle="bold"         android:typeface="serif"         android:clickable="true" />  </merge> 

Test class which extend from RelativeLayout:

public class Test extends RelativeLayout {            public Test(Context context, AttributeSet attrs) {         super(context, attrs);               LayoutInflater.from(context).inflate(R.layout.test, this, true);         } } 

Main activity:

public class MainActivity extends Activity {      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);     }     } 

Main layout:

<com.example.testlayout.Test     xmlns:android="http://schemas.android.com/apk/res/android"                android:id="@+id/layers_list_item_root"     android:layout_height = "fill_parent"     android:layout_width = "fill_parent"           /> 
like image 53
secretlm Avatar answered Sep 27 '22 20:09

secretlm