81

最終的なSDKがgoogleapisでリリースされたので、MapViewを使用してフラグメントを作成するための最良の方法は何ですか?MapViewが正しく機能するには、MapActivityが必要です。

フラグメントを管理するアクティビティがMapActivityから継承し(フラグメントが自己完結型であるという考えに反するため、悪い解決策)、通常のxmlベースのレイアウトを使用することは機能しません。MapActivity.setupMapView()でNullPointerExceptionが発生します:

E / AndroidRuntime(597):原因:java.lang.NullPointerException
E / AndroidRuntime(597):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):com.google.android.maps.MapView。(MapView.java:247)

私の2番目のアイデアは、プログラムでMapViewを作成し、関連するアクティビティを(getActivity()を介して)コンテキストとしてMapViewコンストラクターに渡すことでした。動作しません:

E / AndroidRuntime(834):原因:java.lang.IllegalArgumentException:MapViewsは、MapActivityのインスタンス内でのみ作成できます。
E / AndroidRuntime(834):com.google.android.maps.MapView。(MapView.java:291)
E / AndroidRuntime(834):com.google.android.maps.MapView。(MapView.java:235)
E / AndroidRuntime(834):de.foo.FinderMapFragment.onCreateView(FinderMapFragment.java:225)で
E / AndroidRuntime(834):android.app.FragmentManagerImpl.moveToState(FragmentManager.java:708)で
E / AndroidRuntime(834):android.app.FragmentManagerImpl.moveToState(FragmentManager.java:900)で
E / AndroidRuntime(834):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のようなものがあるはずです...では、これを行うための現在のベストプラクティスは何ですか?

ドイツ、バレンティンからの感謝とよろしく

4

12 に答える 12

87

TabHost をフラグメントで使用することで、これを解決できました。

これがアイデアです(簡単に):

  1. MainFragmentActivityextends FragmentActivity(サポート ライブラリから) と has がありMapFragmentます。

  2. MyMapActivity拡張MapActivityし、含むMapView

  3. LocalActivityManagerFragmentホストLocalActivityManager

  4. MapFragment伸びLocalActivityManagerFragmentます。

  5. そして、その中にアクティビティがLocalActivityManager含まれています。MyMapActivity

実装例: https://github.com/inazaruk/map-fragment .


ここに画像の説明を入力

于 2011-11-14T18:28:16.213 に答える
23

Google Groupsで議論されているように、Peter Doyle は、Google マップもサポートするカスタム互換性ライブラリを作成しました。android-support-v4-googlemaps

ただし、欠点もあります。

現在、1 つの欠点は、FragmentActivity を拡張するすべてのクラスが MapActivity であることです。別のクラス (FragmentMapActivity など) を作成することは可能ですが、FragmentActivity コードのリファクタリングが必要です。

于 2011-07-28T11:36:26.620 に答える
13

答えを明確にするだけです。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());
    }
}
于 2012-05-24T14:11:56.017 に答える
8

As of 03.12.2012 Google released Google Maps Android API v2. Now you can forget about these problems. https://developers.google.com/maps/documentation/android/

Example using new API - https://developers.google.com/maps/documentation/android/start#add_a_map

This API will work for at least Android API 8, so use it ;).

So now you can simply use "com.google.android.gms.maps.MapFragment" fragment class. It will display the map in your Activity. Layout example from the link above:

<?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"/>
于 2012-12-10T08:46:57.467 に答える
4

これに関する 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" />
于 2012-12-03T19:48:14.280 に答える
2

Google Maps API は AOSP の一部ではありません。Google 社員が応答しない限り、将来 MapFragment が存在するかどうかはほとんどわかりません。

考えられる限定的な代替手段は、 を使用し、WebViewFragmentそれを悪用してカスタムmaps.google.comURL をロードすることです。

于 2011-02-24T19:26:20.070 に答える
2

残念ながら、Google はまだ応答していません。FWIW 本当にこれを行う必要がある場合は、次の方法以外に方法がありませんでした。

アクティビティを管理するタブに MapActivity を継承させ、そこにプログラムで MapView を作成し、mapfragment.xml に ViewGroup を含め、次を使用して MapView を ViewGroup に追加します。

((ViewGroup) getFragmentManager().findFragmentById(R.id.finder_map_fragment).getView()).addView(mapView);;

明らかに、これはフラグメントが自己完結型であるという考えに強く反しますが...

于 2011-02-25T17:25:50.780 に答える
2

これは、非常に単純化されたMapFragmentMonoDroid ( Mono for Android ) バージョンです。

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();
    }
}
于 2012-10-02T01:45:33.843 に答える
1

ABS 4.0 の新しいバージョンでは、MapFragmentActivity はサポートされていません。フラグメントにマップビューを含めるための優れたソリューションを次に示します。

https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21

于 2012-04-04T07:08:31.617 に答える
1

これにより、フラグメントに MapView を追加する際の問題が解決されます。 https://github.com/petedoyle/android-support-v4-googlemaps

于 2012-03-11T09:42:07.613 に答える
1

解決策を教えてください:

  1. クラスの作成 TempFragmentActivity は MapActivity を拡張します
  2. TempFragmentActivity 内に MapView オブジェクトがあります (xml での通常の定義と同様)
  3. この MapView オブジェクトを親 (LinearLayout) から削除します (後で例外を無効にします)
  4. この MapView オブジェクトをどこかに保持します (例: TempFragmentActivity の静的メンバー)
  5. Fragment で、コードを使用してこの MapView オブジェクトを追加します(xmlで定義しないでください)いくつかの LinearLayout に
于 2012-05-10T14:09:04.643 に答える
0

MapFragment の問題に対する LocalActivityManager ベースのソリューションをマッシュアップして、小さなライブラリを作成しました (さまざまな使用状況を示すサンプル アプリも含まれています)。

https://github.com/coreform/android-tandemactivities

于 2012-08-29T00:08:20.737 に答える