问题
I have used map view inside recyclerview row. I have attached screenshot. While scrolling maps display black flickering background.
Adapter code:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TASK_VIEW) {
return new TasksViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_task_row, parent, false));
} else if (viewType == CHECKIN_VIEW) {
return new CheckInViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_checkin_row, parent, false));
} else {
return null;
}
}
@Override
private void onBindCheckInViewHolder(CheckInViewHolder holder, int position) {
final JobCheckIn singleCheckIn = (JobCheckIn) items.get(position);
holder.location.setText(singleCheckIn.getAddress());
holder.lastUpdated.setText(String.valueOf("Created " +
activity.getDateTime(singleCheckIn.getCreatedDateTime())));
holder.deleteTask.setOnClickListener(view -> jobInterface.deleteCheckIn(singleCheckIn.getId()));
float f = 0.0f;
if (holder.mapView != null && Float.compare(singleCheckIn.getLatitude(), f) != 0 &&
Float.compare(singleCheckIn.getLongitude(), f) != 0) {
holder.mapView.setVisibility(View.VISIBLE);
holder.initializeMapView();
if (holder.gMap != null) {
// The map is already ready to be used
moveMap(holder.gMap, singleCheckIn.getLatitude(), singleCheckIn.getLongitude());
}
}
}
public class CheckInViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback {
MapView mapView;
GoogleMap gMap;
public CheckInViewHolder(View view) {
super(view);
mapView = view.findViewById(R.id.checkInMapView);
}
@Override
public void onMapReady(GoogleMap googleMap) {
MapsInitializer.initialize(context);
gMap = googleMap;
googleMap.getUiSettings().setMapToolbarEnabled(false);
if(items.get(getLayoutPosition())!=null )
moveMap(gMap,((JobCheckIn) items.get(getLayoutPosition())).getLatitude(), ((JobCheckIn) items.get(getLayoutPosition())).getLongitude());
}
public void initializeMapView() {
if (mapView != null) {
// Initialise the MapView
mapView.onCreate(null);
// Set the map ready callback to receive the GoogleMap object
mapView.getMapAsync(this);
}
}
}
public void moveMap(GoogleMap gMap, double latitude, double longitude) {
Log.v(TAG, "mapMoved: " + gMap);
LatLng latlng = new LatLng(latitude, longitude);
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(latlng, 6);
gMap.addMarker(new MarkerOptions().position(latlng));
gMap.moveCamera(cu);
}
I refer this link: Link but in this demo they used array adapter in my code we have used recyclerview adapter.
xml code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="150dp">
<com.google.android.gms.maps.MapView
android:id="@+id/checkInMapView"
android:layout_width="0dp"
android:layout_height="150dp"
android:layout_weight="1"
android:enabled="true"
android:visibility="gone"
map:cameraZoom="15"
map:liteMode="true"
map:mapType="normal" />
<!-- I have also tried adding transparent view as below but still no solution.
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"/>-->
</LinearLayout>
I am not performing any zoom-In, Zoom-out or drag. Thanks in advance.
Google Issue Track
Update
Previously i was initializing map in viewHolder instead of mentioned as above scenario.
onBindCheckInViewHolder(...){
holder.mapView.onCreate(null);
holder.mapView.getMapAsync(googleMap -> {
MapsInitializer.initialize(context);
gMap = googleMap;
googleMap.getUiSettings().setMapToolbarEnabled(false);
moveMap(gMap, singleCheckIn.getLatitude(), singleCheckIn.getLongitude());
});
}
回答1:
Write this line in AndroidManifest.xml:
android:hardwareAccelerated="true"
<application
android:name="com.xyz"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
</application>
It works.
回答2:
So I dug around a bit, and here are some suggestions to make the performance a little better, it's not perfect, but it is a lot faster.
Map type
This basically determines how the map looks like (normal/hybrid... etc), you need to set the map type to GoogleMap.MAP_TYPE_NONE in these cases.
XMLwhere you define the view, so this is the default type- Override
onViewRecycledin your adapter and if yourholderhas aGoogleMapset its type to none
Only set your type back to GoogleMap.MAP_TYPE_NORMAL or whatever type you want, when your onBindViewHolder is called.
Pre-initialization
Call MapsInitializer.initialize(context) from your onMapReady callback.
Initialization
Call GoogleMap.onCreate() and GoogleMap.getMapAsync() from your onCreateViewHolder, maybe in your ViewHolder constructor.
RecyclerView Prefetch
You can also use a neat new feature of LinearLayoutManager, you can call LinearLayoutManager.setInitialPrefetchItemCount, to start preparing off screen items.
Not that this can cause other performance issues, tweak it till you get a nice balance.
Optimize layout
- Try to have the layout where your
RecyclerViewto be flat as possible, don't nest too much layouts - Make sure you set
setHasFixedSize(true)for yourRecyclerView - Make sure to avoid weights or
RelativeLayouts as parents of yourRecyclerViewor your children list items.
回答3:
<application
android:name="com.yourpackagename"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
Just add hardwareAccelerated as True in your Project Manifest file
回答4:
MapView is a pretty heavy view and when you try to get a bunch of them on the screen then app will become sluggish while scrolling. you can pass data such as the latitude and longitude as a string with some static variables taken from the link mentioned below. you can get co-ordinates from the Facebook API. This is the api link https://developers.google.com/maps/documentation/staticmaps/.
String getMapURL = "http://maps.googleapis.com/maps/api/staticmap?zoom=
18&size=560x240&markers=size:mid|color:red|"
+ JOLocation.getString("latitude") + "," + JOLocation.getString("longitude")
+ "&sensor=false";
The above constructed URL, when you used in a browser, returns a .PNG file. Similar type of issue was discussed here in this link MapView in Listview check it. Hope it helps
来源:https://stackoverflow.com/questions/47646974/map-recyclerview-inside-scrollview-display-black-flickering-background-while-scr