Android – ListView中包含的MapView

目前我正在尝试在一个ListView中放置一个MapView。 有没有人有这个成功? 这甚至有可能吗? 这是我的代码:

ListView myList = (ListView) findViewById(android.R.id.list); List<Map<String, Object>> groupData = new ArrayList<Map<String, Object>>(); Map<String, Object> curGroupMap = new HashMap<String, Object>(); groupData.add(curGroupMap); curGroupMap.put("ICON", R.drawable.back_icon); curGroupMap.put("NAME","Go Back"); curGroupMap.put("VALUE","By clicking here"); Iterator it = data.entrySet().iterator(); while (it.hasNext()) { //Get the key name and value for it Map.Entry pair = (Map.Entry)it.next(); String keyName = (String) pair.getKey(); String value = pair.getValue().toString(); if (value != null) { //Add the parents -- aka main categories curGroupMap = new HashMap<String, Object>(); groupData.add(curGroupMap); //Push the correct Icon if (keyName.equalsIgnoreCase("Phone")) curGroupMap.put("ICON", R.drawable.phone_icon); else if (keyName.equalsIgnoreCase("Housing")) curGroupMap.put("ICON", R.drawable.house_icon); else if (keyName.equalsIgnoreCase("Website")) curGroupMap.put("ICON", R.drawable.web_icon); else if (keyName.equalsIgnoreCase("Area Snapshot")) curGroupMap.put("ICON", R.drawable.camera_icon); else if (keyName.equalsIgnoreCase("Overview")) curGroupMap.put("ICON", R.drawable.overview_icon); else if (keyName.equalsIgnoreCase("Location")) curGroupMap.put("ICON", R.drawable.map_icon); else curGroupMap.put("ICON", R.drawable.icon); //Pop on the Name and Value curGroupMap.put("NAME", keyName); curGroupMap.put("VALUE", value); } } curGroupMap = new HashMap<String, Object>(); groupData.add(curGroupMap); curGroupMap.put("ICON", R.drawable.back_icon); curGroupMap.put("NAME","Go Back"); curGroupMap.put("VALUE","By clicking here"); //Set up adapter mAdapter = new SimpleAdapter( mContext, groupData, R.layout.exp_list_parent, new String[] { "ICON", "NAME", "VALUE" }, new int[] { R.id.photoAlbumImg, R.id.rowText1, R.id.rowText2 } ); myList.setAdapter(mAdapter); //Bind the adapter to the list 

在此先感谢您的帮助!!

Solutions Collecting From Web of "Android – ListView中包含的MapView"

在这种情况下,您可以像添加其他视图一样将MapView添加到列表中。 以下是如何创build自定义列表适配器的快速教程 。 但是我不得不提醒你,MapView是一个相当沉重的视图,如果你试图在屏幕上看到一堆,你会注意到应用程序缓慢! 您可以在列表项中添加一个button,将用户带到另一个包含地图的更多信息的页面。

要发布一个相当老的答案替代解决scheme(实际上超过2年),但我认为这可能会帮助像我这样可能会遇到这个职位的人。

注意:这对于只需要在“地图”中显示位置但不需要在ListView与其交互的人员可能是有用的。 点击ListView某个项目后,实际的地图可以显示在详细信息页面上

正如@CaseyB所指出的那样, MapView是一种沉重的观点。 为了对付这个方面(为了让生活变得更轻松一点,对我来说;-)),我select了像使用静态Google Map一样的URL来创build一个URL,使用我的应用程序所需的几个参数。 您可以在这里获得更多选项: https : //developers.google.com/maps/documentation/staticmaps/

首先,当我构buildListView的数据时,我将诸如纬度经度的数据传递给一个string,其中包含从上述链接中获取的一些静态variables。 我从Facebook API获得我的坐标。

我用来构build链接的代码:

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

以上构造的URL在浏览器中使用时会返回一个.PNG文件。 然后,在我的活动adapter中,我使用@ Fedor的Lazy Loading来显示从早期构造的URL生成的图像,以显示在自定义ListView 。 你当然可以select你自己的方法来显示这个Map (实际上是地图的图像)。

最终结果的一个例子。

在这里输入图像说明

目前,在这个ListView我有大约30个Checkin Maps(我使用它与Facebook SDK一起使用),但是用户可以有100个,并且绝对没有任何放缓的报告。

我怀疑,这可能不会帮助OP考虑问题以来的时间,但希望将来可以帮助其他用户login此页面。

首先,我不认为一次显示多个MapView会工作。 每个进程只支持一个的MapActivity文档:

“每个进程只支持一个MapActivity,同时运行的多个MapActivities可能会干扰意想不到的方式。”

http://code.google.com/android/add-ons/google-apis/reference/index.html

它并没有明确说你不能在一个MapActivity中有多个MapView,但是我认为他们也会干涉,不pipe它们在哪一种父ViewGroup中。

其次,您可能会考虑使用静态地图API来获取包含在ListView中的简单图像 – 完全成熟的MapView在任何情况下都可能是不必要的重量级:

http://code.google.com/apis/maps/documentation/staticmaps/

您可能面临的一个问题是,静态地图API会限制“用户”的使用,这可能意味着通过IP(不需要API密钥),移动networking在IP使用限制方面可能会出现问题。 我不确定如何发挥。

有可能,从GoogleMapSample代码本身:

 /** * 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; } } } 

完整的代码位于: https : //github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java

我今天面对同样的问题 – 事实certificate,你必须在你的MapActivity中创buildMapView,否则你会得到一个错误,如无法膨胀视图com.google.maps.MapView或… …通过这个MapView到你的ListAdapter并在需要时吐出。 我不得不把MapView放在一个RelativeLayout里面来调整高度和宽度(因为某些原因,MapView并不像“正常”的方式)。 你可以问我的详细信息,如果你喜欢:)