ID duplikat, tag nol, atau id induk dengan fragmen lain untuk com.google.android.gms.maps.MapFragment

334

Saya punya aplikasi dengan tiga tab.

Setiap tab memiliki tata letak .xml file sendiri. Main.xml memiliki fragmen peta sendiri. Itu yang muncul saat aplikasi pertama kali diluncurkan.

Semuanya berfungsi dengan baik kecuali ketika saya mengubah antar tab. Jika saya mencoba untuk beralih kembali ke tab fragmen peta, saya mendapatkan kesalahan ini. Beralih ke dan di antara tab lain berfungsi dengan baik.

Apa yang salah di sini?

Ini adalah kelas utama saya dan main.xml saya, serta kelas yang relevan yang saya gunakan (Anda juga akan menemukan log kesalahan di bagian bawah)

kelas utama

package com.nfc.demo;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.Toast;

public class NFCDemoActivity extends Activity {

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

        ActionBar bar = getActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

        bar.addTab(bar
                .newTab()
                .setText("Map")
                .setTabListener(
                        new TabListener<MapFragment>(this, "map",
                                MapFragment.class)));
        bar.addTab(bar
                .newTab()
                .setText("Settings")
                .setTabListener(
                        new TabListener<SettingsFragment>(this, "settings",
                                SettingsFragment.class)));
        bar.addTab(bar
                .newTab()
                .setText("About")
                .setTabListener(
                        new TabListener<AboutFragment>(this, "about",
                                AboutFragment.class)));

        if (savedInstanceState != null) {
            bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
        }
        // setContentView(R.layout.main);

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
    }

    public static class TabListener<T extends Fragment> implements
            ActionBar.TabListener {
        private final Activity mActivity;
        private final String mTag;
        private final Class<T> mClass;
        private final Bundle mArgs;
        private Fragment mFragment;

        public TabListener(Activity activity, String tag, Class<T> clz) {
            this(activity, tag, clz, null);
        }

        public TabListener(Activity activity, String tag, Class<T> clz,
                Bundle args) {
            mActivity = activity;
            mTag = tag;
            mClass = clz;
            mArgs = args;

            // Check to see if we already have a fragment for this tab,
            // probably from a previously saved state. If so, deactivate
            // it, because our initial state is that a tab isn't shown.
            mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
            if (mFragment != null && !mFragment.isDetached()) {
                FragmentTransaction ft = mActivity.getFragmentManager()
                        .beginTransaction();
                ft.detach(mFragment);
                ft.commit();
            }
        }

        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            if (mFragment == null) {
                mFragment = Fragment.instantiate(mActivity, mClass.getName(),
                        mArgs);
                ft.add(android.R.id.content, mFragment, mTag);
            } else {
                ft.attach(mFragment);
            }
        }

        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            if (mFragment != null) {
                ft.detach(mFragment);
            }
        }

        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT)
                         .show();
        }
    }

}

main.xml

<?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:orientation="vertical" >

    <fragment
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/mapFragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

kelas yang relevan (MapFragment.java)

package com.nfc.demo;

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

public class MapFragment extends Fragment {

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

    public void onDestroy() {
        super.onDestroy();
    }
}

kesalahan

android.view.InflateException: Binary XML file line #7: 
     Error inflating class fragment
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
   at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
   at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
   at com.nfc.demo.MapFragment.onCreateView(MapFragment.java:15)
   at android.app.Fragment.performCreateView(Fragment.java:1695)
   at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
   at android.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1255)
   at android.app.BackStackRecord.run(BackStackRecord.java:672)
   at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
   at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
   at android.os.Handler.handleCallback(Handler.java:725)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:5039)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
   at dalvik.system.NativeStart.main(Native Method)

Caused by: java.lang.IllegalArgumentException: 
     Binary XML file line #7: Duplicate id 0x7f040005, tag null, or 
     parent id 0xffffffff with another fragment for 
     com.google.android.gms.maps.MapFragment
   at android.app.Activity.onCreateView(Activity.java:4722)
   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
   ... 19 more
hermann
sumber
coba ini - kembalikan super.onCreateView (inflater, container, SavedInstanceState); alih-alih super.onCreateView (inflater, container, SavedInstanceState); return inflater.inflate (R.layout.main, wadah, false);
Nik
Anda shuold tidak menambahkan Anda fragmen ketika disimpanInstanceState bukan nol.
muyiou
Lihatlah komentar ini. Ini mungkin membantu Anda: stackoverflow.com/questions/15562416/…
Oleksandr
2
Silakan ubah jawaban yang diterima! Anda memilih jawaban yang sangat buruk yang menyebabkan kebocoran memori! Jawaban yang benar adalah ini: stackoverflow.com/a/19815266/902276
Daniele Segato

Jawaban:

400

Jawaban yang disarankan Matt berhasil, tetapi menyebabkan peta dibuat ulang dan digambar ulang, yang tidak selalu diinginkan. Setelah banyak coba-coba, saya menemukan solusi yang berfungsi untuk saya:

private static View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }
    try {
        view = inflater.inflate(R.layout.map, container, false);
    } catch (InflateException e) {
        /* map is already there, just return view as it is */
    }
    return view;
}

Untuk ukuran yang baik, inilah "map.xml" (R.layout.map) dengan R.id.mapFragment (android: id = "@ + id / mapFragment"):

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

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

Saya harap ini membantu, tetapi saya tidak dapat menjamin bahwa itu tidak memiliki efek buruk.

Sunting: Ada beberapa efek buruk, seperti ketika keluar dari aplikasi dan memulainya lagi. Karena aplikasi tidak sepenuhnya dimatikan (tetapi hanya ditidurkan di latar belakang), kode sebelumnya yang saya kirimkan akan gagal setelah memulai ulang aplikasi. Saya telah memperbarui kode ke sesuatu yang bekerja untuk saya, baik masuk & keluar dari peta dan keluar dan memulai kembali aplikasi, saya tidak terlalu senang dengan sedikit try-catch, tetapi tampaknya bekerja dengan cukup baik. Ketika melihat jejak stack, terpikir oleh saya bahwa saya bisa memeriksa apakah fragmen peta ada di FragmentManager, tidak perlu untuk blok try-catch, kode diperbarui.

Lebih banyak hasil pengeditan: Ternyata Anda memerlukan try-catch itu. Hanya memeriksa fragmen peta ternyata tidak berfungsi dengan baik. Blergh.

Vidar Wahlberg
sumber
25
Ini adalah jawaban yang salah -1! Anda membocorkan aktivitas menggunakan pengubah statis untuk Tampilan. Akar penyebab masalah ini mungkin adalah aktivitas bocor lainnya, yang tidak dapat dikumpulkan dengan sampah karena Anda menyimpan referensi yang kuat untuk menunjuknya. Jika ada InflateException yang dilemparkan, Anda menggunakan tampilan yang memiliki konteks aktivitas yang hancur! Lebih baik menemukan kebocoran memori lain di aplikasi Anda, ini akan menyelesaikan semua masalah.
tomrozb
1
Saya kira kita bisa menggunakan WeakReference untuk menghindari kebocoran memori?
Desmond Lua
2
Ini juga berfungsi untuk saya +1. Anda tidak berkewajiban untuk menggunakan referensi tampilan statis
Karol Żygłowicz
4
Jangan lakukan ini !!! Ini menyebabkan kebocoran memori. Satu-satunya alasan ini terjadi adalah karena Anda menggembungkan sebuah fragmen dari XML di dalam fragmen lain. Anda TIDAK seharusnya melakukan itu! Anda harus menggunakan ChildFragmentManager dan menambahkan fragmen di onViewCreated ()!
Daniele Segato
1
Ya, ini memang akan membocorkan aktivitas. Menemukan solusi yang berfungsi di stackoverflow.com/a/27592123/683763 . Idenya adalah untuk menghapus metode SupportMapFragmentin secara manual onDestroyView.
ULazdins
277

Masalahnya adalah bahwa apa yang Anda coba lakukan seharusnya tidak dilakukan. Anda seharusnya tidak menggembungkan fragmen di dalam fragmen lain. Dari dokumentasi Android :

Catatan: Anda tidak dapat mengembang tata letak menjadi fragmen ketika tata letak itu menyertakan <fragment>. Fragmen bersarang hanya didukung ketika ditambahkan ke fragmen secara dinamis.

Meskipun Anda mungkin dapat menyelesaikan tugas dengan retasan yang disajikan di sini, saya sangat menyarankan Anda untuk tidak melakukannya. Mustahil untuk memastikan bahwa peretasan ini akan menangani apa yang dilakukan oleh masing-masing OS Android baru ketika Anda mencoba mengembang tata letak untuk sebuah fragmen yang berisi fragmen lain.

Satu-satunya cara yang didukung Android untuk menambahkan fragmen ke fragmen lain adalah melalui transaksi dari manajer fragmen anak.

Cukup ubah tata letak XML Anda menjadi wadah kosong (tambahkan ID jika perlu):

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

Kemudian dalam onViewCreated(View view, @Nullable Bundle savedInstanceState)metode Fragmen :

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment");
    if (mapFragment == null) {
        mapFragment = new SupportMapFragment();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment");
        ft.commit();
        fm.executePendingTransactions();
    }
    mapFragment.getMapAsync(callback);
}
Justin Breitfeller
sumber
4
Lihat stackoverflow.com/questions/13733299/... untuk contoh membuat fragmen peta secara terprogram dan menginisialisasi peta.
Kristopher Johnson
1
Lihat juga stackoverflow.com/questions/19239175/… untuk solusi bug yang nyata dalam dukungan fragmen anak.
Kristopher Johnson
Saya mengalami masalah ini 4.3ketika menggunakan SupportMapFragmentdidefinisikan dalam XML. Secara dinamis membuat fragmen dan menyuntikkannya ke tampilan wadah menyelesaikan masalah. Lihat jawaban SO ini .
theblang
Jawaban yang sangat berguna. Bagaimana kita bisa melakukan panggilan balik ke fungsi utama onCreate ()?
Utopia
2
Menurut doc, gunakan SupportMapFragment.newInstance(); developers.google.com/maps/documentation/android-api/map
Jemshit Iskenderov
178

Saya memiliki masalah yang sama dan mampu mengatasinya secara manual menghapus MapFragmentdalam onDestroy()metode dari Fragmentkelas. Berikut adalah kode yang berfungsi dan referensi MapFragmentdengan ID dalam XML:

@Override
public void onDestroyView() {
    super.onDestroyView();
    MapFragment f = (MapFragment) getFragmentManager()
                                         .findFragmentById(R.id.map);
    if (f != null) 
        getFragmentManager().beginTransaction().remove(f).commit();
}

Jika Anda tidak menghapus MapFragmentsecara manual, itu akan bertahan sehingga tidak membutuhkan banyak sumber daya untuk membuat ulang / menampilkan tampilan peta lagi. Tampaknya menjaga yang mendasarinya MapViewbagus untuk beralih bolak-balik di antara tab, tetapi ketika digunakan dalam fragmen perilaku ini menyebabkan duplikat MapViewdibuat pada setiap baru MapFragmentdengan ID yang sama. Solusinya adalah dengan secara manual menghapus MapFragmentdan dengan demikian menciptakan kembali peta yang mendasarinya setiap kali fragmen meningkat.

Saya juga mencatat ini dalam jawaban lain [ 1 ].

Mat
sumber
Itu membuat aplikasi macet ketika mengklik tombol beranda perangkat, dengan "Don't keep activities" di opsi pengembang.
Juli
24
ini berfungsi, tetapi jika saya memutar layar saya, aplikasi saya mogok dengan pengecualian ini: Disebabkan oleh: java.lang.IllegalStateException: Tidak dapat melakukan tindakan ini setelah diSaveInstanceState
jramoyo
1
Bagi mereka yang mungkin tertarik, Anda dapat menghilangkan pengecualian yang disebabkan oleh rotasi layar dengan menyimpan orientasi inital dalam konstruktor fragmen dan memanggil transaksi di atas hanya jika orientasi TIDAK diubah. Jika itu diubah, tidak perlu berjuang dengan duplikat ID, karena itu tidak ada ketika tampilan dibuat lagi setelah rotasi. Saya dapat mengedit jawabannya dan memberikan potongan kode, jika Matt tidak keberatan.
Stan
1
Hmm bagi saya fragmen peta tidak dihapus. Saya pasti melakukan sesuatu yang salah tetapi jika saya panggil getActivity (). GetSupportFragmentManager (). GetFragments (), fragmennya tetap ada setelah pemanggilan hapus (f) .commit. Adakah yang tahu mengapa? (Saya mengganti getFragManager dengan getSupportFragManager)
Daniel Wilson
10
commitAllowingStateLoss akan menghindari pengecualian IllegalStateException.
Héctor Júdez Sapena
22

Ini jawaban saya:

1, Buat tata letak xml seperti berikut:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

2, di kelas Fragmen, tambahkan google map secara terprogram.

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link android.support.v4.app.Fragment} subclass. Activities that
 * contain this fragment must implement the
 * {@link MapFragment.OnFragmentInteractionListener} interface to handle
 * interaction events. Use the {@link MapFragment#newInstance} factory method to
 * create an instance of this fragment.
 * 
 */
public class MapFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    private GoogleMap mMap;

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_map, container, false);
        SupportMapFragment mMapFragment = SupportMapFragment.newInstance();
        mMap = mMapFragment.getMap();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.add(R.id.map_container, mMapFragment).commit();
        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d("Attach", "on attach");
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }
} 
Zou
sumber
2
mMapFragment.getMap();kembali null. Ada yang tahu kenapa?
Anas Azeem
@AnasAzeem, membuat fragmen secara terprogram menyelesaikan masalah dengan tepat, Anda tidak perlu mendapatkan mMap untuk solusi yang mungkin ada dalam kasus Anda.
yesildal
@AnasAzeem Anda harus menggunakan get getMapAsync yang akan mengembalikan instance peta dengan benar setelah diinisialisasi (di latar belakang). Ini adalah cara "benar" untuk bekerja dengan peta google dan tidak ada hubungannya dengan fragmen
Ganesh Krishnan
10
  1. Seperti disebutkan oleh @Justin Breitfeller, solusi @Vidar Wahlberg adalah peretasan yang mungkin tidak berfungsi di versi Android yang akan datang.
  2. @Vidar Wahlberg melakukan peretasan karena solusi lain mungkin "menyebabkan peta dibuat ulang dan digambar ulang, yang tidak selalu diinginkan". Redraw peta dapat dicegah dengan mempertahankan fragmen peta lama, daripada membuat instance baru setiap saat.
  3. @Matt solusi tidak bekerja untuk saya (IllegalStateException)
  4. Seperti dikutip oleh @Justin Breitfeller, "Anda tidak dapat mengembang tata letak menjadi fragmen ketika tata letak itu termasuk a. Fragmen bersarang hanya didukung ketika ditambahkan ke fragmen secara dinamis."

Solusi saya:

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

    // init
    //mapFragment = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map);
    // don't recreate fragment everytime ensure last map location/state are maintain
    if (mapFragment == null) {
        mapFragment = SupportMapFragment.newInstance();
        mapFragment.getMapAsync(this);
    }
    FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
    // R.id.map is a layout
    transaction.replace(R.id.map, mapFragment).commit();

    return view;
}
Desmond Lua
sumber
2
Terima kasih @Desmond Solusi Anda bekerja dengan sempurna untuk saya. Satu-satunya hal yang perlu Anda ingat adalah BUKAN untuk membuat peta di tata letak. Pembuatan peta dalam solusi ini tertanam dalam kode sehingga ubah <fragmen android: name = "com.google.android.gms.maps.SupportMapFragment"> menjadi mis. <LinearLayout id = "@ + id / map />
kosiara - Bartosz Kosarzycki
7

Nyatakan objek SupportMapFragment secara global

    private SupportMapFragment mapFragment;

Dalam metode onCreateView () tuliskan kode di bawah ini

mapFragment = (SupportMapFragment) getChildFragmentManager()
            .findFragmentById(R.id.map);
 mapFragment.getMapAsync(this);

Di onDestroyView () masukkan kode di bawah ini

@Override
public void onDestroyView() {
   super.onDestroyView();

    if (mapFragment != null)
        getFragmentManager().beginTransaction().remove(mapFragment).commit();
}

Dalam file xml Anda, letakkan kode di bawah ini

 <fragment
    android:id="@+id/map"
    android:name="com.abc.Driver.fragment.FragmentHome"
    class="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

Kode di atas menyelesaikan masalah saya dan berfungsi dengan baik

Digvijay Machale
sumber
3

Saya akan merekomendasikan replace()daripada attach()/ detach()dalam penanganan tab Anda.

Atau, beralih ke ViewPager. Berikut adalah contoh proyek yang menunjukkan ViewPager, dengan tab, menampung 10 peta.

CommonsWare
sumber
Tetapi ganti kesalahan give outofmemry daripada apa yang harus dilakukan jika kita menggunakan jendela detach daripada masalah peta terjadi.
Pengembang Android Vishal
3

Solusi lain:

if (view == null) {
    view = inflater.inflate(R.layout.nearbyplaces, container, false);
}

Itu saja, jika bukan nol Anda tidak perlu menginisialisasi ulang menghapusnya dari induk adalah langkah yang tidak perlu.

AnonymousDev
sumber
Ini adalah solusi terbaik untuk kasus saya. Saya mendapatkan kesalahan itu karena menggunakan dua fragmen untuk grafik navigasi saya dan ini memperbaiki masalah saya.
Kennedy Kambo
Ini adalah solusi terbaik untuk kasus saya. Saya mendapatkan kesalahan itu karena menggunakan dua fragmen untuk grafik navigasi saya dan ini memperbaiki masalah saya.
Kennedy Kambo
2

Saya kehilangan jam hari ini untuk menemukan alasannya, untungnya masalah ini bukan karena implementasi MapFragment, sayangnya, ini tidak berhasil karena fragmen bersarang hanya didukung melalui perpustakaan dukungan dari rev 11.

Implementasi saya memiliki aktivitas dengan actionbar (dalam mode tab) dengan dua tab (tanpa viewpager), yang satu memiliki peta dan yang lainnya memiliki daftar entri. Tentu saja saya sudah cukup naif untuk menggunakan MapFragment di dalam tab-fragmen saya, dan voila aplikasi mogok setiap kali saya kembali ke tab-peta.

(Masalah yang sama saya juga akan memiliki jika tab-fragmen saya akan mengembang tata letak yang mengandung fragmen lain).

Salah satu opsi adalah menggunakan MapView (bukan MapFragment), dengan beberapa overhead (lihat MapView Docs sebagai pengganti drop-in di layout.xml, opsi lain adalah menggunakan perpustakaan dukungan naik dari rev. 11 tetapi kemudian mengambil pendekatan programatik karena fragmen yang bersarang tidak didukung melalui tata letak atau hanya bekerja secara terprogram dengan menghancurkan fragmen secara eksplisit (seperti dalam jawaban dari Matt / Vidar), btw: efek yang sama dicapai dengan menggunakan MapView (opsi 1).

Tapi sebenarnya, saya tidak ingin kehilangan peta setiap kali saya tab, yaitu, saya ingin menyimpannya di memori dan pembersihan hanya setelah aktivitas ditutup, jadi saya memutuskan untuk hanya menyembunyikan / menampilkan peta saat menabrak, lihat FragmentTransaction / hide

datangGameSome
sumber
2

Bagi mereka yang masih mengalami masalah ini, cara terbaik untuk memastikan Anda tidak mendapatkan kesalahan ini dengan Peta di Tab adalah untuk membuat Fragmen diperluas SupportMapFragmentdaripada bersarang SupportMapFragmentdi dalam Fragmen yang digunakan untuk Tab.

Saya baru saja menggunakan ini ViewPagerdengan FragmentPagerAdapter, dengan SupportMapFragment di Tab ketiga.

Berikut adalah struktur umum, perhatikan tidak perlu menimpa onCreateView()metode, dan tidak perlu mengembang tata letak xml:

public class MapTabFragment extends SupportMapFragment 
                                    implements OnMapReadyCallback {

    private GoogleMap mMap;
    private Marker marker;


    public MapTabFragment() {
    }

    @Override
    public void onResume() {
        super.onResume();

        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {

        if (mMap == null) {

            getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        mMap = googleMap;
        setUpMap();
    }

    private void setUpMap() {

        mMap.setMyLocationEnabled(true);
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        mMap.getUiSettings().setMapToolbarEnabled(false);


        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {

                //remove previously placed Marker
                if (marker != null) {
                    marker.remove();
                }

                //place marker where user just clicked
                marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker")
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));

            }
        });

    }


}

Hasil:

masukkan deskripsi gambar di sini

Berikut adalah kode kelas lengkap yang saya gunakan untuk menguji, yang mencakup Fragmen placeholder yang digunakan untuk dua Tab pertama, dan Fragmen Peta yang digunakan untuk Tab ketiga:

public class MainActivity extends AppCompatActivity implements ActionBar.TabListener{


    SectionsPagerAdapter mSectionsPagerAdapter;

    ViewPager mViewPager;

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

        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        final ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
        }

    }


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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }


    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    return PlaceholderFragment.newInstance(position + 1);
                case 1:
                    return PlaceholderFragment.newInstance(position + 1);
                case 2:
                    return MapTabFragment.newInstance(position + 1);
            }

            return null;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();

            switch (position) {
                case 0:
                    return getString(R.string.title_section1).toUpperCase(l);
                case 1:
                    return getString(R.string.title_section2).toUpperCase(l);
                case 2:
                    return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }


    public static class PlaceholderFragment extends Fragment {

        private static final String ARG_SECTION_NUMBER = "section_number";

        TextView text;

        public static PlaceholderFragment newInstance(int sectionNumber) {
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public PlaceholderFragment() {
        }

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

            text = (TextView) rootView.findViewById(R.id.section_label);
            text.setText("placeholder");

            return rootView;
        }
    }

    public static class MapTabFragment extends SupportMapFragment implements
            OnMapReadyCallback {

        private static final String ARG_SECTION_NUMBER = "section_number";

        private GoogleMap mMap;
        private Marker marker;


        public static MapTabFragment newInstance(int sectionNumber) {
            MapTabFragment fragment = new MapTabFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public MapTabFragment() {
        }

        @Override
        public void onResume() {
            super.onResume();

            Log.d("MyMap", "onResume");
            setUpMapIfNeeded();
        }

        private void setUpMapIfNeeded() {

            if (mMap == null) {

                Log.d("MyMap", "setUpMapIfNeeded");

                getMapAsync(this);
            }
        }

        @Override
        public void onMapReady(GoogleMap googleMap) {
            Log.d("MyMap", "onMapReady");
            mMap = googleMap;
            setUpMap();
        }

        private void setUpMap() {

            mMap.setMyLocationEnabled(true);
            mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
            mMap.getUiSettings().setMapToolbarEnabled(false);


            mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

                @Override
                public void onMapClick(LatLng point) {

                    Log.d("MyMap", "MapClick");

                    //remove previously placed Marker
                    if (marker != null) {
                        marker.remove();
                    }

                    //place marker where user just clicked
                    marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker")
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));

                    Log.d("MyMap", "MapClick After Add Marker");

                }
            });

        }
    }
}
Daniel Nugent
sumber
2

Saya menghargai semua jawaban tetapi saya menemukan solusi liner satu ini: Jika n Adalah Jumlah tab maka:

 mViewPager.setOffscreenPageLimit(n);

Contoh: Dalam hal disebutkan:

 mViewPager.setOffscreenPageLimit(2);

Lihat pager menerapkan antrian jadi, Anda tidak harus membiarkannya menghapus fragmen itu. onCreateView disebut hanya sekali.

Jayant Arora
sumber
1

Anda mengembalikan atau menggembungkan tata letak dua kali, cukup periksa untuk melihat apakah Anda hanya mengembang satu kali.

Mahdi Giveie
sumber
0

Sudahkah Anda mencoba mereferensikan MapFragmentkelas khusus Anda di file tata letak?

<?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:orientation="vertical" >

    <fragment
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/mapFragment"
        android:name="com.nfc.demo.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
JJD
sumber
tolong posting kode untuk fragmen peta khusus com.nfc.demo.MapFragment
Mina Fawzy
Saya bukan pembuat kode - Saya hanya menggunakan kode yang diposting. Anda harus bertanya pada hermann.
JJD
0

Jika Anda hanya akan menggunakan jawaban Vidar Wahlberg, Anda mendapatkan kesalahan saat Anda membuka aktivitas lain (misalnya) dan kembali ke peta. Atau dalam kasus saya buka aktivitas lain lalu dari aktivitas baru buka peta lagi (tanpa menggunakan tombol kembali). Tetapi ketika Anda menggabungkan solusi Vidar Wahlberg dan solusi Matt, Anda tidak akan memiliki pengecualian.

tata letak

<com.example.ui.layout.MapWrapperLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/map_relative_layout">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/root">

        <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" />
    </RelativeLayout>
</<com.example.ui.layout.MapWrapperLayout>

Pecahan

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    setHasOptionsMenu(true);
    if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null){
            parent.removeView(view);
        }
    }
    try {
        view = inflater.inflate(R.layout.map_view, null);
        if(view!=null){
            ViewGroup root = (ViewGroup) view.findViewById(R.id.root);
...

@Override
public void onDestroyView() {
    super.onDestroyView();
    Fragment fragment = this.getSherlockActivity().getSupportFragmentManager().findFragmentById(R.id.map);
    if (fragment != null)
        getFragmentManager().beginTransaction().remove(fragment).commit();
}
Vlad Hudnitsky
sumber
0

Saya punya ini di viewPager dan crash karena setiap fragmen harus memiliki tag sendiri, duplikat tag atau id untuk fragmen yang sama tidak diperbolehkan.

pengguna1396018
sumber
0

Saya pikir ada beberapa bug di lib App-Compat sebelumnya untuk Fragmen anak. Saya mencoba @Vidar Wahlberg dan @ Matt dan mereka tidak bekerja untuk saya. Setelah memperbarui pustaka appcompat kode saya berjalan dengan sempurna tanpa usaha ekstra.

gila d
sumber
0

Hal yang Perlu Dicatat di sini adalah aplikasi Anda akan rusak parah di salah satu dari dua kasus: -

1) Untuk menggunakan kembali fragmen dengan Maps lagi MapView Fragment harus dihapus ketika fragmen Anda yang menampilkan Maps diganti dengan fragmen lain dalam panggilan balik onDestroyView.

lain ketika Anda mencoba untuk mengembang fragmen yang sama dua kali ID duplikat, tag nol, atau id induk dengan fragmen lain untuk com.google.android.gms.maps.MapFragment kesalahan akan terjadi.

2) Kedua, Anda tidak boleh mencampur operasi app.Fragment dengan android.support.v4.app.Fragment API misalnya operasi.tidak menggunakan android.app.FragmentTransaction untuk menghapus v4.app.tipe fragmen MapView Fragment. Mencampur ini lagi akan menghasilkan crash dari sisi fragmen.

Berikut ini cuplikan kode sampel untuk penggunaan MapView yang benar

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.serveroverload.yago.R;

/**
 * @author 663918
 *
 */
public class HomeFragment extends Fragment implements LocationListener {
    // Class to do operations on the Map
    GoogleMap googleMap;
    private LocationManager locationManager;

    public static Fragment newInstance() {
        return new HomeFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.home_fragment, container, false);
        Bundle bdl = getArguments();

        // setuping locatiomanager to perfrom location related operations
        locationManager = (LocationManager) getActivity().getSystemService(
                Context.LOCATION_SERVICE);

        // Requesting locationmanager for location updates
        locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, 1, 1, this);

        // To get map from MapFragment from layout
        googleMap = ((MapFragment) getActivity().getFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        // To change the map type to Satellite
        // googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

        // To show our current location in the map with dot
        // googleMap.setMyLocationEnabled(true);

        // To listen action whenever we click on the map
        googleMap.setOnMapClickListener(new OnMapClickListener() {

            @Override
            public void onMapClick(LatLng latLng) {
                /*
                 * LatLng:Class will give us selected position lattigude and
                 * longitude values
                 */
                Toast.makeText(getActivity(), latLng.toString(),
                        Toast.LENGTH_LONG).show();
            }
        });

        changeMapMode(2);

        // googleMap.setSatellite(true);
        googleMap.setTrafficEnabled(true);
        googleMap.setBuildingsEnabled(true);
        googleMap.setMyLocationEnabled(true);

        return v;
    }

    private void doZoom() {
        if (googleMap != null) {
            googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(18.520430, 73.856744), 17));
        }
    }

    private void changeMapMode(int mapMode) {

        if (googleMap != null) {
            switch (mapMode) {
            case 0:
                googleMap.setMapType(GoogleMap.MAP_TYPE_NONE);
                break;

            case 1:
                googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                break;

            case 2:
                googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                break;

            case 3:
                googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                break;

            case 4:
                googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                break;

            default:
                break;
            }
        }
    }

    private void createMarker(double latitude, double longitude) {
        // double latitude = 17.385044;
        // double longitude = 78.486671;

        // lets place some 10 random markers
        for (int i = 0; i < 10; i++) {
            // random latitude and logitude
            double[] randomLocation = createRandLocation(latitude, longitude);

            // Adding a marker
            MarkerOptions marker = new MarkerOptions().position(
                    new LatLng(randomLocation[0], randomLocation[1])).title(
                    "Hello Maps " + i);

            Log.e("Random", "> " + randomLocation[0] + ", " + randomLocation[1]);

            // changing marker color
            if (i == 0)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
            if (i == 1)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
            if (i == 2)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_CYAN));
            if (i == 3)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
            if (i == 4)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            if (i == 5)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
            if (i == 6)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED));
            if (i == 7)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
            if (i == 8)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_VIOLET));
            if (i == 9)
                marker.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));

            googleMap.addMarker(marker);

            // Move the camera to last position with a zoom level
            if (i == 9) {
                CameraPosition cameraPosition = new CameraPosition.Builder()
                        .target(new LatLng(randomLocation[0], randomLocation[1]))
                        .zoom(15).build();

                googleMap.animateCamera(CameraUpdateFactory
                        .newCameraPosition(cameraPosition));
            }
        }

    }

    /*
     * creating random postion around a location for testing purpose only
     */
    private double[] createRandLocation(double latitude, double longitude) {

        return new double[] { latitude + ((Math.random() - 0.5) / 500),
                longitude + ((Math.random() - 0.5) / 500),
                150 + ((Math.random() - 0.5) * 10) };
    }

    @Override
    public void onLocationChanged(Location location) {

        if (null != googleMap) {
            // To get lattitude value from location object
            double latti = location.getLatitude();
            // To get longitude value from location object
            double longi = location.getLongitude();

            // To hold lattitude and longitude values
            LatLng position = new LatLng(latti, longi);

            createMarker(latti, longi);

            // Creating object to pass our current location to the map
            MarkerOptions markerOptions = new MarkerOptions();
            // To store current location in the markeroptions object
            markerOptions.position(position);

            // Zooming to our current location with zoom level 17.0f
            googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,
                    17f));

            // adding markeroptions class object to the map to show our current
            // location in the map with help of default marker
            googleMap.addMarker(markerOptions);
        }

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onDestroyView() {
        // TODO Auto-generated method stub
        super.onDestroyView();

        locationManager.removeUpdates(this);

        android.app.Fragment fragment = getActivity().getFragmentManager()
                .findFragmentById(R.id.map);
        if (null != fragment) {
            android.app.FragmentTransaction ft = getActivity()
                    .getFragmentManager().beginTransaction();
            ft.remove(fragment);
            ft.commit();
        }
    }

}

XML

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

Hasilnya terlihat seperti ini: -masukkan deskripsi gambar di sini

Semoga ini bisa membantu Seseorang.

Hitesh Sahu
sumber
0

Dalam solusi ini Anda tidak perlu mengambil variabel statis;

Button nextBtn;

private SupportMapFragment mMapFragment;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);

    if (mRootView != null) {
        ViewGroup parent = (ViewGroup) mRootView.getParent();
        Utility.log(0,"removeView","mRootView not NULL");
        if (parent != null) {
            Utility.log(0, "removeView", "view removeViewed");
            parent.removeAllViews();
        }
    }
    else {
        try {
            mRootView = inflater.inflate(R.layout.dummy_fragment_layout_one, container, false);//
        } catch (InflateException e) {
    /* map is already there, just return view as it is  */
            e.printStackTrace();
        }
    }

    return  mRootView;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.mapView);
    if (mapFragment == null) {
        mapFragment = new SupportMapFragment();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.mapView, mapFragment, "mapFragment");
        ft.commit();
        fm.executePendingTransactions();
    }
    //mapFragment.getMapAsync(this);
    nextBtn = (Button) view.findViewById(R.id.nextBtn);
    nextBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Utility.replaceSupportFragment(getActivity(),R.id.dummyFragment,dummyFragment_2.class.getSimpleName(),null,new dummyFragment_2());
        }
    });

}`
Lalit kumar
sumber
0

Saya agak terlambat ke pesta tetapi tidak ada jawaban yang membantu saya dalam kasus saya. Saya menggunakan Google map sebagai SupportMapFragment dan PlaceAutocompleteFragment baik dalam fragmen saya. Karena semua jawaban menunjuk pada fakta bahwa masalahnya adalah dengan SupportMapFragment menjadi peta yang akan dibuat kembali dan digambar ulang. Tapi setelah menggali menemukan masalah saya sebenarnya dengan PlaceAutocompleteFragment

Jadi di sini adalah solusi untuk mereka yang menghadapi masalah ini karena SupportMapFragment dan SupportMapFragment

 //Global SupportMapFragment mapFragment;
 mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapFragment);
    FragmentManager fm = getChildFragmentManager();

    if (mapFragment == null) {
        mapFragment = SupportMapFragment.newInstance();
        fm.beginTransaction().replace(R.id.mapFragment, mapFragment).commit();
        fm.executePendingTransactions();
    }

    mapFragment.getMapAsync(this);

    //Global PlaceAutocompleteFragment autocompleteFragment;


    if (autocompleteFragment == null) {
        autocompleteFragment = (PlaceAutocompleteFragment) getActivity().getFragmentManager().findFragmentById(R.id.place_autoCompleteFragment);

    }

Dan di onDestroyView hapus SupportMapFragment dan SupportMapFragment

@Override
public void onDestroyView() {
    super.onDestroyView();


    if (getActivity() != null) {
        Log.e("res","place dlted");
        android.app.FragmentManager fragmentManager = getActivity().getFragmentManager();
        android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.remove(autocompleteFragment);
        fragmentTransaction.commit(); 
       //Use commitAllowingStateLoss() if getting exception 

        autocompleteFragment = null;
    }


}
Ratul Bin Tazul
sumber
0

Coba atur id (android: id = "@ + id / maps_dialog") untuk tata letak induk mapView Anda. Bekerja untukku.

hieudev develo
sumber
0

Siapa pun yang datang ke sini sekarang yang mendapatkan jenis kesalahan ini ketika membuka Dialogatau lainnya Fragmentdengan Google Places AutocompleteSupportFragment, coba ini satu-liner (saya tidak tahu seberapa aman ini tetapi ini berfungsi untuk saya):

autocompleteFragment.getFragmentManager().beginTransaction().remove(autocompleteFragment).commit();

sebelum Anda menolak / menghancurkan fragmen Anda.

barnacle.m
sumber
-1
<?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" >


<com.google.android.gms.maps.MapView
    android:id="@+id/mapview"
    android:layout_width="100dip"
    android:layout_height="100dip"
    android:layout_alignParentTop="true"
    android:layout_alignRight="@+id/textView1"
    android:layout_marginRight="15dp" >
</com.google.android.gms.maps.MapView>

Mengapa Anda tidak menyisipkan peta menggunakan objek MapView alih-alih MapFragment? Saya tidak yakin apakah ada batasan dalam MapView, meskipun saya merasa terbantu.

Ankur Gautam
sumber
Maaf saya jadi tahu bahwa itu adalah versi sebelumnya Google Maps API
Ankur Gautam