谷歌地图精简版模式导致JANK在RecyclerView [英] Google Maps Lite Mode causes jank in RecyclerView
问题描述
我有一个 RecyclerView
这是一个项目一个垂直滚动列表。每个列表项包含了谷歌地图V2图形页面中 精简版模式 。我利用这一新功能,返回的位图,而不是一个完全成熟的地图作为替代来利用谷歌静态地图API
。
图形页面要求调用的onCreate()
, onResume()
,的onPause()
,的onDestroy()
等从父活动/片段的相应方法。哪里是合适的地方调用这些从 RecyclerView.Adapter
和/或 RecyclerView.ViewHolder
?
我如何清理回收MapViews使记忆力不漏,同时保持列表JANK免费的吗?
......精简版模式地图选项,非常适合情况下,要 提供多个较小的地图,或者在地图是如此小,以致 有意义的互动是不切实际的,如在一个列表中的缩略图。
ListItem.xml
< RelativeLayout的的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT>
< com.google.android.gms.maps.MapView
机器人:ID =@ + ID / mapImageView
的xmlns:地图=http://schemas.android.com/apk/res-auto
机器人:layout_width =80dp
机器人:layout_height =100dp
图:liteMode =真
图:地图类型=正常
图:cameraZoom =15/>
< - !... - >
< / RelativeLayout的>
RecyclerView.Adapter和ViewHolder
公共类NearbyStopsAdapter扩展RecyclerView.Adapter< NearbyStopsAdapter.ViewHolder> {
私人最终语境mContext;
公共类ViewHolder扩展RecyclerView.ViewHolder实现View.OnClickListener {
MapView的地图;
公共ViewHolder(查看视图){
超(视图);
地图=(图形页面)view.findViewById(R.id.mapImageView);
//如果这在此处产生的?
map.onCreate(空);
map.onResume();
}
}
公共NearbyStopsAdapter(上下文C){
this.mContext = C;
}
@覆盖公共ViewHolder onCreateViewHolder(ViewGroup中的ViewGroup,INT位置){
查看ItemView控件= LayoutInflater.from(viewGroup.getContext())膨胀(R.layout.list_item_nearby_stop,ViewGroup中,假的)。
返回新ViewHolder(ItemView控件);
}
@覆盖公共无效onBindViewHolder(ViewHolder持有人,INT位置){
//调用异步地图吗?
holder.map.getMapAsync(本);
}
@覆盖公共无效onViewRecycled(ViewHolder持有者){
//在这里清理的MapView?
//如果(holder.map!= NULL){
// holder.map.onPause();
// holder.map.onDestroy();
//}
}
@覆盖公共无效onViewAttachedToWindow(ViewHolder持有者){
//这里设置的MapView?
// holder.map.onCreate(空);
// holder.map.onResume();
}
@覆盖公共无效onViewDetachedFromWindow(ViewHolder持有者){
//在这里清理的MapView?
//如果(holder.map!= NULL){
// holder.map.onPause();
// holder.map.onDestroy();
//}
}
// ...
}
logcat的:
I /谷歌地图Android的API:谷歌播放服务包的版本:659943
W /谷歌地图Android的API:地图加载回调不支持精简版模式
W /谷歌地图Android的API:建筑物中不支持精简版模式
W /谷歌地图Android的API:室内不支持精简版模式
W /谷歌地图Android的API:切换姿态不支持精简版模式
W /谷歌地图Android的API:切换姿态不支持精简版模式
W /谷歌地图Android的API:切换姿态不支持精简版模式
W /谷歌地图Android的API:切换姿态不支持精简版模式
解决方法如下:
- 实施
OnMa preadyCallback
在ViewHolder
类。 - 在
onMa pready
,呼叫MapsInitializer.initialize
,以garante特征可以得到之前被使用地图。
<醇开始=3>使用这个类来初始化谷歌地图Android的API,如果功能需要得到一张地图前使用。它必须调用因为一些类如BitmapDescriptorFactory和CameraUpdateFactory需要初始化。
onViewRecycled
。
公共类NearbyStopsAdapter扩展RecyclerView.Adapter&LT; NearbyStopsAdapter.ViewHolder&GT; {
@覆盖
公共无效onBindViewHolder(ViewHolder持有人,INT位置)
{
//获取位置从数据清单位置
//获取的GoogleMap
GoogleMap的thisMap = holder.gMap;
//然后将地图移动到位置
如果(thisMap!= NULL)
//将地图移动到位置
thisMap.moveCamera(...);
}
//回收的GoogleMap的列表项
@覆盖
公共无效onViewRecycled(ViewHolder持有人)
{
//在这里清理的MapView?
如果(holder.gMap!= NULL)
{
holder.gMap.clear();
holder.gMap.setMapType(GoogleMap.MAP_TYPE_NONE);
}
}
公共类ViewHolder扩展RecyclerView.ViewHolder实现OnMa preadyCallback {
GoogleMap的GMAP;
MapView的地图;
......
公共ViewHolder(查看视图){
超(视图);
地图=(图形页面)view.findViewById(R.id.mapImageView);
如果(图!= NULL)
{
map.onCreate(空);
map.onResume();
map.getMapAsync(本);
}
}
@覆盖
公共无效onMa pready(GoogleMap的GoogleMap的){
//初始化谷歌地图Android的API,如果功能需要得到一张地图前,要使用
MapsInitializer.initialize(getApplicationContext());
GMAP = GoogleMap的;
//你可以在这里将地图移动到项目特定的位置
INT POS =为getPosition();
//获取位置从数据列表POS
//然后移动到位置
gMap.moveCamera(...);
......
}
}
}
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 new feature which returns bitmaps instead of a full-blown map as a replacement to the Google Static Maps API
.
MapView requires that you call onCreate()
, onResume()
, onPause()
, onDestroy()
etc. from the parent Activity/Fragment's corresponding method. Where is the proper place to call these from the RecyclerView.Adapter
and/or RecyclerView.ViewHolder
?
How can I clean up recycled MapViews so that memory doesn't leak, while keeping the list jank free?
Google says Lite Mode can be used in lists:
... ‘lite mode’ map option, ideal for situations where you want to provide a number of smaller maps, or a map that is so small that meaningful interaction is impractical, such as a thumbnail in a list.
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>
RecyclerView.Adapter and ViewHolder
public class NearbyStopsAdapter extends RecyclerView.Adapter<NearbyStopsAdapter.ViewHolder> {
private final Context mContext;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
MapView map;
public ViewHolder(View view) {
super(view);
map = (MapView) view.findViewById(R.id.mapImageView);
// Should this be created here?
map.onCreate(null);
map.onResume();
}
}
public NearbyStopsAdapter(Context c) {
this.mContext = c;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item_nearby_stop, viewGroup, false);
return new ViewHolder(itemView);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
//Call Async Map here?
holder.map.getMapAsync(this);
}
@Override public void onViewRecycled(ViewHolder holder) {
// Cleanup MapView here?
// if (holder.map != null) {
// holder.map.onPause();
// holder.map.onDestroy();
// }
}
@Override public void onViewAttachedToWindow(ViewHolder holder) {
// Setup MapView here?
// holder.map.onCreate(null);
// holder.map.onResume();
}
@Override public void onViewDetachedFromWindow(ViewHolder holder) {
// Cleanup MapView here?
// if (holder.map != null) {
// holder.map.onPause();
// holder.map.onDestroy();
// }
}
// ...
}
Logcat:
I/Google Maps Android API﹕ Google Play services package version: 659943
W/Google Maps Android API﹕ Map Loaded callback is not supported in Lite Mode
W/Google Maps Android API﹕ Buildings are not supported in Lite Mode
W/Google Maps Android API﹕ Indoor is not supported in Lite Mode
W/Google Maps Android API﹕ Toggling gestures is not supported in Lite Mode
W/Google Maps Android API﹕ Toggling gestures is not supported in Lite Mode
W/Google Maps Android API﹕ Toggling gestures is not supported in Lite Mode
W/Google Maps Android API﹕ Toggling gestures is not supported in Lite Mode
Solution as following:
- Implement
OnMapReadyCallback
inViewHolder
class. - In
onMapReady
, callMapsInitializer.initialize
, to garante 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.
- 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(...);
... ...
}
}
}
这篇关于谷歌地图精简版模式导致JANK在RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!