Com.google.android.gms.maps.pdf के लिए एक और टुकड़े के साथ डुप्लिकेट आईडी, टैग अशक्त या मूल आईडी


333

मेरे पास तीन टैब के साथ एक एप्लिकेशन है।

प्रत्येक टैब की अपनी लेआउट .xml फ़ाइल होती है। Main.xml का अपना मानचित्र टुकड़ा है। यह वह है जो तब दिखाई देता है जब एप्लिकेशन पहली बार लॉन्च होता है।

जब मैं टैब के बीच बदलता हूं, तो सब कुछ ठीक काम करता है। अगर मैं नक्शे के टुकड़े टैब पर वापस जाने की कोशिश करता हूं, तो मुझे यह त्रुटि मिलती है। अन्य टैब के बीच स्विच करना ठीक काम करता है।

यहां क्या गलत हो सकता है?

यह मेरा मुख्य वर्ग है और मेरा main.xml है, साथ ही एक प्रासंगिक वर्ग है जिसका मैं उपयोग करता हूं (आपको नीचे की ओर त्रुटि लॉग भी मिलेगा)

मुख्य वर्ग

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>

प्रासंगिक वर्ग (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();
    }
}

त्रुटि

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

इसे आज़माएं - super.onCreateView (इनफ्लोटर, कंटेनर, सेवइन्स्टांसस्टैट) लौटें; इसके बजाय super.onCreateView (इनफ्लोटर, कंटेनर, सेवइंस्टेंसस्टैट); वापसी inflater.inflate (R.layout.main, कंटेनर, गलत);
निक

जब आप सहेजे गए टुकड़े को नहीं जोड़ते हैं तो बचाया जाता है। InstanceState शून्य नहीं है।
मुईउउ

इस टिप्पणी पर एक नज़र डालें। यह आपकी मदद कर सकता है: stackoverflow.com/questions/15562416/…
ऑलेक्ज़ेंडर

2
कृपया स्वीकृत उत्तर बदलें! आपने एक बहुत खराब उत्तर चुना जो मेमोरी लीक बनाता है! सही उत्तर यह है: stackoverflow.com/a/19815266/902276
डेनियल सेगाटो

जवाबों:


400

उत्तर मैट का सुझाव देता है, लेकिन यह मानचित्र को फिर से बनाने और पुनः बनाने का कारण बनता है, जो हमेशा वांछनीय नहीं होता है। बहुत परीक्षण और त्रुटि के बाद, मुझे एक समाधान मिला जो मेरे लिए काम करता है:

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;
}

अच्छे उपाय के लिए, यहाँ R.id.mapFragment के साथ "map.xml" (R.layout.map) (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>

मुझे आशा है कि यह मदद करता है, लेकिन मैं यह गारंटी नहीं दे सकता कि इसका कोई प्रतिकूल प्रभाव नहीं है।

संपादित करें: कुछ प्रतिकूल प्रभाव थे, जैसे कि आवेदन से बाहर निकलते समय और इसे फिर से शुरू करना। चूंकि एप्लिकेशन जरूरी पूरी तरह से बंद नहीं हुआ है (लेकिन बस पृष्ठभूमि में सोने के लिए रखा गया है), मेरे द्वारा सबमिट किया गया पिछला कोड एप्लिकेशन को पुनरारंभ करने में विफल होगा। मैंने कोड को कुछ के लिए अद्यतन किया है जो मेरे लिए काम करता है, दोनों मानचित्र के अंदर और बाहर जा रहे हैं और आवेदन से बाहर निकलना और पुनः आरंभ कर रहे हैं, मैं कोशिश-कैच बिट से बहुत खुश नहीं हूं, लेकिन यह बहुत अच्छा काम करता है। जब स्टैक ट्रेस को देखते हुए यह मेरे साथ हुआ कि मैं जांच कर सकता हूं कि क्या नक्शा टुकड़ा FragmentManager में है, तो ट्राइ-कैच ब्लॉक, कोड अपडेट की कोई आवश्यकता नहीं है।

अधिक संपादन: आपको उस प्रयास को पूरा करने की आवश्यकता है, जिसे आप चाहते हैं। बस नक्शे के टुकड़े की जाँच करने से पता चला कि आखिरकार इतना अच्छा काम नहीं हुआ। Blergh।


25
यह गलत उत्तर है -1! आप किसी दृश्य के लिए स्थिर संशोधक का उपयोग करके गतिविधि को लीक कर रहे हैं। इस समस्या का मूल कारण संभवतः एक और लीक हुई गतिविधि है, जिसे इकट्ठा नहीं किया जा सकता क्योंकि आप इसे एक मजबूत संदर्भ इंगित कर रहे हैं। मामले में एक InflateException फेंक दिया गया है, तो आप एक दृश्य का उपयोग कर रहे हैं जिसमें नष्ट गतिविधि का संदर्भ है! अपने ऐप में अन्य मेमोरी लीक को बेहतर तरीके से ढूंढें, इससे सभी समस्याएं हल हो जाएंगी।
टॉमहॉर्ब

1
मुझे लगता है कि हम मेमोरी लीक से बचने के लिए WeakReference का उपयोग कर सकते हैं?
डेसमंड लुआ

2
यह मेरे लिए भी काम करता है +1। आप देखने के स्थिर संदर्भ का उपयोग करने के लिए बाध्य नहीं हैं
करोल łygłowicz

4
ऐसा मत करो !!! यह स्मृति रिसाव का कारण बनता है। ऐसा होने का एकमात्र कारण यह है कि आप XML से एक टुकड़े को दूसरे टुकड़े के अंदर प्रवाहित कर रहे हैं। आप ऐसा करने वाले नहीं हैं! आपको चाइल्डफ्रैगमेंट मैनजर का उपयोग करना चाहिए और ऑन व्यू क्रिएट () में टुकड़े को जोड़ना चाहिए!
डेनियल सेगाटो

1
हां, यह वास्तव में गतिविधि को लीक कर देगा। में एक काम कर समाधान मिले stackoverflow.com/a/27592123/683763 । विधि SupportMapFragmentमें मैन्युअल रूप से हटाने के लिए विचार है onDestroyView
उलजदिंस

277

समस्या यह है कि आप जो करने की कोशिश कर रहे हैं वह नहीं किया जाना चाहिए। आपको अन्य टुकड़ों के अंदर अंशों को नहीं बढ़ाना चाहिए। Android के दस्तावेज़ से :

नोट: जब आप उस लेआउट में एक <टुकड़ा> शामिल होते हैं, तो आप एक टुकड़े को एक टुकड़े में नहीं बढ़ा सकते। घोंसले के टुकड़े का समर्थन केवल तब किया जाता है जब एक टुकड़े को गतिशील रूप से जोड़ा जाता है।

जब आप यहां प्रस्तुत हैक के साथ कार्य को पूरा करने में सक्षम हो सकते हैं, तो मेरा सुझाव है कि आप ऐसा नहीं करते हैं। यह सुनिश्चित करना असंभव है कि ये हैक संभाल लेंगे कि प्रत्येक नया एंड्रॉइड ओएस क्या करता है जब आप एक टुकड़े के लिए एक लेआउट को बढ़ाने की कोशिश करते हैं जिसमें एक टुकड़ा होता है।

एक टुकड़े में दूसरे टुकड़े को जोड़ने का एकमात्र एंड्रॉइड-समर्थित तरीका बाल टुकड़ा प्रबंधक से लेनदेन के माध्यम से है।

बस अपने XML लेआउट को एक खाली कंटेनर में बदलें (यदि आवश्यक हो तो एक आईडी जोड़ें):

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

फिर फ्रैगमेंट onViewCreated(View view, @Nullable Bundle savedInstanceState)विधि में:

@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);
}

4
देखें stackoverflow.com/questions/13733299/... प्रोग्राम के रूप में एक नक्शा टुकड़ा बनाने और नक्शा आरंभ के उदाहरण के लिए।
क्रिस्टोफर जॉनसन

1
बाल टुकड़े समर्थन में स्पष्ट बग के लिए वर्कअराउंड के लिए stackoverflow.com/questions/19239175/… भी देखें ।
क्रिस्टोफर जॉनसन

XML में 4.3एक SupportMapFragmentपरिभाषित का उपयोग करते समय मुझे इस मुद्दे का सामना करना पड़ा । गतिशील रूप से टुकड़ा बनाने और इसे कंटेनर दृश्य में इंजेक्ट करने से समस्या हल हो गई। इस SO उत्तर को देखें ।
theblang

बहुत उपयोगी जवाब। हम onCreate () मुख्य फ़ंक्शन को कॉलबैक कैसे कर सकते हैं?
यूटोपिया

2
डॉक्टर के अनुसार, SupportMapFragment.newInstance(); डेवलपर्स का
http://www.maps/documentation/android-api/map

178

मेरे पास एक ही मुद्दा था और कक्षा MapFragmentकी onDestroy()विधि में मैन्युअल रूप से हटाकर इसे हल करने में सक्षम था Fragment। यहाँ वह कोड है MapFragmentजो XML में ID द्वारा काम करता है और संदर्भित करता है :

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

यदि आप MapFragmentमैन्युअल रूप से नहीं निकालते हैं , तो यह चारों ओर लटका देगा ताकि मानचित्र को फिर से देखने / दिखाने के लिए बहुत सारे संसाधनों की लागत न हो। ऐसा लगता है कि अंतर्निहित रखना MapViewटैब के बीच आगे और पीछे स्विच करने के लिए बहुत अच्छा है, लेकिन जब टुकड़ों में उपयोग किया जाता है तो यह व्यवहार एक ही आईडी के साथ MapViewप्रत्येक नए पर एक डुप्लिकेट बनाया जाता है MapFragment। समाधान मैन्युअल रूप से हटाने के लिए है MapFragmentऔर इस प्रकार टुकड़े को फुलाए जाने पर हर बार अंतर्निहित नक्शे को फिर से बनाना है।

मैंने एक अन्य उत्तर में भी इसका उल्लेख किया [ 1 ]।


डेवलपर के विकल्पों में "गतिविधियां न रखें" के साथ डिवाइस के होम बटन पर क्लिक करने पर यह ऐप क्रैश कर देता है।
जुलाई

24
यह काम करता है, लेकिन अगर मैं अपनी स्क्रीन को घुमाता हूं, तो मेरा ऐप इस अपवाद के साथ क्रैश हो जाता है: इसके कारण: java.lang.IllegalStateException: onSaveInstanceState
jramoyo

1
उन लोगों के लिए जो रूचि ले सकते हैं, आप अंश के निर्माण में इनबिल्ट ओरिएंटेशन को संग्रहीत करके स्क्रीन रोटेशन के कारण होने वाले अपवाद को समाप्त कर सकते हैं और उपरोक्त लेन-देन को केवल तभी कॉल कर सकते हैं जब अभिविन्यास नहीं बदला गया था। यदि इसे बदल दिया गया था, तो डुप्लिकेट आईडी के साथ संघर्ष करने की कोई आवश्यकता नहीं है, क्योंकि रोटेशन के बाद नए सिरे से दृश्य बनाए जाने पर यह नहीं है। मैं जवाब को संपादित कर सकता हूं और एक कोड स्निपेट प्रदान कर सकता हूं, अगर मैट को कोई आपत्ति नहीं है।
स्टैन

1
मेरे लिए हम्म का नक्शा टुकड़ा नहीं हटाया जा रहा है। मुझे कुछ गलत करना चाहिए, लेकिन अगर मुझे getActivity () कहते हैं। क्या किसी को कोई विचार है क्यों? (मैंने getFragManager को getSupportFragManager से बदल दिया)
डैनियल विल्सन

10
प्रतिबद्धAllowingStateLoss IllegalStateException अपवाद से बच जाएगा।
हेक्टर जुडेज़ सपना

22

यह मेरा जवाब है:

1, निम्नलिखित की तरह एक लेआउट xml बनाएँ:

<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, फ्रैगमेंट वर्ग में, प्रोग्रामेटिक रूप से एक गूगल मैप जोड़ें।

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();
    }
} 

2
mMapFragment.getMap();लौटता है null। कोई विचार क्यों?
अनस अज़ीम

@AanasAzeem, खंडित प्रोग्राम बनाने से समस्या का हल ठीक हो जाता है, आपको समाधान के लिए mMap प्राप्त करने की आवश्यकता नहीं है।
येसिल्डल डे

@AnasAzeem आपको getMapAsync का उपयोग करना चाहिए जो मानचित्रण को प्रारंभिक रूप से (पृष्ठभूमि में) करने के बाद सही तरीके से लौटाएगा। यह गूगल मैप्स के साथ काम करने का "सही" तरीका है और इसका टुकड़ों से कोई लेना-देना नहीं है
गणेश कृष्णन

10
  1. जैसा कि @ जस्टिन ब्रेइटफेलर द्वारा उल्लेख किया गया है, @ विदर वाह्लबर्ग समाधान एक हैक है जो एंड्रॉइड के भविष्य के संस्करण में काम नहीं कर सकता है।
  2. @Vidar Wahlberg एक हैक को टाल देती है क्योंकि अन्य समाधान "मानचित्र को फिर से बनाने और पुन: डिज़ाइन करने का कारण हो सकता है, जो हमेशा वांछनीय नहीं होता है"। हर बार एक नया उदाहरण बनाने के बजाय पुराने नक्शे के टुकड़े को बनाए रखने से मैप रिड्रा को रोका जा सकता है।
  3. @ मैट समाधान मेरे लिए काम नहीं करता है (IllegalStateException)
  4. जैसा कि @ जस्टिन ब्रेइटफेलर के हवाले से कहा गया है, "जब आप उस लेआउट को शामिल करते हैं, तो आप किसी टुकड़े को लेआउट में नहीं बढ़ा सकते हैं। नेस्टेड टुकड़े को केवल तब जोड़ा जाता है, जब किसी टुकड़े को गतिशील रूप से जोड़ा जाता है।"

मेरा समाधान:

@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;
}

2
धन्यवाद @Desmond आपका समाधान मेरे लिए त्रुटिपूर्ण काम करता है। केवल एक चीज जो आपको याद रखने की जरूरत है वह है लेआउट में नक्शा बनाना नहीं। इस समाधान में मानचित्र निर्माण कोड में अंतर्निहित है, इसलिए <खंड Android: नाम = "com.google.android.gms.maps.SupportMapFragment"> से उदा <LinearLayout आईडी = "@ + आईडी / मानचित्र>>
kosiara - Bartosz कोसरज़ी

7

विश्व स्तर पर SupportMapFragment ऑब्जेक्ट घोषित करें

    private SupportMapFragment mapFragment;

OnCreateView () विधि में कोड नीचे रखें

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

OnDestroyView () कोड के नीचे रखें

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

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

अपनी xml फ़ाइल में नीचे कोड डाल दिया

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

उपरोक्त कोड से मेरी समस्या हल हो गई और यह ठीक काम कर रहा है


3

मैं आपके टैब हैंडलिंग में / के replace()बजाय सिफारिश करूंगा ।attach()detach()

या, स्विच करने के लिए ViewPagerयहाँ एक नमूना प्रोजेक्ट दिखाया गया है ViewPagerजिसमें टैब, 10 मानचित्रों की मेजबानी के साथ दिखाया गया है ।


लेकिन अगर हम मानचित्र की समस्या होने की तुलना में डिटैच विंडो का उपयोग करते हैं तो क्या करना चाहिए, इसकी तुलना में आउटफॉमेरी त्रुटि को बदलें।
विशाल एंड्रॉइड डेवलपर

3

एक और समाधान:

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

यही कारण है, अगर शून्य नहीं है, तो आपको इसे माता-पिता से हटाने की आवश्यकता नहीं है अनावश्यक कदम है।


यह मेरे मामले का सबसे अच्छा समाधान है। मुझे अपने नेविगेशन ग्राफ के लिए दो टुकड़ों का उपयोग करने के परिणामस्वरूप यह त्रुटि मिल रही थी और इसने मेरा मुद्दा ठीक कर दिया।
केनेडी काम्बो

यह मेरे मामले का सबसे अच्छा समाधान है। मुझे अपने नेविगेशन ग्राफ के लिए दो टुकड़ों का उपयोग करने के परिणामस्वरूप यह त्रुटि मिल रही थी और इसने मेरा मुद्दा ठीक कर दिया।
कैनेडी काम्बो

2

कारण जानने के लिए मुझे आज घंटों का समय मिल गया है, सौभाग्य से यह मुद्दा MapFragment कार्यान्वयन के कारण नहीं है, दुर्भाग्य से, यह काम नहीं करता है क्योंकि नेस्टेड फ़्रेम्स केवल Rev 11 से समर्थन लाइब्रेरी के माध्यम से समर्थित हैं।

मेरे कार्यान्वयन में दो टैब (कोई दृश्यदर्शी) के साथ एक्शनबार (टैब्ड मोड में) की गतिविधि है, जिसमें एक नक्शा है और दूसरा प्रविष्टियों की एक सूची है। बेशक, मैं अपने टैब-टुकड़ों के अंदर MapFragment का उपयोग करने के लिए काफी अनुभवहीन हूं, एट वॉयला ऐप ने हर उस समय दुर्घटनाग्रस्त कर दिया, जिसे मैंने मैप-टैब पर वापस स्विच किया था।

(एक ही मुद्दा मैं भी मामले में मेरा टैब-टुकड़ा किसी भी अन्य टुकड़े युक्त किसी भी लेआउट बढ़ाना होगा)।

एक विकल्प MapView (MapFragment के बजाय) का उपयोग करने के लिए है, हालांकि कुछ ओवरहेड के साथ (हालांकि MapView डॉक्स को लेआउट -xml में ड्रॉप-इन प्रतिस्थापन के रूप में देखें, एक अन्य विकल्प है रिवाइज 11 से सपोर्ट-लाइब्रेरी का उपयोग करना लेकिन फिर लेमेटिक दृष्टिकोण लेना। चूँकि नेस्टेड अंशों को न तो लेआउट के माध्यम से समर्थित किया गया है। या केवल खंड को नष्ट करके (जैसे मैट / विडार से उत्तर में) विस्फोटक तरीके से प्रोग्रामेटिक रूप से काम कर रहे हैं, btw: उसी प्रभाव को MapView (विकल्प 1) का उपयोग करके प्राप्त किया जाता है।

लेकिन वास्तव में, मैं हर बार जब मैं टैब को मैप को ढीला नहीं करना चाहता था, अर्थात, मैं इसे केवल गतिविधि के करीब स्मृति और सफाई में रखना चाहता था, इसलिए मैंने टैब करते समय बस मैप को छिपाने / दिखाने का निर्णय लिया, FragmentTransaction / Hide देखें


2

उन लोगों के लिए जो अभी भी इस मुद्दे में चल रहे हैं, यह सुनिश्चित करने का सबसे अच्छा तरीका है कि आपको टैब में एक मैप के साथ यह त्रुटि नहीं मिलती है, यह है कि टैब के अंदर उपयोग किए जाने वाले फ्रैगमेंट के अंदर SupportMapFragmentघोंसले के बजाय फ्रैगमेंट का विस्तार करना है SupportMapFragment

मैं सिर्फ तीसरे टैब में SupportMapFragment के ViewPagerसाथ एक का उपयोग कर इस काम मिला है FragmentPagerAdapter

यहां सामान्य संरचना है, ध्यान दें कि onCreateView()विधि को ओवरराइड करने की कोई आवश्यकता नहीं है , और किसी भी लेआउट 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)));

            }
        });

    }


}

परिणाम:

यहां छवि विवरण दर्ज करें

यहां वह पूर्ण श्रेणी कोड है जिसका मैंने परीक्षण किया था, जिसमें पहले दो टैब के लिए उपयोग किए जाने वाले प्लेसहोल्डर फ्रैगमेंट और तीसरे टैब के लिए उपयोग किए जाने वाले मैप फ्रैगमेंट शामिल हैं:

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");

                }
            });

        }
    }
}

2

मैं सभी उत्तरों का सम्मान करता हूं, लेकिन मुझे यह एक लाइनर समाधान मिला: यदि n टैब की संख्या है तो:

 mViewPager.setOffscreenPageLimit(n);

उदाहरण: उल्लेखित मामले में:

 mViewPager.setOffscreenPageLimit(2);

पेजर एक कतार को लागू करता है, तो आपको इसे उस टुकड़े को निकालने की अनुमति नहीं है। onCreateView केवल एक बार कहा जाता है।


1

आप दो बार लेआउट लौटा रहे हैं या फुला रहे हैं, बस यह देखने के लिए जांचें कि क्या आप केवल एक बार फुलाते हैं।



0

क्या आप MapFragmentलेआउट फ़ाइल में अपने कस्टम वर्ग को संदर्भित करने का प्रयास कर रहे हैं ?

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

आप कस्टम मानचित्र टुकड़ा com.nfc.demo.MapFragment के लिए पोस्ट कोड को खुश कर सकता है
मीना Fawzy

मैं कोड का लेखक नहीं हूं - मैंने केवल प्रश्न में पोस्ट किए गए कोड का उपयोग किया है। आपको हरमन से पूछना होगा।
JJD

0

यदि आप केवल Vidar Wahlberg उत्तर का उपयोग करेंगे, तो जब आप अन्य गतिविधि (उदाहरण के लिए) और मानचित्र पर वापस आते हैं तो आपको त्रुटि मिलती है। या मेरे मामले में अन्य गतिविधि खोलें और फिर नई गतिविधि खुले मानचित्र से फिर से (बिना बैक बटन का उपयोग करें)। लेकिन जब आप Vidar Wahlberg solution और Matt solution को मिलाते हैं तो आपके पास अपवाद नहीं होंगे।

ख़ाका

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

टुकड़ा

@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();
}

0

मेरे पास यह देखने के लिए पेजर और क्रैश था क्योंकि किसी भी टुकड़े का अपना टैग होना चाहिए था, उसी टुकड़े के लिए डुप्लिकेट टैग या आईडी की अनुमति नहीं है।


0

मुझे लगता है कि बच्चे के टुकड़े के लिए पिछले ऐप-कम्पैटिबल लिब में कुछ कीड़े थे। मैंने @Vidar Wahlberg और @ मैट एन्स की कोशिश की जो उन्होंने मेरे लिए काम नहीं किए। Appcompat लाइब्रेरी को अपडेट करने के बाद मेरा कोड बिना किसी अतिरिक्त प्रयास के पूरी तरह से चलता है।


0

ध्यान देने योग्य बात यह है कि आपका ऐप दो मामलों में बुरी तरह दुर्घटनाग्रस्त हो जाएगा: -

1) मैप्स के साथ फिर से टुकड़े का पुन: उपयोग करने के लिए, मैप्स फ्रैगमेंट को तब हटा दिया जाना चाहिए, जब मैप्स दिखा रहा है कि मैप्स को अन्य टुकड़े के साथ onDestroyView कॉलबैक में बदल दिया गया है।

जब आप डुप्लिकेट आईडी, टैग नल, या पैरेंट आईडी को दो बार com.google.android.gms.maps.MapFragment त्रुटि के लिए एक ही टुकड़े के साथ एक ही टुकड़े को बढ़ाने की कोशिश करेंगे।

2) दूसरी बात यह है कि आपको android.support.v4.app.ragment एपीआई ऑपरेशन जैसे कि ऐप को बंद नहीं करना चाहिए। जैसे कि v4.app को हटाने के लिए android.app.FragmentTransaction का उपयोग नहीं करते हैं। फ़्रेग्मेंटेशन टाइप करें MapView Fragment। इसे मिलाने से फिर से टुकड़े टुकड़े हो जाएंगे।

MapView के सही उपयोग के लिए यहाँ नमूना कोड स्निपेट है

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();
        }
    }

}

एक्सएमएल

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

परिणाम इस तरह दिखता है: -यहां छवि विवरण दर्ज करें

आशा है कि यह किसी को मदद करेगा।


0

इस समाधान में आपको स्थैतिक चर लेने की आवश्यकता नहीं है;

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());
        }
    });

}`

0

मुझे पार्टी में थोड़ी देर हो गई है, लेकिन इनमें से गैर जवाब ने मेरे मामले में मेरी मदद की। मैं अपने टुकड़े में Google मैप का उपयोग SupportMapFragment और PlaceAutocompleteFragment के रूप में कर रहा था । जैसा कि सभी उत्तर इस तथ्य की ओर इशारा करते हैं कि समस्या SupportMapFragment मानचित्र को फिर से बनाने और पुनः बनाने के लिए है। लेकिन खुदाई के बाद मेरी समस्या का पता चला वास्तव में PlaceAutocompleteFragment के साथ था

तो यहाँ उन लोगों के लिए काम कर रहे समाधान है जो SupportMapFragment और 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);

    }

और onDestroyView में SupportMapFragment और 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;
    }


}

0

अपने mapView जनक लेआउट के लिए एक id (android: id = "@ + id / Maps_dialog") सेट करने का प्रयास करें। मेरे लिये कार्य करता है।


0

यहां आने वाले किसी भी व्यक्ति को इस प्रकार की त्रुटि तब हो रही है जब Google स्थल के साथ Dialogया अन्य Fragmentको खोलते हुए AutocompleteSupportFragment, इस एक-लाइनर को आज़माएं (मुझे नहीं पता कि यह कितना सुरक्षित है लेकिन यह मेरे लिए काम करता है):

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

इससे पहले कि आप अपने टुकड़े को खारिज / नष्ट कर दें।


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

आप MapFragment के बजाय MapView ऑब्जेक्ट का उपयोग करके मैप क्यों नहीं डालते हैं? मुझे यकीन नहीं है कि अगर MapView में कोई सीमा है, हालांकि मुझे यह मददगार लगा।


क्षमा करें, मुझे पता चला है कि Google मैप्स एपीआई का पिछला संस्करण है
अंकुर गौतम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.