我想在listview上显示mapview。地图无法在listview中加载。如果我触摸地图视图,则会加载地图。如果我滚动列表视图mapview进入卸载初始阶段。我的listview适配器和屏幕截图已经给出,
公共类OfferListAdapter扩展了BaseAdapter {
String lat="",lon="";
String adId;
Context context;
MapView mapView;
GoogleMap map;
Util g;
ArrayList<HashMap<String, String>> adList;
Bundle savedInstanceState;
public OfferListAdapter(final Context context, final ArrayList<HashMap<String, String>> addlist, final String type, final Bundle b) {
// TODO Auto-generated constructor stub
this.context=context;
this.adList=addlist;
this.listType=type;
this.savedInstanceState=b;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return adList.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
private class ViewHolder
{
ImageView adImg;
TextView txt;
}
@SuppressLint("InflateParams")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
adId=null;
g=Util.getInstance(context);
final LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View view=mInflater.inflate(R.layout.offer_list_row, null);
final ViewHolder holder;
holder=new ViewHolder();
mapView = (MapView) view.findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
// Gets to GoogleMap from the MapView and does initialization stuff
map = mapView.getMap();
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Showing / hiding your current location
map.setMyLocationEnabled(false);
// Enable / Disable zooming controls
map.getUiSettings().setZoomControlsEnabled(false);
// Enable / Disable my location button
map.getUiSettings().setMyLocationButtonEnabled(false);
// Enable / Disable Compass icon
map.getUiSettings().setCompassEnabled(false);
// Enable / Disable Rotate gesture
map.getUiSettings().setRotateGesturesEnabled(false);
// Enable / Disable zooming functionality
map.getUiSettings().setZoomGesturesEnabled(false);
MapsInitializer.initialize(context);
// Updates the location and zoom of the MapView
double latitude = 12.965119900000000000;
double longitude = 80.243980900000000000;
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude))
.title("Hello Maps");
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED));
map.addMarker(marker);
//Zoom Particular position
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(latitude,
longitude)).zoom(12).build();
map.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
return view;
}
public void updateData(final ArrayList<HashMap<String, String>> addlist, final String type) {
// TODO Auto-generated method stub
this.adList=addlist;
this.listType=type;
}
}
截图列表。 1)此屏幕将在第一次加载时出现,
2)点击mapview后会出现此界面,
3)点击mapview后会出现此界面,
4)在mapview上点击10到15次后会出现此界面,
答案 0 :(得分:5)
在listView中直接使用mapView是一项繁重的操作。这将导致延迟并导致您的应用程序的用户体验缓慢。要避免此行为,您可以使用Static maps。这将在列表视图中启用延迟加载地图,而且用户不必立即点击地图。
我在下面提供一个使用此方法的小例子。首先从数据(API或DB)创建列表视图。然后将纬度和经度等数据传递给一个字符串,其中一些静态变量定义如下。
String getMapURL = "http://maps.googleapis.com/maps/api/staticmap?zoom=12&size=360x180&markers=size:mid|color:green|"
+ JOLocation.getString("latitude")
+ ","
+ JOLocation.getString("longitude")
+ "&sensor=false";
上述构造的URL在浏览器中使用时会返回.PNG文件。然后,在我的活动适配器中,此方法导致在应用程序中延迟加载地图,其中显示坐标的标记在运行时被提取,从而避免在代码中繁重工作。
希望这会有所帮助!!!
答案 1 :(得分:3)
我遇到了同样的问题,使用你的代码和其他堆栈主题,我想出了这样做的方式
mapView.onCreate(savedInstanceState);
mapView.onResume();
mapView.getMapAsync(
new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googlemap) {
final GoogleMap map = googlemap;
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
MapsInitializer.initialize(context);
map.setMyLocationEnabled(true);
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
LatLng sydney = new LatLng(-33.873, 151.206);
String markerTitle = "Sydney";
String snippetTitle = "Lovely city";
if (markerTitle != null && snippetTitle != null) {
map.addMarker(new MarkerOptions()
.title(markerTitle)
.snippet(snippetTitle)
.position(sydney));
}
map.setMyLocationEnabled(true);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney2, 13));
}
}
);
1)你需要调用onResume();在mapView上,所以它正确加载 2)使用.getMapAsync,不推荐使用getMap
您可以通过双击放大:)
答案 2 :(得分:0)
google有一个很棒的工作示例 googlemaps sample
它在列表中加载轻量级地图(参见示例中的LiteListDemoActivity.java)
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.mapdemo;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.HashSet;
/**
* This shows to include a map in lite mode in a ListView.
* Note the use of the view holder pattern with the
* {@link com.google.android.gms.maps.OnMapReadyCallback}.
*/
public class LiteListDemoActivity extends AppCompatActivity {
private ListFragment mList;
private MapAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lite_list_demo);
// Set a custom list adapter for a list of locations
mAdapter = new MapAdapter(this, LIST_LOCATIONS);
mList = (ListFragment) getSupportFragmentManager().findFragmentById(R.id.list);
mList.setListAdapter(mAdapter);
// Set a RecyclerListener to clean up MapView from ListView
AbsListView lv = mList.getListView();
lv.setRecyclerListener(mRecycleListener);
}
/**
* Adapter that displays a title and {@link com.google.android.gms.maps.MapView} for each item.
* The layout is defined in <code>lite_list_demo_row.xml</code>. It contains a MapView
* that is programatically initialised in
* {@link #getView(int, android.view.View, android.view.ViewGroup)}
*/
private class MapAdapter extends ArrayAdapter<NamedLocation> {
private final HashSet<MapView> mMaps = new HashSet<MapView>();
public MapAdapter(Context context, NamedLocation[] locations) {
super(context, R.layout.lite_list_demo_row, R.id.lite_listrow_text, locations);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
// Check if a view can be reused, otherwise inflate a layout and set up the view holder
if (row == null) {
// Inflate view from layout file
row = getLayoutInflater().inflate(R.layout.lite_list_demo_row, null);
// Set up holder and assign it to the View
holder = new ViewHolder();
holder.mapView = (MapView) row.findViewById(R.id.lite_listrow_map);
holder.title = (TextView) row.findViewById(R.id.lite_listrow_text);
// Set holder as tag for row for more efficient access.
row.setTag(holder);
// Initialise the MapView
holder.initializeMapView();
// Keep track of MapView
mMaps.add(holder.mapView);
} else {
// View has already been initialised, get its holder
holder = (ViewHolder) row.getTag();
}
// Get the NamedLocation for this item and attach it to the MapView
NamedLocation item = getItem(position);
holder.mapView.setTag(item);
// Ensure the map has been initialised by the on map ready callback in ViewHolder.
// If it is not ready yet, it will be initialised with the NamedLocation set as its tag
// when the callback is received.
if (holder.map != null) {
// The map is already ready to be used
setMapLocation(holder.map, item);
}
// Set the text label for this item
holder.title.setText(item.name);
return row;
}
/**
* Retuns the set of all initialised {@link MapView} objects.
*
* @return All MapViews that have been initialised programmatically by this adapter
*/
public HashSet<MapView> getMaps() {
return mMaps;
}
}
/**
* Displays a {@link LiteListDemoActivity.NamedLocation} on a
* {@link com.google.android.gms.maps.GoogleMap}.
* Adds a marker and centers the camera on the NamedLocation with the normal map type.
*/
private static void setMapLocation(GoogleMap map, NamedLocation data) {
// Add a marker for this item and set the camera
map.moveCamera(CameraUpdateFactory.newLatLngZoom(data.location, 13f));
map.addMarker(new MarkerOptions().position(data.location));
// Set the map type back to normal.
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
/**
* Holder for Views used in the {@link LiteListDemoActivity.MapAdapter}.
* Once the the <code>map</code> field is set, otherwise it is null.
* When the {@link #onMapReady(com.google.android.gms.maps.GoogleMap)} callback is received and
* the {@link com.google.android.gms.maps.GoogleMap} is ready, it stored in the {@link #map}
* field. The map is then initialised with the NamedLocation that is stored as the tag of the
* MapView. This ensures that the map is initialised with the latest data that it should
* display.
*/
class ViewHolder implements OnMapReadyCallback {
MapView mapView;
TextView title;
GoogleMap map;
@Override
public void onMapReady(GoogleMap googleMap) {
MapsInitializer.initialize(getApplicationContext());
map = googleMap;
NamedLocation data = (NamedLocation) mapView.getTag();
if (data != null) {
setMapLocation(map, data);
}
}
/**
* Initialises the MapView by calling its lifecycle methods.
*/
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);
}
}
}
/**
* RecycleListener that completely clears the {@link com.google.android.gms.maps.GoogleMap}
* attached to a row in the ListView.
* Sets the map type to {@link com.google.android.gms.maps.GoogleMap#MAP_TYPE_NONE} and clears
* the map.
*/
private AbsListView.RecyclerListener mRecycleListener = new AbsListView.RecyclerListener() {
@Override
public void onMovedToScrapHeap(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
if (holder != null && holder.map != null) {
// Clear the map and free up resources by changing the map type to none
holder.map.clear();
holder.map.setMapType(GoogleMap.MAP_TYPE_NONE);
}
}
};
/**
* Location represented by a position ({@link com.google.android.gms.maps.model.LatLng} and a
* name ({@link java.lang.String}).
*/
private static class NamedLocation {
public final String name;
public final LatLng location;
NamedLocation(String name, LatLng location) {
this.name = name;
this.location = location;
}
}
/**
* A list of locations to show in this ListView.
*/
private static final NamedLocation[] LIST_LOCATIONS = new NamedLocation[]{
new NamedLocation("Cape Town", new LatLng(-33.920455, 18.466941)),
new NamedLocation("Beijing", new LatLng(39.937795, 116.387224)),
new NamedLocation("Bern", new LatLng(46.948020, 7.448206)),
new NamedLocation("Breda", new LatLng(51.589256, 4.774396)),
new NamedLocation("Brussels", new LatLng(50.854509, 4.376678)),
new NamedLocation("Copenhagen", new LatLng(55.679423, 12.577114)),
new NamedLocation("Hannover", new LatLng(52.372026, 9.735672)),
new NamedLocation("Helsinki", new LatLng(60.169653, 24.939480)),
new NamedLocation("Hong Kong", new LatLng(22.325862, 114.165532)),
new NamedLocation("Istanbul", new LatLng(41.034435, 28.977556)),
new NamedLocation("Johannesburg", new LatLng(-26.202886, 28.039753)),
new NamedLocation("Lisbon", new LatLng(38.707163, -9.135517)),
new NamedLocation("London", new LatLng(51.500208, -0.126729)),
new NamedLocation("Madrid", new LatLng(40.420006, -3.709924)),
new NamedLocation("Mexico City", new LatLng(19.427050, -99.127571)),
new NamedLocation("Moscow", new LatLng(55.750449, 37.621136)),
new NamedLocation("New York", new LatLng(40.750580, -73.993584)),
new NamedLocation("Oslo", new LatLng(59.910761, 10.749092)),
new NamedLocation("Paris", new LatLng(48.859972, 2.340260)),
new NamedLocation("Prague", new LatLng(50.087811, 14.420460)),
new NamedLocation("Rio de Janeiro", new LatLng(-22.90187, -43.232437)),
new NamedLocation("Rome", new LatLng(41.889998, 12.500162)),
new NamedLocation("Sao Paolo", new LatLng(-22.863878, -43.244097)),
new NamedLocation("Seoul", new LatLng(37.560908, 126.987705)),
new NamedLocation("Stockholm", new LatLng(59.330650, 18.067360)),
new NamedLocation("Sydney", new LatLng(-33.873651, 151.2068896)),
new NamedLocation("Taipei", new LatLng(25.022112, 121.478019)),
new NamedLocation("Tokyo", new LatLng(35.670267, 139.769955)),
new NamedLocation("Tulsa Oklahoma", new LatLng(36.149777, -95.993398)),
new NamedLocation("Vaduz", new LatLng(47.141076, 9.521482)),
new NamedLocation("Vienna", new LatLng(48.209206, 16.372778)),
new NamedLocation("Warsaw", new LatLng(52.235474, 21.004057)),
new NamedLocation("Wellington", new LatLng(-41.286480, 174.776217)),
new NamedLocation("Winnipeg", new LatLng(49.875832, -97.150726))
};
}
答案 3 :(得分:0)
使用静态地图API而不是地图片段。您可以使用Web视图实现它。首先用webview替换地图片段。按照以下步骤进行操作。
在资产文件夹的html文件夹中创建一个html文件 static_map.html
其内容可能如下所示
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
html,body{
padding:0;
margin:0;
}
.map{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<img class="map" src="REPLACE_HERE" >
</body>
</html>
以编程方式创建静态地图网址,并将 REPLACE_HERE 字符串替换为该字符串。将其加载到Web视图中。这将大大减少我们的努力。
代码如下
try {
String url ="https://maps.googleapis.com/maps/api/staticmap?";
url+="&zoom=13";
url+="&size=600x300";
url+="&maptype=roadmap";
url+="&markers=color:green%7Clabel:G%7C"+latitude+", "+longitude;
url+="&key="+ YOUR_GOOGLE_API_KEY;
InputStream is = context.getAssets().open("html/static_map.html");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String str = new String(buffer);
str = str.replace("REPLACE_HERE", url);
wv_map.getSettings().setJavaScriptEnabled(true);
wv_map.loadDataWithBaseURL("", str, "text/html", "UTF-8", "");
} catch (IOException e) {
}
需要在谷歌控制台中启用和静态API。