Java 使用map fragment从fragment切换会留下一个黑屏

Java 使用map fragment从fragment切换会留下一个黑屏,java,android,google-maps,android-fragments,supportmapfragment,Java,Android,Google Maps,Android Fragments,Supportmapfragment,我在我的三个选项卡式片段中添加了一个全屏地图片段。除了我在标签之间切换时遇到的一个问题外,一切都很好 每次我从带有地图的片段切换到另一个片段时,我都会得到一个黑屏,大约0.2秒。这似乎与使用地图片段在活动中滚动的问题类似 我曾尝试按照其他人的建议在地图顶部添加一个透明视图,但没有效果 这是我的xml: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http:/

我在我的三个选项卡式片段中添加了一个全屏地图片段。除了我在标签之间切换时遇到的一个问题外,一切都很好

每次我从带有地图的片段切换到另一个片段时,我都会得到一个黑屏,大约0.2秒。这似乎与使用地图片段在活动中滚动的问题类似

我曾尝试按照其他人的建议在地图顶部添加一个透明视图,但没有效果

这是我的xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ParkMapFragment">

    <fragment
        android:id="@+id/fullParkMap"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>
有人有什么建议吗

   @Override
public void onDestroyView() {
    super.onDestroyView();
    SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
    if (mapFragment != null) {
        getFragmentManager().beginTransaction().remove(mapFragment).commit();
    }
}
就在这里,您正在移除片段而不替换它。我将使用。替换为一个新片段

大概是这样的:

getFragmentManager().beginTransaction().replace(R.id.your_placeholder, new CustomFragment(), "cstmFragID").commit();
这是一个很好的例子。同时,您可以通过在地图顶部放置另一个视图来使用变通方法,该视图使用与其容器相同的背景色。这使得地图一旦准备好就可以顺利地进入

SupportMapFragment mapFragment = SupportMapFragment.newInstance(new  GoogleMapOptions().zOrderOnTop(true));

由于您总是替换片段,因此始终创建映射,因此解决方法是只加载一次映射片段,其余时间只显示/隐藏片段(就像显示选项卡式片段一样)。

检查视图是否为空,如果不是空,请将其从其父视图中删除。这样,你就看不到黑屏了

请尝试下面的代码

片段:

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class ExhibhitionMap2  extends Fragment implements OnMapClickListener,OnMarkerClickListener{

    View v;
    private  GoogleMap mMap;
    FragmentManager fragmentManager;

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

    //   android = inflater.inflate(R.layout.activity_exhibhition_map, container, false);

         if (v != null) {
                ViewGroup parent = (ViewGroup) v.getParent();
                if (parent != null)
                    parent.removeView(v);
            }
            try {
                 v = inflater.inflate(R.layout.activity_exhibhition_map, container, false);
            } catch (InflateException e) {
                /* map is already there, just return view as it is */
            }

         setUpMapIfNeeded();        
         return v;
     }

     /***** Sets up the map if it is possible to do so *****/
        public  void setUpMapIfNeeded() {
            // Do a null check to confirm that we have not already instantiated the map.
            if (mMap == null) {


                mMap = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map2)).getMap();

                // Check if we were successful in obtaining the map.
                if (mMap != null)
                {
                    mMap.setOnMapClickListener(this);
                    mMap.setOnMarkerClickListener((OnMarkerClickListener) this);

                     MarkerOptions marker = new MarkerOptions().position(new LatLng(36.011513,-115.174853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-1");

                     MarkerOptions marker01 = new MarkerOptions().position(new LatLng(36.111513,-115.204853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-2");

                     MarkerOptions marker02 = new MarkerOptions().position(new LatLng(36.051513,-115.154853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-3");


                     MarkerOptions marker03 = new MarkerOptions().position(new LatLng(36.057513,-115.344853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
                             .title("P-4");

                     MarkerOptions marker1 = new MarkerOptions().position(new LatLng(36.081513,-115.224853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-1");

                     MarkerOptions marker2 = new MarkerOptions().position(new LatLng(36.051513,-115.334853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-2");

                     MarkerOptions marker3 = new MarkerOptions().position(new LatLng(36.101513,-115.124853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-1");

                     MarkerOptions marker4 = new MarkerOptions().position(new LatLng(36.031513,-115.154853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-2");

                     MarkerOptions marker5 = new MarkerOptions().position(new LatLng(36.081513,-115.194853))
                             .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                             .title("F-2");


                     mMap.addMarker(marker);
                     mMap.addMarker(marker01);
                     mMap.addMarker(marker02);
                     mMap.addMarker(marker03);

                     mMap.addMarker(marker1);
                     mMap.addMarker(marker2);
                     mMap.addMarker(marker3);
                     mMap.addMarker(marker4);

                     mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.051513,-115.174853), 10.0f));

                }

            }
        }

    @Override
    public boolean onMarkerClick(Marker marker) {

        /*Toast.makeText(getActivity(),
                  "" + marker.getTitle(), Toast.LENGTH_LONG)
                  .show();*/

        marker.showInfoWindow();

        return false;
    }

    @Override
    public void onMapClick(LatLng arg0) {
        // TODO Auto-generated method stub

    }

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

}
XML:


我建议您使用MapView而不是SupportFragment来避免嵌套片段,了解详细信息,请参阅以下帖子

现在你的停车场看起来像

MapFragment.java

public class MapFragment extends Fragment implements OnMapReadyCallback {

    private MapView mMapView;
    private GoogleMap mGoogleMap;

    public MapFragment() {
        // Required empty public constructor
    }

    public static MapFragment newInstance() {
        MapFragment fragment = new MapFragment();
        return fragment;
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_map, container, false);
        mMapView = (MapView) rootView.findViewById(R.id.map);
        mMapView.onCreate(savedInstanceState);
        mMapView.getMapAsync(this);

        return rootView;
    }

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


    @Override
    public void onPause() {
        mMapView.onPause();
        super.onPause();
    }

    @Override
    public void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        googleMap.getUiSettings().setZoomControlsEnabled(true);

    }
}
片段映射.xml

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

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

</FrameLayout>

问题可能是因为它正在重新创建导致黑屏的
片段。如果您使用的是
ViewPager
,则可以使用

// Note that you must set adapter before this line otherwise it can cause NullPointerException
// Or add null check on getAdapter if required
mViewPager.setOffscreenPageLimit(mViewPager.getAdapter().getCount());
它将强制
ViewPager
第二次不创建片段。当然,它需要更多的内存,但我相信当使用更少的选项卡时效率更高,所以我通常这样做是为了避免重新创建片段

其次,我建议将这些行从
onDestroy
中删除:

SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
    getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
并通过将
onCreateView
更新为以下内容来解决此问题:

private View mView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (mView == null) {
        mView = inflater.inflate(R.layout.fragment_map, container, false);
    }
    return mView;
}
它不会每次都膨胀布局,所以您不会面临com.google.android.gms.maps.MapFragment的重复ID、标记null或父ID的问题。
但请确保在attachToRoot(充气机.inflate的最后一个参数)中通过false,否则可能会出现异常,如指定的子级已经有父级

最后,当在片段中使用MapFragment时,或者换句话说,当使用嵌套片段时,我建议使用getChildFragmentManager()而不是getFragmentManager(),以避免意外问题。
因为正如《圣经》所说:
:返回FragmentManager,以便与与此片段的活动关联的片段进行交互。请注意,从片段放入FragmentTransaction到提交并附加到其活动,在getActivity()之前的一段时间内,该值将不为null。如果此片段是另一个片段的子片段,则此处返回的FragmentManager将是父片段的getChildFragmentManager()。

:返回专用FragmentManager,用于在此片段中放置和管理片段。

是否尝试隐藏和显示片段(而不是删除/添加它)

在您的情况下,您可以将其更改为ParkMapFragment等

protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}

来源:

在createView中尝试以下操作:

if (v != null) {
    ViewGroup parent = (ViewGroup) v.getParent();
    if (parent != null)
        parent.removeView(v);
}

您应该通过以下方式进行片段转换:

Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit(); 
使用TRANSIT_FRAGMENT_FADE FRAGMENT时,应简单地淡入或淡出;也就是说,除了由于某种原因出现或消失之外,没有与之相关的强大导航

当您用另一个片段替换带有map的片段时使用它,在其他情况下,我建议使用公共用法,而不使用(.setTransition…):


该代码是为了避免。不幸的是,这对我遇到的问题没有影响。你正在使用的代码在哪里。添加以替换片段?我对Android还是相当陌生,但我猜
onCreateView
正在替换整个片段(其中包含地图片段)?每次我返回片段时,地图肯定都在重新加载,所以我想这一定是发生的事情。@user3746428我想这应该可以解决它。您根本不应该覆盖onDestroyView。当您希望片段不在视图中时,只需替换片段(使用上面的代码)。剩下的问题已经解决了。问题不在于地图的出现,而在于我切换片段的时候(它会变黑几毫秒)。只是尝试一下,不幸的是它也有同样的问题。你找到解决方案了吗?谢谢,你救了我一天!
protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}
if (v != null) {
    ViewGroup parent = (ViewGroup) v.getParent();
    if (parent != null)
        parent.removeView(v);
}
Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit(); 
Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).commit();