com.google.android.gms.maps.MapFragment의 다른 조각과 중복 된 ID, 태그 null 또는 부모 ID


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

이것을 시도하십시오-return super.onCreateView (inflater, container, savedInstanceState); super.onCreateView (inflater, container, savedInstanceState) 대신; inflater.inflate (R.layout.main, 컨테이너, false)를 반환합니다.
Nik

savedInstanceState가 null이 아닌 경우 조각을 추가하지 않습니다.
muyiou

이 의견을 살펴보십시오. 도움이 될 것입니다 : stackoverflow.com/questions/15562416/…
Oleksandr

2
허용 된 답변을 변경하십시오! 메모리 누수를 일으키는 매우 나쁜 답변을 선택했습니다! : 정답은 이것이다 stackoverflow.com/a/19815266/902276
다니엘 Segato

답변:


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 (android : id = "@ + id / mapFragment")가 포함 된 "map.xml"(R.layout.map)은 다음과 같습니다.

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

이것이 도움이되기를 바랍니다.하지만 부작용이 없음을 보장 할 수는 없습니다.

편집 : 응용 프로그램을 종료하고 다시 시작할 때와 같은 부작용이 발생했습니다. 응용 프로그램이 반드시 완전히 종료되지는 않지만 (백그라운드에서 잠자기 상태로) 응용 프로그램을 다시 시작하면 제출 한 이전 코드가 실패합니다. 맵에 들어가거나 나가고 응용 프로그램을 종료했다가 다시 시작하는 코드를 업데이트했습니다 .try-catch 비트에 너무 만족하지는 않지만 충분히 잘 작동하는 것 같습니다. 스택 추적을 볼 때 맵 조각이 FragmentManager에 있는지 확인하고 try-catch 블록이 필요하지 않고 코드가 업데이트되었는지 확인할 수 있습니다.

더 많은 편집 : 결국 그 try-catch가 필요하다는 것이 밝혀졌습니다. 지도 조각을 검사하는 것만으로도 제대로 작동하지 않는 것으로 나타났습니다. 블러그.


25
이것은 잘못된 답변입니다 -1! 뷰에 정적 수정자를 사용하여 활동을 유출하고 있습니다. 이 문제의 근본 원인은 아마도 유출 된 또 다른 활동 일 것입니다.이 활동은이를 가리키는 강력한 참조를 유지하기 때문에 가비지 수집 될 수 없습니다. InflateException이 발생하면 활동이 파괴 된 컨텍스트를 가진 뷰를 사용하고 있습니다! 앱에서 다른 메모리 누수를 더 잘 찾으면 모든 문제가 해결됩니다.
tomrozb

1
메모리 누출을 피하기 위해 WeakReference를 사용할 수 있습니까?
Desmond Lua

2
이것은 나에게도 +1입니다. 정적 참조를 사용해야 할 의무는 없습니다.
Karol Żygłowicz

4
이러지마 !!! 메모리 누수가 발생합니다. 이것이 발생하는 유일한 이유는 다른 조각 내부의 XML에서 조각을 팽창시키기 때문입니다. 당신은 그렇게하지 않아야합니다! ChildFragmentManager를 사용하고 onViewCreated ()에 조각을 추가해야합니다!
Daniele Segato

1
예, 이것은 실제로 활동을 누출시킵니다. stackoverflow.com/a/27592123/683763 에서 작동하는 솔루션을 찾았습니다 . 아이디어는 SupportMapFragmentin onDestroyView메소드 를 수동으로 제거하는 것 입니다 .
ULazdins

277

문제는 당신이하려는 일을해서는 안된다는 것입니다. 다른 조각 안에 조각을 부풀려서는 안됩니다. 안드로이드 문서에서 :

참고 : 레이아웃에 <fragment>가 포함되어 있으면 레이아웃을 조각으로 팽창시킬 수 없습니다. 중첩 된 조각은 조각에 동적으로 추가 된 경우에만 지원됩니다.

여기에 제시된 해킹으로 작업을 수행 할 수는 있지만 그렇게하지 않는 것이 좋습니다. 이러한 해킹이 다른 조각을 포함하는 조각의 레이아웃을 부풀 리려고 할 때 각각의 새로운 Android OS가 수행하는 작업을 처리하는지 확인하는 것은 불가능합니다.

다른 프래그먼트에 프래그먼트를 추가하는 유일한 Android 지원 방법은 하위 프래그먼트 관리자의 트랜잭션을 이용하는 것입니다.

XML 레이아웃을 빈 컨테이너로 변경하기 만하면됩니다 (필요한 경우 ID 추가).

<?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/… 도 참조하십시오 .
Kristopher Johnson 1

정의 된 XML을 4.3사용할 때이 문제가 발생했습니다 SupportMapFragment. 조각을 동적으로 만들어 컨테이너보기에 주입하면 문제가 해결되었습니다. 이 SO 답변을 참조하십시오 .
theblang

매우 유용한 답변입니다. onCreate () 메인 함수에 대한 콜백을 어떻게 할 수 있습니까?
유토피아

2
문서에 따르면 SupportMapFragment.newInstance(); developers.google.com/maps/documentation/android-api/map
Jemshit Iskenderov를

178

나는 같은 문제가 있었고 클래스 MapFragmentonDestroy()메소드 에서 수동으로를 제거하여 해결할 수있었습니다 Fragment. 다음은 MapFragmentXML에서 by 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것이 탭 사이를 전환 하는 데 좋은 것처럼 보이지만 조각에 사용하면이 동작으로 인해 동일한 ID를 가진 MapView각 새 항목에 복제본 이 만들어집니다 MapFragment. 해결책은 수동으로MapFragment 조각을 하여 조각이 팽창 될 때마다 기본 맵을 다시 작성하는 것입니다.

나는 또 다른 답변에서 이것을 언급했다 [ 1 ].


개발자 옵션에서 "활동을 유지하지 마십시오"와 함께 장치의 홈 버튼을 클릭하면 앱이 중단됩니다.
jul

24
난 내 화면을 회전하면이 작품은, 그러나, 내 응용 프로그램이 예외와 충돌 : 인한 기준 : java.lang.IllegalStateException : onSaveInstanceState 후이 작업을 수행 할 수 없습니다
jramoyo

1
관심이있는 사람들은 조각의 생성자에 초기 방향을 저장하고 방향이 변경되지 않은 경우에만 위의 트랜잭션을 호출하여 화면 회전으로 인한 예외를 제거 할 수 있습니다. 변경 된 경우 회전 후 뷰를 새로 만들 때 ID가 없으므로 중복 ID로 어려움을 겪을 필요가 없습니다. Matt가 마음에 들지 않으면 답변을 편집하고 코드 스 니펫을 제공 할 수 있습니다.
Stan

1
흠 나를 위해지도 조각이 제거되지 않습니다. 뭔가 잘못하고 있어야하지만 getActivity (). getSupportFragmentManager (). getFragments ()를 호출하면 remove (f) .commit 호출 후에 조각이 남아 있습니다. 왜 그런지 아는 사람이 있습니까? (getFragManager를 getSupportFragManager로 교체했습니다)
Daniel Wilson

10
commitAllowingStateLoss는 IllegalStateException 예외를 피합니다.
Héctor Júdez Sapena

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, Fragment 클래스에서 프로그래밍 방식으로 Google 맵을 추가하십시오.

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. 왜 그런지 알아?
Anas Azeem

@AnasAzeem은 프로그래밍 방식으로 조각을 생성하여 문제를 정확하게 해결합니다. 귀하의 경우 솔루션에 대한 mMap을 얻을 필요가 없습니다.
yesildal

@AnasAzeem은 get getMapAsync를 사용해야하며 백그라운드에서 초기화 후 맵 인스턴스를 올바르게 반환합니다. 이것은 구글지도 작업의 "올바른"방법이며 조각과 아무 상관이
가네 Krishnan

10
  1. @Justin Breitfeller가 언급했듯이 @Vidar Wahlberg 솔루션은 향후 버전의 Android에서는 작동하지 않을 수 있습니다.
  2. @Vidar Wahlberg는 다른 솔루션이 "맵을 다시 작성하고 다시 그려야하므로 항상 바람직하지는 않기 때문에"해킹을 유발합니다. 매번 새 인스턴스를 만드는 대신 이전 맵 조각을 유지하면 맵 다시 그리기를 방지 할 수 있습니다.
  3. @Matt 솔루션이 작동하지 않습니다 (IllegalStateException)
  4. @Justin Breitfeller가 인용 한 것처럼 "레이아웃에 포함 된 레이아웃에는 조각으로 레이아웃을 부 풀릴 수 없습니다. 중첩 된 조각은 조각에 동적으로 추가 된 경우에만 지원됩니다."

내 해결책 :

@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 귀하의 솔루션이 완벽하게 작동했습니다. 기억해야 할 것은 레이아웃에서 맵을 만들지 않는 것입니다. 이 솔루션의 맵 생성은 코드에 포함되므로 <fragment android : name = "com.google.android.gms.maps.SupportMapFragment">를 <LinearLayout id = "@ + id / map />로 변경하십시오.
kosiara-Bartosz Kosarzycki

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 개)지도를 호스팅 탭은.


그러나 맵 문제가 발생하는 것보다 분리 창을 사용하는 경우해야 할 일보다 outofmmry 오류를 대체하십시오.
Vishal Android 개발자

3

다른 해결책 :

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

그것은 null이 아니라면 부모에서 제거하는 것이 불필요한 단계이므로 다시 초기화 할 필요가 없습니다.


이것은 내 경우에 가장 적합한 솔루션입니다. 내 탐색 그래프에 두 개의 조각을 사용하여 오류가 발생하여 문제가 해결되었습니다.
케네디 캄보

이것은 내 경우에 가장 적합한 솔루션입니다. 내 탐색 그래프에 두 개의 조각을 사용하여 오류가 발생하여 문제가 해결되었습니다.
케네디 캄보

2

오늘 이유를 찾기 위해 시간을 잃었습니다. 다행히도이 문제는 MapFragment 구현 때문이 아닙니다. 아직도 중첩 된 조각은 rev 11의 지원 라이브러리를 통해서만 지원되기 때문에 작동하지 않습니다.

내 구현에는 두 개의 탭 (뷰 페이저 없음)이있는 작업 표시 줄 (탭 모드)이있는 활동이 있습니다. 하나는 맵이 있고 다른 하나는 항목 목록이 있습니다. 물론 나는 탭 조각 내에서 MapFragment를 사용하는 것이 순진했습니다.

(내 탭 조각이 다른 조각을 포함하는 레이아웃에 팽창하는 경우에도 동일한 문제가 발생합니다).

한 가지 옵션은 약간의 오버 헤드와 함께 MapFragment 대신 MapView를 사용하는 것입니다 ( MapView Docs 참조) layout.xml의 드롭 인 대체로 , 또 다른 옵션은 rev. 11에서 support-library를 사용하지만 프로그래밍 방식을 취하는 것입니다 중첩 된 조각은 레이아웃을 통해 지원되지 않거나 조각을 명시 적으로 파괴하여 프로그래밍 방식으로 해결합니다 (Mat / Vidar의 답변에서와 같이) btw : MapView (옵션 1)를 사용하여 동일한 효과를 얻습니다.

그러나 실제로 탭을 누를 때마다 맵을 풀고 싶지 않았습니다. 즉, 메모리에 보관하고 활동이 끝날 때만 정리하고 싶었으므로 탭하면서 맵을 숨기거나 표시하기로 결정했습니다. FragmentTransaction / hide


2

여전히이 문제가 발생하는 사람들을 위해 탭의 맵 에서이 오류가 발생하지 않도록하는 가장 좋은 방법은 탭에 사용 된 조각 내부 SupportMapFragment에 중첩 대신 조각을 확장하는 것입니다 SupportMapFragment.

난 그냥 이것을 사용하여 작업 가지고 ViewPagerA를을 FragmentPagerAdapter세 번째 탭에서 SupportMapFragment와 함께.

일반적인 구조는 다음과 같습니다. 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);

View pager는 대기열을 구현하므로 해당 조각을 제거하지 않아도됩니다. 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
Mina Fawzy의

나는 코드의 저자가 아닙니다-방금 질문에 게시 된 코드를 사용했습니다. 헤르만에게 물어봐야합니다.
JJD

0

Vidar Wahlberg 답변 만 사용하는 경우 다른 활동 (예 :)을 열고지도로 돌아올 때 오류가 발생합니다. 또는 제 경우에는 다른 활동을 연 다음 새 활동에서 다시 맵을 엽니 다 (뒤로 버튼 사용하지 않음). 그러나 Vidar Wahlberg 솔루션과 Matt 솔루션을 결합하면 예외는 없습니다.

나열한 것

<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

나는 viewPager에서 이것을 가지고 있었고 충돌은 모든 조각에 자체 태그가 있어야하고 동일한 조각에 대한 중복 태그 또는 ID가 허용되지 않기 때문에 충돌이 발생했습니다.


0

하위 Fragment의 이전 App-Compat lib에 버그가 있다고 생각합니다. @Vidar Wahlberg와 @Matt의 ans를 시도했지만 그들은 나를 위해 작동하지 않았습니다. appcompat 라이브러리를 업데이트 한 후 추가 노력없이 코드가 완벽하게 실행됩니다.


0

여기에 유의해야 할 사항은 다음 두 경우 중 하나에서 앱이 심하게 충돌하는 것입니다.

1) 다시 맵으로 프래그먼트를 재사용하려면 맵을 보여주는 프래그먼트가 onDestroyView 콜백에서 다른 프래그먼트로 대체되었을 때 MapView 프래그먼트를 제거해야합니다.

그렇지 않으면 동일한 조각을 두 번 팽창 시키려고 할 때 com.google.android.gms.maps.MapFragment 오류에 대해 다른 조각으로 중복 ID, 태그 null 또는 부모 ID를 두 번 넣으려고하면 오류가 발생합니다.

2) 둘째, app.Fragment 작업과 android.support.v4.app.Fragment API 작업을 혼합해서는 안됩니다. 예를 들어 v4.app.Fragment 유형 MapView Fragment를 제거하기 위해 android.app.FragmentTransaction을 사용하지 마십시오. 이것을 혼합하면 조각 쪽에서 충돌이 다시 발생합니다.

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

}

XML

 <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지도를 SupportMapFragmentPlaceAutocompleteFragment 로 사용 하고 있었습니다 . 모든 답변에서 문제는 SupportMapFragment가 맵을 다시 작성하고 다시 그려야한다는 사실을 지적했지만 발굴 후 내 문제는 실제로 PlaceAutocompleteFragment 알았습니다.

따라서 SupportMapFragmentSupportMapFragment인해이 문제에 직면 한 사람들을위한 효과적인 솔루션이 있습니다.

 //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 Places로 하나 Dialog또는 다른 것을 열 때 이러한 유형의 오류가 발생 합니다.FragmentAutocompleteSupportFragment

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지도 API의 사용되지 않는 이전 버전입니다 알게
Ankur 가우 탐
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.