SupportMapFragment on a tab. I can only see once
Asked Answered
A

4

3

I'm working on a tabbed application using FragmentTabHost. One of my tabs(Fragments) is a map (extends Fragment), and I can only see the first time I select it, If I select other tab and back to map, app crashes...

The app must be compatible with API8

Main activity

package pack.unimaps2;

import com.google.android.gms.common.GooglePlayServicesUtil;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.view.Menu;

public class MainActivity extends FragmentActivity {
private FragmentTabHost mTabHost;

@Override
protected void onCreate(Bundle savedInstanceState) {
    GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

    mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Ir a..."),
            Fragments.RutaHastaTab.class, null);
    mTabHost.addTab(mTabHost.newTabSpec("mapa").setIndicator("Mapa"),
            Fragments.map.class, null);
    mTabHost.addTab(mTabHost.newTabSpec("acercade").setIndicator("Acerca de..."),
            Fragments.AcercaDeTab.class, null);

}


}

FragmentsActivity (Omitted first fragment)

package pack.unimaps2;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


import com.google.android.gms.maps.SupportMapFragment;

public class Fragments extends FragmentActivity {


    public static class map extends Fragment{

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.map, container, false);
            return v;
        }

    }

    public static class AcercaDeTab extends Fragment {

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.tab_acercade, container, false);
            return v;
        }

    }
}

And the xml to create the view of map Fragment (map.xml):

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/map"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 class="com.google.android.gms.maps.SupportMapFragment"/>

Log

03-30 21:07:49.180: E/AndroidRuntime(16464): FATAL EXCEPTION: main
03-30 21:07:49.180: E/AndroidRuntime(16464): android.view.InflateException: Binary XML file line #1: Error inflating class fragment
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at pack.unimaps2.Fragments$map.onCreateView(Fragments.java:73)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1264)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.os.Handler.handleCallback(Handler.java:615)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.os.Looper.loop(Looper.java:137)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.app.ActivityThread.main(ActivityThread.java:4745)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at java.lang.reflect.Method.invokeNative(Native Method)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at java.lang.reflect.Method.invoke(Method.java:511)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at dalvik.system.NativeStart.main(Native Method)
03-30 21:07:49.180: E/AndroidRuntime(16464): Caused by: java.lang.IllegalArgumentException: Binary XML file line #1: Duplicate id 0x7f040007, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
03-30 21:07:49.180: E/AndroidRuntime(16464):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
03-30 21:07:49.180: E/AndroidRuntime(16464):    ... 18 more

Don't know what is wrong, thank you for your help...

Aflcio answered 31/3, 2013 at 2:0 Comment(5)
Logcat of the crash, please?Poised
Please add the error here..Glyconeogenesis
Please see the updates below, please notice the change in inflaterGlyconeogenesis
please check my solution below and notice the comment inside the code, do the same for AcercaDeTab classGlyconeogenesis
i have the same issue. Anyone know the answer to this one?Coating
D
3

Still looking for an answer?

You can't inflate the layout everytime onCreateView all the time. Use something along the lines of:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (view != null && this.previousContainer == container) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null) {
            parent.removeView(view);
        }
    } else {
        try {
            view = inflater.inflate(R.layout.map, container, false);
            this.previousContainer = container;
        } catch (InflateException e) {
            Log.w("InflateException happened ou nous", e.getMessage());
        }
    }
    return view;
}

I managed to prevent that and also losing the map when recreating the Fragment (when changing from vertical to landscape for instance)

Doggo answered 2/10, 2013 at 2:0 Comment(0)
G
1

Fragments should have an empty constructor

as follows:

public static class map extends Fragment{

    public map(){
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.map, container, false);
        // Change the previous line to this:
        View v = inflater.inflate(R.layout.map, null);

        return v;
    }

}
Glyconeogenesis answered 31/3, 2013 at 2:11 Comment(0)
P
0

the problem is that you are trying to make a new view where there's an old one exist; just simply implement this code.

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

    if (v != null) {
        ViewGroup parent = (ViewGroup) v.getParent();
        if (parent != null)
            parent.removeView(v);
    }
    try {
         v = inflater.inflate(R.layout.map_fragment, container, false);
    } catch (InflateException e) {
        // map is already there, just return view as it is
    }

    return v;
}
Pycnidium answered 16/2, 2014 at 21:20 Comment(0)
O
0

this solution works, but may not be your case. I had the same problem but using a FragmentPagerAdapter inside a ViewPager, not a TabHost.

What I did is to make the ViewPager store all pages all the time:

viewPager.setOffscreenPageLimit(2); 
viewPager.setAdapter(adapter);

so my tab with the map fragment (page 0 in my case) will be never deleted and re-created, getting rid of the problem.

value 2 means that it will keep in memory two pages before and two pages after the current one. That will be enough when you have 3 tabs. Feel free to increment it if you have more tabs, but your app's memory consumption will increase too

Overheat answered 19/8, 2016 at 6:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.