これで、最終的なSDKがGoogle APIとともにリリースされました。MapViewでフラグメントを作成する最良の方法は何ですか? MapViewを正しく動作させるには、MapActivityが必要です。
フラグメントを管理するアクティビティがMapActivityから継承し(フラグメントが自己完結型であるという考えに反するため、悪いソリューションです)、通常のxmlベースのレイアウトを使用しても機能しません。 MapActivity.setupMapView()でNullPointerExceptionが発生します。
E/AndroidRuntime(597):原因:Java.lang.NullPointerException E/AndroidRuntime(597):at com.google.Android.maps.MapActivity.setupMapView(MapActivity.Java:400 ) E/AndroidRuntime(597):com.google.Android.maps.MapView。(MapView.Java:289) E/AndroidRuntime(597):com.google.Android。 maps.MapView。(MapView.Java:264) E/AndroidRuntime(597):at com.google.Android.maps.MapView。(MapView.Java:247)
私の2番目のアイデアは、MapViewをプログラムで作成し、関連するアクティビティ(getActivity()経由)をContextとしてMapViewコンストラクターに渡すことでした。動作しません:
E/AndroidRuntime(834):原因:Java.lang.IllegalArgumentException:MapViewはMapActivityのインスタンス内でのみ作成できます。 E/AndroidRuntime(834):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):Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:900) E/AndroidRuntime(834):at Android.app.FragmentManagerImpl.addFragment(FragmentManager.Java:978) E/AndroidRuntime(834):Android.app.Activity.onCreateView(Activity.Java:4090) E/AndroidRuntime(834):Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java :664)
MapViewが必要とするバックグラウンドスレッドを処理するMapFragmentのようなものが本当にあるはずです...では、これを行うための現在のベストプラクティスは何でしょうか。
ドイツ、バレンティンからの感謝と敬意
2012年3月12日の時点で、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"/>
フラグメントでTabHostを使用して、これを解決することができました。
これがアイデアです(簡単に):
MainFragmentActivity
はFragmentActivity
を拡張し(サポートライブラリから)、MapFragment
を持ちます。
MyMapActivity
は MapActivity
を拡張し、 MapView
を含みます。
LocalActivityManagerFragment
ホスト LocalActivityManager
MapFragment
はLocalActivityManagerFragment
を拡張します。
そして LocalActivityManager
にはMyMapActivity
アクティビティが含まれています。
実装例: https://github.com/inazaruk/map-fragment 。
Googleグループ で説明したように、Peter DoyleはGoogleマップもサポートするカスタム互換性ライブラリを構築しました。 Android-support-v4-googlemaps
ただし、欠点もあります。
現在、欠点の1つは、FragmentActivityを拡張するすべてのクラスがMapActivityであるということです。別のクラス(FragmentMapActivity)を作成することは可能ですが、FragmentActivityコードのリファクタリングが必要です。
答えを明確にするだけです。 inazarukとChristophKが提案したアプローチを試しました。実際、Googleマップだけでなく、フラグメント内のあらゆるアクティビティを実行できます。これは、inazarukとChristophKのおかげで、Googleマップアクティビティをフラグメントとして実装するコードです。
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());
}
}
これに関するGoogleからの素晴らしいニュース。彼らは本日、インドアマップとMapFragmentを備えた 新しいGoogle Maps API をリリースします。
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" />
Google Maps APIはAOSPの一部ではありません。 Google社員が応答しない限り、将来MapFragmentがあるかどうかはほとんどわかりません。
可能性のある制限された代替手段は、 WebViewFragment
を使用し、それを悪用してカスタムmaps.google.com
URL。
MonoDroid(Mono for Android)非常に単純化されたMapFragmentのバージョンです:
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();
}
}
Googleがまだ応答していないのは残念です。 FWIWあなたが本当にこれを行う必要がある場合、私は他の方法を見つけませんでした:
タブ管理アクティビティにMapActivityを継承させ、プログラムでMapViewを作成し、mapfragment.xmlにViewGroupを含め、MapViewを使用してViewGroupに追加します
((ViewGroup)getFragmentManager()。findFragmentById(R.id.Finder_map_fragment).getView())。addView(mapView);;
これは明らかに、フラグメントは自己完結型であるという考え方に大きく反しますが...
ソリューションを入手できますか:
これにより、フラグメントにMapViewを追加する際の問題が解決します。 https://github.com/petedoyle/Android-support-v4-googlemaps
ABS 4.0の新しいバージョンでは、MapFragmentActivityのサポートはありません。これは、フラグメントにマップビューを作成するための優れたソリューションです。
https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21
MapFragment問題に対するLocalActivityManagerベースのソリューションをマッシュアップする小さなライブラリを作成しました(さまざまな使用状況を示すサンプルアプリも含まれています)。