duplicated id with fragment
N

3

11

I'm trying to applicate drawernavigation (my first fragment is a map & the others are just some fragments with simple layouts).So it runs fine & I can navigate between my fragments but when I return to the first fragment which is a map I got a crash

logcat:

11-20 11:03:27.306: E/AndroidRuntime(13787): FATAL EXCEPTION: main
11-20 11:03:27.306: E/AndroidRuntime(13787): android.view.InflateException: Binary XML file line #6: Error inflating class fragment
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at challenge.arabe.taxitaxi.HomeFragment.onCreateView(HomeFragment.java:48)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:828)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1032)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.BackStackRecord.run(BackStackRecord.java:622)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.os.Handler.handleCallback(Handler.java:605)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.os.Looper.loop(Looper.java:137)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.ActivityThread.main(ActivityThread.java:4511)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at java.lang.reflect.Method.invokeNative(Native Method)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at java.lang.reflect.Method.invoke(Method.java:511)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at dalvik.system.NativeStart.main(Native Method)
11-20 11:03:27.306: E/AndroidRuntime(13787): Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Duplicate id 0x7f05000c, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.app.Activity.onCreateView(Activity.java:4253)
11-20 11:03:27.306: E/AndroidRuntime(13787):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
11-20 11:03:27.306: E/AndroidRuntime(13787):    ... 18 more

I think this the most impportant:

Duplicate id 0x7f05000c, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment

so this is my code: LoginScreen:a fragmentActivity which make all call for the fragment

public class LoginScreen extends FragmentActivity {

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;

    // nav drawer title
    private CharSequence mDrawerTitle;

    // used to store app title
    private CharSequence mTitle;

    // slide menu items
    private String[] navMenuTitles;
    private TypedArray navMenuIcons;

    private ArrayList<NavDrawerItem> navDrawerItems;
    private NavDrawerListAdapter adapter;



MapFragment mMap;
    GoogleMap googleMap;

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




          int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
            if(status == ConnectionResult.SUCCESS) {
                        // what you want to do
                Toast.makeText(getApplicationContext(), "good connection", Toast.LENGTH_SHORT).show();
            }
          //  setUpMapIfNeeded();
           // addTwitterMarq();

            mTitle = mDrawerTitle = getTitle();

            // load slide menu items
            navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

            // nav drawer icons from resources
            navMenuIcons = getResources()
                    .obtainTypedArray(R.array.nav_drawer_icons);

            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

            navDrawerItems = new ArrayList<NavDrawerItem>();

            // adding nav drawer items to array
            // Home
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
            // Find People
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
            // Photos
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
            // Communities, Will add a counter here
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1), true, "22"));
            // Pages
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
            // What's hot, We  will add a counter here
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));


            // Recycle the typed array
            navMenuIcons.recycle();

            mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

            // setting the nav drawer list adapter
            adapter = new NavDrawerListAdapter(getApplicationContext(),
                    navDrawerItems);
            mDrawerList.setAdapter(adapter);

            // enabling action bar app icon and behaving it as toggle button
            getActionBar().setDisplayHomeAsUpEnabled(true);
            //getActionBar().setHomeButtonEnabled(true);

            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                    R.drawable.ic_drawer, //nav menu toggle icon
                    R.string.app_name, // nav drawer open - description for accessibility
                    R.string.app_name // nav drawer close - description for accessibility
            ) {
                public void onDrawerClosed(View view) {
                    getActionBar().setTitle(mTitle);
                    // calling onPrepareOptionsMenu() to show action bar icons
                    invalidateOptionsMenu();
                }

                public void onDrawerOpened(View drawerView) {
                    getActionBar().setTitle(mDrawerTitle);
                    // calling onPrepareOptionsMenu() to hide action bar icons
                    invalidateOptionsMenu();
                }
            };
            mDrawerLayout.setDrawerListener(mDrawerToggle);

            if (savedInstanceState == null) {
                // on first time display view for first nav item
                displayView(0);
            }


    }


    /**
     * Slide menu item click listener
     * */
    private class SlideMenuClickListener implements
            ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            // display view for selected nav drawer item
            displayView(position);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // toggle nav drawer on selecting action bar app icon/title
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle action bar actions click
        switch (item.getItemId()) {
        case R.id.action_settings:
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    /* *
     * Called when invalidateOptionsMenu() is triggered
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // if nav drawer is opened, hide the action items
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }

    /**
     * Diplaying fragment view for selected nav drawer list item
     * */
    private void displayView(int position) {
        // update the main content by replacing fragments
        Fragment fragment = null;
        switch (position) {
        case 0:
            fragment = new HomeFragment();
            break;
        case 1:
            fragment = new FindPeopleFragment();
            break;
        case 2:
            fragment = new PhotosFragment();
            break;
        case 3:
            fragment = new CommunityFragment();
            break;
        case 4:
            fragment = new PagesFragment();
            break;
        case 5:
            fragment = new WhatsHotFragment();
            break;

        default:
            break;
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.frame_container, fragment).commit();

            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(navMenuTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        } else {
            // error in creating fragment
            Log.e("MainActivity", "Error in creating fragment");
        }
    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    /**
     * When using the ActionBarDrawerToggle, you must call it during
     * onPostCreate() and onConfigurationChanged()...
     */

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggls
        mDrawerToggle.onConfigurationChanged(newConfig);
    }





    private void addTwitterMarq() {
        // TODO Auto-generated method stub


    LatLng pos = new LatLng(48.85078, 2.34440);

        googleMap.addMarker(new MarkerOptions()
             .title("Twitter")
             .snippet("Twitter HQ")
             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
             .position(pos)          
          );


    }

    private void setUpMapIfNeeded() {
        // TODO Auto-generated method stub
        if (googleMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();


            // Check if we were successful in obtaining the map.
            googleMap.setMyLocationEnabled(true);
            googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);       

            if (googleMap != null) {
               // setUpMap();
                drawTestJunk();

            }
        }
    }

    private void drawTestJunk() {
        // TODO Auto-generated method stub
        UiSettings settings = googleMap.getUiSettings();

        settings.setZoomControlsEnabled(true);
        settings.setCompassEnabled(true);
        settings.setTiltGesturesEnabled(false);

        settings.setMyLocationButtonEnabled(true);

        CameraUpdate camUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(45.53, -73.59), 14);
        googleMap.moveCamera(camUpdate);



        /**
         * "Markers" lesson
         */
        googleMap.addMarker(new MarkerOptions()
        .position(new LatLng(45.538490,-73.598480))
        .title("Hello world")
        .snippet("what does a snippet look like?")
        .draggable(true)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
                );
        /**
         * skipping other "Marker" lessons, to move on to Lines, Polygons, and Circles.
         * Topic list for later study:
         * - Customized info windows
         * - Marker click events
         * - Marker drag events
         * - Info window click events
         */


        /**
         * "Lines, Polygons, and Circles" lesson
         */

        // LINE
        PolylineOptions route = new PolylineOptions()
        .add(new LatLng(45.538451240403596, -73.59851807077722) )
        .add(new LatLng(45.5390432, -73.5997465) )
        .add(new LatLng(45.5387234, -73.6000517) )
        .add(new LatLng(45.5389376, -73.6005275) )
        .color(Color.GREEN)
        ;


        Polyline polyline = googleMap.addPolyline(route);
        //you can also call PolylineOptions.addAll(Iterable<LatLng>) if the points are already in a list


        // POLYGON
        ArrayList<LatLng> hole= new ArrayList<LatLng>();
        hole.add(new LatLng(45.5275, -73.5925));
        hole.add(new LatLng(45.5225, -73.5925));
        hole.add(new LatLng(45.5225, -73.5975));
        hole.add(new LatLng(45.5275, -73.5975));

        PolygonOptions rectOptions = new PolygonOptions()
        .add(new LatLng(45.53, -73.59),
                new LatLng(45.52, -73.59),
                new LatLng(45.52, -73.60),
                new LatLng(45.53, -73.60),
                new LatLng(45.53, -73.59))
                .addHole(hole)
                .strokeColor(Color.RED)
                .fillColor(Color.BLUE);

        Polygon polygon = googleMap.addPolygon(rectOptions);

        // And sure, why not, a CIRCLE
        CircleOptions circleOptions = new CircleOptions()
        .center(new LatLng(45.525, -73.595))
        .radius(100);

        Circle circle = googleMap.addCircle(circleOptions);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.login_screen, menu);
        return true;
    }

}

and this is my main layout for the fragmentActivity:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Framelayout to display Fragments -->
    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

   </FrameLayout>

    <!--     

<fragment
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.MapFragment"/>

     -->

    <!-- Listview to display slider menu -->
    <ListView
        android:id="@+id/list_slidermenu"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/list_divider"
        android:dividerHeight="1dp"        
        android:listSelector="@drawable/list_selector"
        android:background="@color/list_background"/>

</android.support.v4.widget.DrawerLayout>

and this is the xml layout of the mapfragment:

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

    <fragment
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.MapFragment"/>

</RelativeLayout>

and this is the mapfragment code:

public class HomeFragment extends Fragment {


      int mCurrentPosition = -1;
MapFragment mMap;
    GoogleMap googleMap;
    final static String ARG_POSITION = "position";

    public HomeFragment(){}

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

          if (savedInstanceState != null) {
                mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
            }
        View rootView = inflater.inflate(R.layout.fragment_map, container, false);
//        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
//        if(status == ConnectionResult.SUCCESS) {
//                    // what you want to do
//          //Toast.makeText(getApplicationContext(), "good connection", Toast.LENGTH_SHORT).show();
//        }

        setUpMapIfNeeded();
        addTwitterMarq();
        return rootView;
    }




    private void addTwitterMarq() {
        // TODO Auto-generated method stub


    LatLng pos = new LatLng(48.85078, 2.34440);

        googleMap.addMarker(new MarkerOptions()
             .title("Twitter")
             .snippet("Twitter HQ")
             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
             .position(pos)          
          );


    }

    private void setUpMapIfNeeded() {
        // TODO Auto-generated method stub
        if (googleMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();


            // Check if we were successful in obtaining the map.
            googleMap.setMyLocationEnabled(true);
            googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);       

            if (googleMap != null) {
               // setUpMap();
                drawTestJunk();

            }
        }
    }

    private void drawTestJunk() {
        // TODO Auto-generated method stub
        UiSettings settings = googleMap.getUiSettings();

        settings.setZoomControlsEnabled(true);
        settings.setCompassEnabled(true);
        settings.setTiltGesturesEnabled(false);

        settings.setMyLocationButtonEnabled(true);

        CameraUpdate camUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(45.53, -73.59), 14);
        googleMap.moveCamera(camUpdate);



        /**
         * "Markers" lesson
         */
        googleMap.addMarker(new MarkerOptions()
        .position(new LatLng(45.538490,-73.598480))
        .title("Hello world")
        .snippet("what does a snippet look like?")
        .draggable(true)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
                );
        /**
         * skipping other "Marker" lessons, to move on to Lines, Polygons, and Circles.
         * Topic list for later study:
         * - Customized info windows
         * - Marker click events
         * - Marker drag events
         * - Info window click events
         */


        /**
         * "Lines, Polygons, and Circles" lesson
         */

        // LINE
        PolylineOptions route = new PolylineOptions()
        .add(new LatLng(45.538451240403596, -73.59851807077722) )
        .add(new LatLng(45.5390432, -73.5997465) )
        .add(new LatLng(45.5387234, -73.6000517) )
        .add(new LatLng(45.5389376, -73.6005275) )
        .color(Color.GREEN)
        ;


        Polyline polyline = googleMap.addPolyline(route);
        //you can also call PolylineOptions.addAll(Iterable<LatLng>) if the points are already in a list


        // POLYGON
        ArrayList<LatLng> hole= new ArrayList<LatLng>();
        hole.add(new LatLng(45.5275, -73.5925));
        hole.add(new LatLng(45.5225, -73.5925));
        hole.add(new LatLng(45.5225, -73.5975));
        hole.add(new LatLng(45.5275, -73.5975));

        PolygonOptions rectOptions = new PolygonOptions()
        .add(new LatLng(45.53, -73.59),
                new LatLng(45.52, -73.59),
                new LatLng(45.52, -73.60),
                new LatLng(45.53, -73.60),
                new LatLng(45.53, -73.59))
                .addHole(hole)
                .strokeColor(Color.RED)
                .fillColor(Color.BLUE);

        Polygon polygon = googleMap.addPolygon(rectOptions);

        // And sure, why not, a CIRCLE
        CircleOptions circleOptions = new CircleOptions()
        .center(new LatLng(45.525, -73.595))
        .radius(100);

        Circle circle = googleMap.addCircle(circleOptions);

    }
@Override
    public void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        //setUpMapIfNeeded();
        //addTwitterMarq();
    }

@Override
public void onSaveInstanceState(Bundle outState) {
    // TODO Auto-generated method stub
    super.onSaveInstanceState(outState);
    outState.putInt(ARG_POSITION, mCurrentPosition);

}
public void updateArticleView(int position) {
    mCurrentPosition = position;
}
@Override
public void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
     Bundle args = getArguments();
     if (args != null) {
         // Set article based on argument passed in
         updateArticleView(args.getInt(ARG_POSITION));
     } else if (mCurrentPosition != -1) {
         // Set article based on saved instance state defined during onCreateView
         updateArticleView(mCurrentPosition);
     }
}
}

I think that the problem is located in onResume & onCreateView methods!! Hope that you'll help me thanks.

Nicholenicholl answered 20/11, 2013 at 11:19 Comment(1)
A
48

use this

<fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
         />

and override method onDestroyView() and Just put this code in onDestroyView()

public void onDestroyView() 
 {
    super.onDestroyView(); 
    Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));  
    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
    ft.remove(fragment);
    ft.commit();
}
Agripinaagrippa answered 20/11, 2013 at 13:13 Comment(2)
I tried this solution and while it worked at first; when I turned the device into landscape/portrait I got an IllegalStateException when I tried to commit(). There are other posts on SO talking about this; you can't commit after an onStop or onSaveInstanceState has been called on the fragment.Peterman
you can use commitAllowingStateLoss() method insted of commit and make sure you have given attributes to your activity android:configChanges="screenSize|orientation" in android manifiest fileAgripinaagrippa
D
13

Try to reuse/recycle your layout. I am running into "duplicate id" when using a map fragment. So in onCreateView instead of

final View rootView = inflater.inflate(R.layout.fragment_profile, container, false);

i am using

public class YourFragment extends Fragment {
   public YourFragment(){}
   ...
   private static View rootView;
   ...


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    //View rootView = inflater.inflate(R.layout.fragment_layout, container, false);

    if (rootView != null) {
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null)
            parent.removeView(rootView);
    }
    try {
        rootView = inflater.inflate(R.layout.fragment_layout, container, false);
    } catch (InflateException e) {
        /* map is already there, just return view as it is  */
    }
Dedradedric answered 12/9, 2014 at 6:6 Comment(2)
This answer is far better. Using the selected answer's method I was crashing my app due to IllegalStateExceptions. Attempting to commit() after onStop or after onSaveInstanceState will trigger this. The easiest way to see this is turn your phone into portrait/landscape.Peterman
Better answer than the accepted one. This one keeps the previous state of the fragment. Thank you very much, bro.Ham
G
0

I think you have to try to retrieve old Fragments instance instead of recreating it each time a drawer item is selected. In your displayView method of LoginScreen Activity, you have to do something like that in the switch:

Fragment fragment = null;
String title = getResources().getString(SOME_FRAGMENT_TITLE);
switch (position) {
case 1:
   fragment = (YourFragment) fm.findFragmentByTag(title);
   if (fragment == null) fragment = new YourFragment();
   break;
 }
Gnu answered 20/11, 2013 at 11:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.