现在最终的SDK已经推出google apis - 使用MapView创建片段的最佳方法是什么? MapView需要MapActivity才能正常工作。
让管理Fragments的Activity继承自MapActivity(糟糕的解决方案,因为它违背了Fragments自包含的想法)并使用基于xml的常规布局不起作用。我在MapActivity.setupMapView()中得到一个NullPointerException:
E/AndroidRuntime( 597): Caused by: java.lang.NullPointerException E/AndroidRuntime( 597): at com.google.android.maps.MapActivity.setupMapView(MapActivity.java:400) E/AndroidRuntime( 597): at com.google.android.maps.MapView.(MapView.java:289) E/AndroidRuntime( 597): at com.google.android.maps.MapView.(MapView.java:264) E/AndroidRuntime( 597): at com.google.android.maps.MapView.(MapView.java:247)
我的第二个想法是以编程方式创建MapView并将关联的活动(通过getActivity())作为Context传递给MapView构造函数。不起作用:
E/AndroidRuntime( 834): Caused by: java.lang.IllegalArgumentException: MapViews can only be created inside instances of MapActivity. E/AndroidRuntime( 834): at com.google.android.maps.MapView.(MapView.java:291) E/AndroidRuntime( 834): at com.google.android.maps.MapView.(MapView.java:235) E/AndroidRuntime( 834): at de.foo.FinderMapFragment.onCreateView(FinderMapFragment.java:225) E/AndroidRuntime( 834): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:708) E/AndroidRuntime( 834): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:900) E/AndroidRuntime( 834): at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:978) E/AndroidRuntime( 834): at android.app.Activity.onCreateView(Activity.java:4090) E/AndroidRuntime( 834): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
确实应该有类似MapFragment的东西来处理MapView需要的后台线程我猜...那么目前最好的做法是什么呢?
感谢德国的问候, 的Valentin
答案 0 :(得分:87)
我设法通过在片段中使用TabHost来解决这个问题。
这是一个想法(简要):
MainFragmentActivity
扩展FragmentActivity
(来自支持库),并MapFragment
。
MyMapActivity
扩展MapActivity
并包含MapView
。
LocalActivityManagerFragment
个主机LocalActivityManager
MapFragment
延伸LocalActivityManagerFragment
。
LocalActivityManager
中包含MyMapActivity
个活动。
示例实施:https://github.com/inazaruk/map-fragment。
答案 1 :(得分:23)
如Google Groups所述,Peter Doyle也构建了一个支持Google地图的自定义兼容库。 android-support-v4-googlemaps
然而,也存在不利因素:
目前,一个缺点是扩展FragmentActivity的所有类都是MapActivitys。它可以创建一个单独的类(即FragmentMapActivity),但它需要重构FragmentActivity代码。
答案 2 :(得分:13)
只是为了澄清答案。我尝试了inazaruk和ChristophK提出的方法。实际上,您可以在片段中运行任何活动 - 而不仅仅是谷歌地图。以下是感谢inazaruk和ChristophK将谷歌地图活动实现为片段的代码。
import com.actionbarsherlock.app.SherlockFragment;
import android.view.Window;
import android.app.LocalActivityManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MapFragment extends SherlockFragment {
private static final String KEY_STATE_BUNDLE = "localActivityManagerState";
private LocalActivityManager mLocalActivityManager;
protected LocalActivityManager getLocalActivityManager() {
return mLocalActivityManager;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle state = null;
if (savedInstanceState != null) {
state = savedInstanceState.getBundle(KEY_STATE_BUNDLE);
}
mLocalActivityManager = new LocalActivityManager(getActivity(), true);
mLocalActivityManager.dispatchCreate(state);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//This is where you specify you activity class
Intent i = new Intent(getActivity(), GMapActivity.class);
Window w = mLocalActivityManager.startActivity("tag", i);
View currentView=w.getDecorView();
currentView.setVisibility(View.VISIBLE);
currentView.setFocusableInTouchMode(true);
((ViewGroup) currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
return currentView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBundle(KEY_STATE_BUNDLE,
mLocalActivityManager.saveInstanceState());
}
@Override
public void onResume() {
super.onResume();
mLocalActivityManager.dispatchResume();
}
@Override
public void onPause() {
super.onPause();
mLocalActivityManager.dispatchPause(getActivity().isFinishing());
}
@Override
public void onStop() {
super.onStop();
mLocalActivityManager.dispatchStop();
}
@Override
public void onDestroy() {
super.onDestroy();
mLocalActivityManager.dispatchDestroy(getActivity().isFinishing());
}
}
答案 3 :(得分:8)
截至2012年12月3日,Google发布了 Google Maps Android API v2 。现在你可以忘记这些问题了。 https://developers.google.com/maps/documentation/android/
使用新API的示例 - https://developers.google.com/maps/documentation/android/start#add_a_map
此API至少适用于Android API 8,因此请使用它;)。
现在您只需使用“com.google.android.gms.maps.MapFragment”片段类即可。它将在您的活动中显示地图。上面链接的布局示例:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
答案 4 :(得分:4)
Google对此发表了重大新闻。他们今天发布new Google Maps API,有室内地图和MapFragment。
With this new API, adding a map to your Activity is as simple as:
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
答案 5 :(得分:2)
Google Maps API不属于AOSP。只要Googler没有回应,几乎不可能知道将来是否会有MapFragment。
可能有限的替代方法是使用WebViewFragment
并滥用它来加载自定义maps.google.com
网址。
答案 6 :(得分:2)
太糟糕了,谷歌还没有回复。 FWIW如果你真的需要这样做我找不到别的方法:
让Tab Managing Activity继承MapActivity,以编程方式在那里创建MapView,让mapfragment.xml包含ViewGroup并使用
将MapView添加到ViewGroup((ViewGroup) getFragmentManager().findFragmentById(R.id.finder_map_fragment).getView()).addView(mapView);;
显然,这强烈反对片段是自成一体的想法但是......
答案 7 :(得分:2)
这是一个非常简化的 MapFragment 的 MonoDroid ( Android版Mono )版本:
public class MapFragment : Fragment
{
// FOLLOW http://stackoverflow.com/questions/5109336/mapview-in-a-fragment-honeycomb
private static String KEY_STATE_BUNDLE = "localActivityManagerState";
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Bundle state = null;
if (savedInstanceState != null) {
state = savedInstanceState.GetBundle(KEY_STATE_BUNDLE);
}
mLocalActivityManager = new LocalActivityManager(Activity, true);
mLocalActivityManager.DispatchCreate(state);
}
public override Android.Views.View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//This is where you specify you activity class
Intent i = new Intent(Activity, typeof(SteamLocationMapActivity));
Window w = mLocalActivityManager.StartActivity("tag", i);
View currentView=w.DecorView;
currentView.Visibility = ViewStates.Visible;
currentView.FocusableInTouchMode = true;
((ViewGroup) currentView).DescendantFocusability = DescendantFocusability.AfterDescendants;
return currentView;
}
private LocalActivityManager mLocalActivityManager;
protected LocalActivityManager GetLocalActivityManager() {
return mLocalActivityManager;
}
public override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
outState.PutBundle(KEY_STATE_BUNDLE,mLocalActivityManager.SaveInstanceState());
}
public override void OnResume()
{
base.OnResume();
mLocalActivityManager.DispatchResume();
}
public override void OnPause()
{
base.OnPause();
mLocalActivityManager.DispatchPause(Activity.IsFinishing);
}
public override void OnStop()
{
base.OnStop();
mLocalActivityManager.DispatchStop();
}
}
答案 8 :(得分:1)
这解决了我在Fragments中添加MapView的问题。 https://github.com/petedoyle/android-support-v4-googlemaps
答案 9 :(得分:1)
使用新版本的ABS 4.0,不支持Map FragmentActivity,这是一个很好的解决方案,可以在片段中使用mapview!
https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21
答案 10 :(得分:1)
我可以得到解决方案:
答案 11 :(得分:0)
我写了一个小库,将基于LocalActivityManager的解决方案混合到MapFragment问题中(还包括一个显示各种使用情况的示例应用程序):