Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 谷歌地图Lite模式在RecyclerView中引起jank_Android_Google Maps_Android Recyclerview_Google Play Services_Google Maps Lite - Fatal编程技术网

Android 谷歌地图Lite模式在RecyclerView中引起jank

Android 谷歌地图Lite模式在RecyclerView中引起jank,android,google-maps,android-recyclerview,google-play-services,google-maps-lite,Android,Google Maps,Android Recyclerview,Google Play Services,Google Maps Lite,我有一个RecyclerView,它是一个项目的垂直滚动列表。每个列表项中都包含一个Google Maps V2地图视图。我正在利用这个新功能,它返回位图而不是完整的位图,以替代谷歌静态地图API 需要从父活动/片段的相应方法调用onCreate()、onResume()、onPause()、onDestroy()等。从RecyclerView.Adapter和/或RecyclerView.ViewHolder调用这些的正确位置在哪里 如何清理回收的地图视图,使内存不会泄漏,同时保持列表的自由

我有一个
RecyclerView
,它是一个项目的垂直滚动列表。每个列表项中都包含一个Google Maps V2地图视图。我正在利用这个新功能,它返回位图而不是完整的位图,以替代
谷歌静态地图API

需要从父活动/片段的相应方法调用
onCreate()
onResume()
onPause()
onDestroy()
等。从
RecyclerView.Adapter
和/或
RecyclerView.ViewHolder
调用这些的正确位置在哪里

如何清理回收的地图视图,使内存不会泄漏,同时保持列表的自由

…'lite mode“映射选项,非常适合您需要 提供一些较小的地图,或一个小到 有意义的交互是不切实际的,例如列表中的缩略图

ListItem.xml

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

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapImageView"
        xmlns:map="http://schemas.android.com/apk/res-auto"
        android:layout_width="80dp"
        android:layout_height="100dp"
        map:liteMode="true"
        map:mapType="normal"
        map:cameraZoom="15"/>

<!-- ... -->

</RelativeLayout>

更新:(2018年6月8日)谷歌发布了一个在列表视图中使用Lite地图的代码示例

您需要有一个单独的视图持有者类。RecyclerView适配器类只有onCreateViewHolder()和onBindViewHolder()

布局文件的外观应类似于以下内容:

<RelativeLayout 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"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MyActivity">

    <view
    <com.google.android.gms.maps.MapView
    android:id="@+id/mapImageView"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:layout_width="80dp"
    android:layout_height="100dp"
    map:liteMode="true"
    map:mapType="normal"
    map:cameraZoom="15" />

</RelativeLayout>

解决方案如下:

  • ViewHolder
    类中执行
    OnMapReadyCallback

  • onMapReady
    中,调用
    mapsitializer.initialize
    ,以确保在获取地图之前可以使用这些功能
  • 如果在获取地图之前需要使用功能,请使用此类初始化Google Maps Android API。必须调用它,因为某些类(如BitmapDescriptorFactory和CameraUpdateFactory)需要初始化

  • onViewRecycled
    中回收地图

  •     public class NearbyStopsAdapter extends RecyclerView.Adapter<NearbyStopsAdapter.ViewHolder> {
    
    
           @Override 
           public void onBindViewHolder(ViewHolder holder, int position)  
           {
              //get 'location' by 'position' from data list
              //get GoogleMap
              GoogleMap thisMap = holder.gMap;
              //then move map to 'location'
              if(thisMap != null) 
                 //move map to the 'location' 
                 thisMap.moveCamera(...);          
           }
    
    
           //Recycling GoogleMap for list item
           @Override 
           public void onViewRecycled(ViewHolder holder) 
           {
              // Cleanup MapView here?
              if (holder.gMap != null) 
              {
                  holder.gMap.clear();
                  holder.gMap.setMapType(GoogleMap.MAP_TYPE_NONE);
              }
           }
    
    
    
           public class ViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback { 
    
               GoogleMap gMap; 
               MapView map;
                ... ... 
    
               public ViewHolder(View view) {
                  super(view);
                  map = (MapView) view.findViewById(R.id.mapImageView);
    
                  if (map != null) 
                  {
                     map.onCreate(null);
                     map.onResume();
                     map.getMapAsync(this);
                  }
    
              }
    
    
              @Override
              public void onMapReady(GoogleMap googleMap) {
                  //initialize the Google Maps Android API if features need to be used before obtaining a map 
                  MapsInitializer.initialize(getApplicationContext());
                  gMap = googleMap;
    
                  //you can move map here to item specific 'location'
                  int pos = getPosition();
                  //get 'location' by 'pos' from data list  
                  //then move to 'location'
                  gMap.moveCamera(...);
    
                      ... ...
             }
    
           }
        } 
    
    公共类NearbyStopsAdapter扩展了RecyclerView.Adapter{
    @凌驾
    公共无效onBindViewHolder(ViewHolder,int位置)
    {
    //通过数据列表中的“位置”获取“位置”
    //获取谷歌地图
    谷歌地图thisMap=holder.gMap;
    //然后将地图移动到“位置”
    if(thisMap!=null)
    //将地图移动到“位置”
    这张地图。移动相机(…);
    }
    //为列表项回收GoogleMap
    @凌驾
    视图上的公共无效已回收(视图持有人)
    {
    //这里是地图视图吗?
    如果(holder.gMap!=null)
    {
    holder.gMap.clear();
    holder.gMap.setMapType(GoogleMap.MAP\u TYPE\u无);
    }
    }
    公共类ViewHolder扩展了RecyclerView.ViewHolder在MapReadyCallback上实现{
    谷歌地图;
    地图视图;
    ... ... 
    公共视图持有者(视图){
    超级(视图);
    map=(MapView)view.findViewById(R.id.mapImageView);
    if(map!=null)
    {
    map.onCreate(null);
    onResume();
    getMapAsync(this);
    }
    }
    @凌驾
    4月1日公开作废(谷歌地图谷歌地图){
    //如果在获取地图之前需要使用功能,请初始化Google Maps Android API
    初始化(getApplicationContext());
    gMap=谷歌地图;
    //您可以将此地图移动到特定于项目的“位置”
    int pos=getPosition();
    //通过数据列表中的“pos”获取“位置”
    //然后移动到“位置”
    移动摄影机(…);
    ... ...
    }
    }
    } 
    
    谷歌说:

    在完全交互模式下使用API时,MapView类的用户必须将所有活动生命周期方法转发给MapView类中的相应方法。生命周期方法的示例包括onCreate()、onDestroy()、onResume()和onPause()

    在lite模式下使用MapView类时,转发生命周期事件是可选的,但以下情况除外:

    必须调用onCreate(),否则将不显示映射。 如果希望在lite模式映射上显示“我的位置”点并使用默认位置源,则需要调用onResume()和onPause(),因为位置源只会在这些调用之间更新。如果使用自己的位置源,则无需调用这两个方法

    因此,在lite模式下,您不必担心onDestroy()、onResume()和onPause()

    查找()


    我已经删除了这个覆盖方法,因为每次测试时它都会给出空映射,并且它在我的recyclerView中工作得非常好

    @Override 
    public void onViewRecycled(ViewHolder holder) 
    {
      // Cleanup MapView here?
      if (holder.gMap != null) 
      {
          holder.gMap.clear();
          holder.gMap.setMapType(GoogleMap.MAP_TYPE_NONE);
      }
    }
    

    如果上述代码在您的情况下不起作用,您可以尝试使用它。

    谷歌地图提供
    Lite模式

    Android版地图SDK可以提供地图的位图图像,为用户提供有限的交互性。这称为精简模式映射


    遵循
    :使用lite模式在ListView中高效显示地图的示例。

    我想您可能没有回答这个问题。
    RecyclerView.Adapter
    中已经定义了一个ViewHolder。问题是应该在何处调用
    MapView.onCreate()
    MapView.onDestroy()
    等?请查看布局文件“代码”下方的行,活动类中将一如既往地调用onCreate(),onDestroy()。“您的链接不包括
    MapView
    。”。它有什么关系?这是通常的活动课。。。使用onCreate()和描述的其他Android生命周期方法。有关更多详细信息,请参阅这段代码,其中包含mapView和从布局充气器中提取的数据,
    RecyclerView
    没有
    onCreate()
    和其他Android生命周期方法。以及
    RecyclerView    public class NearbyStopsAdapter extends RecyclerView.Adapter<NearbyStopsAdapter.ViewHolder> {
    
    
           @Override 
           public void onBindViewHolder(ViewHolder holder, int position)  
           {
              //get 'location' by 'position' from data list
              //get GoogleMap
              GoogleMap thisMap = holder.gMap;
              //then move map to 'location'
              if(thisMap != null) 
                 //move map to the 'location' 
                 thisMap.moveCamera(...);          
           }
    
    
           //Recycling GoogleMap for list item
           @Override 
           public void onViewRecycled(ViewHolder holder) 
           {
              // Cleanup MapView here?
              if (holder.gMap != null) 
              {
                  holder.gMap.clear();
                  holder.gMap.setMapType(GoogleMap.MAP_TYPE_NONE);
              }
           }
    
    
    
           public class ViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback { 
    
               GoogleMap gMap; 
               MapView map;
                ... ... 
    
               public ViewHolder(View view) {
                  super(view);
                  map = (MapView) view.findViewById(R.id.mapImageView);
    
                  if (map != null) 
                  {
                     map.onCreate(null);
                     map.onResume();
                     map.getMapAsync(this);
                  }
    
              }
    
    
              @Override
              public void onMapReady(GoogleMap googleMap) {
                  //initialize the Google Maps Android API if features need to be used before obtaining a map 
                  MapsInitializer.initialize(getApplicationContext());
                  gMap = googleMap;
    
                  //you can move map here to item specific 'location'
                  int pos = getPosition();
                  //get 'location' by 'pos' from data list  
                  //then move to 'location'
                  gMap.moveCamera(...);
    
                      ... ...
             }
    
           }
        } 
    
    @Override 
    public void onViewRecycled(ViewHolder holder) 
    {
      // Cleanup MapView here?
      if (holder.gMap != null) 
      {
          holder.gMap.clear();
          holder.gMap.setMapType(GoogleMap.MAP_TYPE_NONE);
      }
    }