4

Hi I'm trying to inflate my layout with <merge> tag here is my main.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" >

    <com.osmgames.kartuves.LinesLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/lines" />

</merge>

This is my LinesLayout.java:

public class LinesLayout extends FrameLayout {

    public LinesLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        super.onInterceptTouchEvent(event);
        return false;
    }
}

And my main.java:

public class main extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }}

So I want to inflate the XML below to main.xml. How can I do that?

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent">

    <ImageView   
         android:layout_width="40dp" 
         android:layout_height="40dp"
         android:layout_gravity="center" 
         android:layout_marginTop="75dp" 
         android:layout_marginRight="40dp"
         android:src="@drawable/line" />

    <ImageView   
         android:layout_width="40dp" 
         android:layout_height="40dp"
         android:layout_gravity="center" 
         android:layout_marginTop="75dp" 
         android:src="@drawable/line" />

    <ImageView   
         android:layout_width="40dp" 
         android:layout_height="40dp"
         android:layout_gravity="center" 
         android:layout_marginTop="75dp" 
         android:layout_marginLeft="40dp"
         android:src="@drawable/line"  />
</FrameLayout>

This is log I'm getting:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.osmgames.kartuves/com.osmgames.kartuves.InGame}: android.view.InflateException: <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)

Caused by: android.view.InflateException: <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
at **com.osmgames.kartuves.InGame.onCreate(InGame.java:59)**
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
... 11 more

InGame.java:59 is :

58 FrameLayout item = (FrameLayout)findViewById(R.id.lines);
59 View child = getLayoutInflater().inflate(R.layout.letters3, null);
60 item.addView(child);
JJD
  • 50,076
  • 60
  • 203
  • 339
Kęstas Venslauskas
  • 391
  • 1
  • 5
  • 14

3 Answers3

2

The merge tag should be used in the inflated layout, it merges itself inside the parent ViewGroup.

Try this :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent">

    <com.osmgames.kartuves.LinesLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/lines" />

</FrameLayout >

and this :

<?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" >

    <ImageView   
         android:layout_width="40dp" 
         android:layout_height="40dp"
         android:layout_gravity="center" 
         android:layout_marginTop="75dp" 
         android:layout_marginRight="40dp"
         android:src="@drawable/line" />

    <ImageView   
         android:layout_width="40dp" 
         android:layout_height="40dp"
         android:layout_gravity="center" 
         android:layout_marginTop="75dp" 
         android:src="@drawable/line" />

    <ImageView   
         android:layout_width="40dp" 
         android:layout_height="40dp"
         android:layout_gravity="center" 
         android:layout_marginTop="75dp" 
         android:layout_marginLeft="40dp"
         android:src="@drawable/line" />
</merge>

Hope it will help

JJD
  • 50,076
  • 60
  • 203
  • 339
Mathieu de Brito
  • 2,536
  • 2
  • 26
  • 30
  • Arf sorry, forgot one thing : Your merged view need to be have a viewgroup as merged view. You can also use the include tag, could be better for your need. – Mathieu de Brito May 09 '12 at 09:50
  • I tried include, but i need to set the included layout programmatically depending on app needs. I need to set 1 of the 8 layouts that should be inserted... – Kęstas Venslauskas May 09 '12 at 10:00
  • There is something sure : the merge tag should not be in the main.xml layout file. It should be in the inflated view. The inflated view must also have the merge tag, then a viewGroup and then your image views. – Mathieu de Brito May 09 '12 at 10:06
  • Just saw something : `FrameLayout item = (FrameLayout)findViewById(R.id.lines); View child = getLayoutInflater().inflate(R.layout.letters3, item );` – Mathieu de Brito May 09 '12 at 10:11
2

use

    View headerView = View.inflate(this, R.layout.layout_name, null);
    lv.addHeaderView(headerView);

to inflate your layout it will give you your parent layout in which all views are present then typecast it or if you want to add then add it directly to another layout.

Bharat Sharma
  • 3,926
  • 2
  • 17
  • 29
1

You should better use

58 FrameLayout item = (FrameLayout)findViewById(R.id.lines);
59 View child = getLayoutInflater().inflate(R.layout.letters3, item, false);
60 item.addView(child);

or you can use

58 FrameLayout item = (FrameLayout)findViewById(R.id.lines);
    59 View child = getLayoutInflater().inflate(R.layout.letters3, item, true);

when you pass true it will automatically do the things for you.

which would be one less view instead of that useless FrameLayout you are adding in place of merge tag.

Akhil Dad
  • 1,804
  • 22
  • 35