2

私は実験を行っておりandroid.support.v4.widget.DrawerLayout、引き出しから選択する 4 つのフラグメントがあります。マップは最初は問題なく読み込まれますが、ドロワーを開いてフラグメントを変更すると、マップに戻ることができません。黒い画面が表示されます。Logcat はフラグメントが再作成されたことを示していますが、何も得られません。ただ真っ黒な画面。問題なく他のフラグメントを切り替えることができます。私は何を間違っていますか?私のプロジェクトの最小 API は 14 です。

ExploreMapここから(フラグメント)をロードしMainActivity.javaます:

        if (position == 0){
            ExploreMap exMap = new ExploreMap();
            exMap.setRetainInstance(true);
            getFragmentManager().beginTransaction().replace(R.id.content_frame, exMap).commit();
        }

ExploreMap.java私は次のことをします

public class ExploreMap extends Fragment implements OnInfoWindowClickListener, android.location.LocationListener, OnMapLongClickListener{

 private LocationManager mLocManager;
 private GoogleMap mMap;
 private MapFragment mMapFragment;

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

        FragmentManager fm = getActivity().getFragmentManager();
        mMapFragment = (MapFragment) fm.findFragmentById(R.id.map);


        if (mMapFragment == null) {
            mMapFragment = MapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map, mMapFragment).commit();
        }


        if (savedInstanceState == null) {
            // First incarnation of this activity.
            mMapFragment.setRetainInstance(true);
        }else {
            // Reincarnated activity. The obtained map is the same map instance in the previous
            // activity life cycle. There is no need to reinitialize it.
            mMap = mMapFragment.getMap();
        }

        createMapIfNeeded();


       return inflater.inflate(R.layout.explore_map_layout, container, false);
    }




    @Override
    public void onResume() {
        super.onResume();
        //create the map
       createMapIfNeeded();  
    }





    private void createMapIfNeeded(){

        if(mLocManager == null){
            mLocManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            mLocManager.requestLocationUpdates(
                       LocationManager.NETWORK_PROVIDER,
                       MIN_TIME_BW_UPDATES,
                       MIN_DISTANCE_CHANGE_FOR_UPDATES,
                       this);
        }

         //locmanager can return null if no last known locaiton is available.
        location = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);


        //if a map has not already been instantiated it'll return null
        if(mMap == null){
            //instantiate map
            mMap = mMapFragment.getMap();
            //check it has been instantiated

            if(mMap != null){   
                mMap.setOnMapLongClickListener(this);
                mMap.setOnInfoWindowClickListener(this);
                mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                mMap.setMyLocationEnabled(true);

                //Manipulate map here (add coordinates/polylines from trip etc etc.)
                UiSettings setting = mMap.getUiSettings();
                setting.setTiltGesturesEnabled(true);
                setting.setRotateGesturesEnabled(true);
                setting.setZoomControlsEnabled(true);
                setting.setMyLocationButtonEnabled(true);

                if(location != null){
                CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15);
                mMap.animateCamera(cu);
                }
            }
        }  
    }

XML は次のとおりです。

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

    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         The drawer is given a fixed width in dp and extends the full height of
         the container. A solid background is used for contrast
         with the content view. -->
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

exploremap_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


        <FrameLayout
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
4

3 に答える 3

2

何日も頭を壁にぶつけた後、私は問題を見つけました。tsp は上記のライブラリを使用することを提案しましたが、これも機能しますが、これを Google が提供するandroid.support.v4.widget.DrawerLayout.

問題は 2 倍でした。

  1. ネストされたフラグメントを使用していましたが、ExploreMap フラグメントを離れるときに子 (マップ) フラグメントを削除していませんでした。私の階層は、Activity(DrawerLayout)-->ExploreMap(A Fragment)-->MapFragment です。ドロワーを開いてフラグメントを変更するときに、MapFragment を ExploreMap(fragment) から削除していませんでした。が原因で、元の MapFragment インスタンスがメモリに残っていましたsetRetainInstance(true)。ExplorerMap フラグメントに戻ると、MapFragment の元のインスタンスが再表示されないことをまだ完全には理解していません。これを解決するために、MapFragment が最初に作成されたときに「mapfrag」と呼ばれる文字列タグを割り当て、変数を に設定しますpublic static。次に、ドロワー コードがフラグメントを切り替えるアクティビティで、findFragmentByTag()その をテストしnull、null でない場合は MapFragment を削除します。

ただし、#1は、ExploreMapに戻ったときにマップが再表示されるため、途中までしか取得GoogleMapできませんが、MapFragmentの基になるものがnullを返し続け、マップをまったく構成できませんでした。

2) この投稿MapFragment return nullを見つけました。独自の MapFragment を拡張し、MapFragment の作成が完了したときに通知するインターフェイスを実装することをお勧めします。これにより、null 以外の GoogleMap がほぼ保証されます。

そしてワーミー!! googles drawer レイアウトに作業中の google マップがあります。これが私の完全な作業コードです。

MainActivity.java
 if (position == 0){
                exMap = new ExploreMap();
                exMap.setRetainInstance(true);
                getFragmentManager().beginTransaction().replace(R.id.content_frame, exMap).commit();
            }
            if(position == 1){  
                //remove map frag here instead of in explore map
                Fragment f = getFragmentManager().findFragmentByTag("mapfrag");
                if(f != null){
                     getFragmentManager().beginTransaction().remove(f).commit();
                }

                Ms fragment = new Ms();
                getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit(); 
            }
            if(position == 2){
                Fragment f = getFragmentManager().findFragmentByTag("mapfrag");
                if(f != null){
                     getFragmentManager().beginTransaction().remove(f).commit();
                }
                Settings fragment = new Settings();
                getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit(); 
            }
            if(position == 3){
                Fragment f = getFragmentManager().findFragmentByTag("mapfrag");
                if(f != null){
                     getFragmentManager().beginTransaction().remove(f).commit();
                }
                About fragment = new About();
                getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit(); 
            }

ExploreMap.java

public class ExploreMap extends Fragment implements MyMapFragment.MapCallback,  OnInfoWindowClickListener, android.location.LocationListener, OnMapLongClickListener{

     private LocationManager mLocManager;
     private GoogleMap mMap;
     public static MyMapFragment mMapFragment;

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


            FragmentManager fm = getActivity().getFragmentManager();
            mMapFragment = (MyMapFragment) fm.findFragmentById(R.id.map_framelayout);


            if (mMapFragment == null) {
                mMapFragment = new MyMapFragment();
                mMapFragment.setRetainInstance(true);
                mMapFragment.setMapCallback(this);
                fm.beginTransaction().replace(R.id.map_framelayout, mMapFragment,"mapfrag").commit();
            }

            createMapIfNeeded();

            return v;
        }



        @Override
        public void onMapReady(GoogleMap map) {
            createMapIfNeeded();
        }   

private void createMapIfNeeded(){

            if(mLocManager == null){
                mLocManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
                mLocManager.requestLocationUpdates(
                           LocationManager.NETWORK_PROVIDER,
                           MIN_TIME_BW_UPDATES,
                           MIN_DISTANCE_CHANGE_FOR_UPDATES,
                           this);
            }

             //locmanager can return null if no last known locaiton is available.
            location = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);


            //if a map has not already been instantiated it'll return null
            if(mMap == null){
                //instantiate map
                mMap = mMapFragment.getMap();


                //check it has been instantiated
                if(mMap != null){
                    mMap.setOnMapLongClickListener(this);
                    mMap.setOnInfoWindowClickListener(this);
                    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                    mMap.setMyLocationEnabled(true);

                    //Manipulate map here (add coordinates/polylines from trip etc etc.)
                    UiSettings setting = mMap.getUiSettings();
                    setting.setTiltGesturesEnabled(true);
                    setting.setRotateGesturesEnabled(true);
                    setting.setZoomControlsEnabled(true);
                    setting.setMyLocationButtonEnabled(true);

                    if(location != null){
                    CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15);
                    mMap.animateCamera(cu);
                    }
                }
            }  
        }

そしていまMyMapFragment.java

public class MyMapFragment extends MapFragment{



      private MapCallback callback;

      public static interface MapCallback
      {
         public void onMapReady(GoogleMap map);
      }

      public void setMapCallback(MapCallback callback)
      {
        this.callback = callback;
      }

      @Override public void onActivityCreated(Bundle savedInstanceState)
      {
          super.onActivityCreated(savedInstanceState);
         if(callback != null) callback.onMapReady(getMap());     
      }


}

乾杯!!!

于 2013-10-25T03:33:30.500 に答える
0

これがうまくいくことを願っています: https://github.com/jfeinstein10/SlidingMenu https://play.google.com/store/apps/details?id=com.slidingmenu.example&hl=en

于 2013-10-18T04:41:07.407 に答える