Google Maps Lite Mode causes jank in RecyclerView

前端 未结 6 1813
囚心锁ツ
囚心锁ツ 2020-12-07 11:31

I have a RecyclerView which is a vertical scrolling list of items. Each list item contains a Google Maps V2 MapView in Lite Mode. I\'m taking advantage of this

相关标签:
6条回答
  • 2020-12-07 12:05

    Google says:

    When using the API in fully interactive mode, users of the MapView class must forward all the activity life cycle methods to the corresponding methods in the MapView class. Examples of the life cycle methods include onCreate(), onDestroy(), onResume(), and onPause().

    When using the MapView class in lite mode, forwarding lifecycle events is optional, except for the following situations:

    It is mandatory to call onCreate(), otherwise no map will appear. If you wish to show the My Location dot on your lite mode map and use the default location source, you will need to call onResume() and onPause(), because the location source will only update between these calls. If you use your own location source, it's not necessary to call these two methods.

    So on lite mode you don't have to worry about onDestroy(), onResume() and onPause()

    0 讨论(0)
  • 2020-12-07 12:11

    Google map provides Lite Mode

    The Maps SDK for Android can serve a bitmap image of a map, offering limited interactivity to the user. This is called a lite mode map.

    Lite Mode

    Follow the LiteListDemoActivity: Displaying maps efficiently in ListViews using lite mode example.

    0 讨论(0)
  • 2020-12-07 12:23

    You need to have a separate View Holder class. The RecyclerView Adapter class will just have onCreateViewHolder() and onBindViewHolder().

    Your Layout file should look something similar to this:

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

    And the onCreate(), onDestroy() will be called in the Activity class as usual.

    Please follow this tutorial to get a complete overview.

    0 讨论(0)
  • 2020-12-07 12:27

    Find Google Maps Android API Lite Mode Example (source code)

    0 讨论(0)
  • 2020-12-07 12:27

    I have removed this Override method because every time this gives empty map when testing and it works perfectly in my recyclerView.

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

    You can try it if above code does not work in your case as well.

    0 讨论(0)
  • 2020-12-07 12:28

    Solution as following:

    1. Implement OnMapReadyCallback in ViewHolder class.
    2. In onMapReady, call MapsInitializer.initialize, to gaurantee features can to be used before obtaining a map.

    Use this class to initialize the Google Maps Android API if features need to be used before obtaining a map. It must be called because some classes such as BitmapDescriptorFactory and CameraUpdateFactory need to be initialized.

    1. Recycle map from 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(...);
    
                      ... ...
             }
    
           }
        } 
    
    0 讨论(0)
提交回复
热议问题