Swipe to the right after left gives error ANDROID

1

I'm creating an Android application in Eclipse with 3 screen with horizontal Swipe, on the last tab I have a Map Fragment.

But it happens that when doing swipe to the right the first time everything is normal, when making a swipe to the left and to make a right to the application crash again and appears to me this error, what could be? / p>

Thank you in advance

07-29 23:35:38.279: E/AndroidRuntime(10353): FATAL EXCEPTION: main
07-29 23:35:38.279: E/AndroidRuntime(10353): Process: com.sapires.JoesPizzariaGEN, PID: 10353
07-29 23:35:38.279: E/AndroidRuntime(10353): android.view.InflateException: Binary XML file line #8: Error inflating class fragment
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at com.sapires.JoesPizzaria.Mapa.onCreateView(Mapa.java:16)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1504)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:482)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.support.v4.view.ViewPager$3.run(ViewPager.java:249)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.Choreographer.doCallbacks(Choreographer.java:603)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.Choreographer.doFrame(Choreographer.java:572)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.os.Handler.handleCallback(Handler.java:733)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.os.Handler.dispatchMessage(Handler.java:95)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.os.Looper.loop(Looper.java:136)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.app.ActivityThread.main(ActivityThread.java:5579)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at java.lang.reflect.Method.invoke(Native Method)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
07-29 23:35:38.279: E/AndroidRuntime(10353): Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f070016, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.app.Activity.onCreateView(Activity.java:5002)
07-29 23:35:38.279: E/AndroidRuntime(10353):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:695)
07-29 23:35:38.279: E/AndroidRuntime(10353):    ... 25 more

Layout of Fragment Map

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    <fragment
        android:id="@+id/fragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment" />
</LinearLayout>

Class

    package com.sapires.JoesPizzaria;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

public class TabPagerAdapter extends FragmentStatePagerAdapter {
    public TabPagerAdapter(FragmentManager fm) {
        super(fm);
        // TODO Auto-generated constructor stub
    }

    @Override
    public Fragment getItem(int i) {
        switch (i) {
        case 0:
            return new APizzaria();
        case 1:
            return new Ementa();
        case 2:
            return new Mapa();
        }
        return null;

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return 3; //No of Tabs
    }
    }
    
asked by anonymous 30.07.2014 / 00:41

1 answer

1

The error is due to LayoutInflater trying to add to the Activity layout a fragment that had already been added previously (exception triggered here ). The reason for this is that FragmentStatePagerAdapter wants to display the same fragment twice on the screen. It does this because it is not removing the FragmentManager fragment when it should, since it is a "child" fragment of the fragment that is effectively removed (fragment within another fragment or nested fragment ). The "parent" fragment is removed from FragmentManager and the "child" remains. The child fragment in question is MapFragment included in res/layout/mapa.xml with id R.id.fragment .

The error is not due to the application trying to add to FragmentManager two instances of MapFragment identified in the same way, as I stated earlier.

Solution

According to this answer in SOen for the nested fragments run the child fragment has to be added dynamically in the code rather than including it in the layout as it is being done. This excerpt from the documentation illustrates this:

  

Note: You can not inflate a layout into a fragment when that layout includes a . Nested fragments are only supported when added to a fragment dynamically.

This means that the code for the files /res/layout/mapa.xml and Mapa.java should be changed as follows (note the replacement of MapFragment with SupportMapFragment , among other changes):

/res/layout/mapa.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

</RelativeLayout>

Mapa.java

package com.sapires.JoesPizzaria;

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

import com.google.android.gms.maps.SupportMapFragment;
import com.sapires.JoesPizzariaGEN.R;

public class Mapa extends Fragment {

    private SupportMapFragment mFragmentoDoMapa;

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

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mFragmentoDoMapa = SupportMapFragment.newInstance();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.container, mFragmentoDoMapa);
        ft.commit();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getFragmentManager().beginTransaction().remove(mFragmentoDoMapa).commit();
    }
}

Note however that this adds flicker when the user goes to the map tab, that is, the screen gives a "blink" due to the sudden addition of SupportMapFragment to the layout. To resolve this, make ViewPager instantiate only once the fragments created for each tab and preserve those instances between screen changes by adding the line Tab.setOffscreenPageLimit(2); to the class MainActivity.java :

Tab.setAdapter(TabAdapter);
Tab.setOffscreenPageLimit(2);

Another possible solution

You can remove the instance of MapFragment from FragmentManager along with the destruction of the Mapa fragment. One place where this can be done is just before the return new Mapa(); line, make the way you're doing Mapa to remove the snippet with the R.id.fragment id. Another place where this can be done is in one of the methods Mapa.onDestroyView() , Mapa.onDetach() or Mapa.onDestroy() (the latter is the most appropriate).

    
30.07.2014 / 02:50