片段中的MapView(Honeycomb)

Val*_*tin 81 android google-maps android-maps android-fragments android-3.0-honeycomb

既然最终的SDK已经推出google apis - 使用MapView创建片段的最佳方法是什么?MapView需要MapActivity才能正常工作.

让管理片段的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

ina*_*ruk 87

我已经设法通过在片段中使用TabHost来解决这个问题.

这是一个想法(简要地):

  1. MainFragmentActivity扩展FragmentActivity(从支持库)并具有MapFragment.

  2. MyMapActivity扩展MapActivity和包含MapView.

  3. LocalActivityManagerFragment 主机 LocalActivityManager

  4. MapFragment延伸LocalActivityManagerFragment.

  5. LocalActivityManager包含MyMapActivity活动.

示例实现:https: //github.com/inazaruk/map-fragment.


在此输入图像描述

  • 请注意,现在不推荐使用LocalActivityManager (8认同)
  • 如果您希望MapActivity能够与父Activity一起使用(使用Fragment很容易),那么您可以使用Activity.getParent() (4认同)
  • 如果其他人想知道,这里是代码:`Intent i = new Intent(getActivity().getParent(),MyMapActivity.class); 窗口w = localActivityManager.startActivity("tag",i); currentView = w.getDecorView(); currentView.setVisibility(View.VISIBLE); currentView.setFocusableInTouchMode(真); ((ViewGroup)currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); this.contentView.addView(currentView);` (4认同)
  • 它使用标签和片段对我来说效果很好.对于那些询问解释的人,我宁愿看到项目及其代码,这很容易理解.是的,"LocalActivityManager"已被弃用,但这只是一个黑客攻击,当他们决定在Fragments中包含对Maps的适当支持时,这个问题应该得到妥善解决. (4认同)
  • 你真的不需要使用TabHost,你也可以只使用LocalActivityManager并将返回的窗口附加到你的片段的内容 (3认同)
  • 我试过这个,就像一个魅力,谢谢:) (2认同)

Tom*_*che 23

正如Google网上论坛所讨论的那样,Peter Doyle也构建了一个支持Google地图的自定义兼容库.Android的支持-V4-谷歌地图

但是,也有一个缺点:

目前,一个缺点是扩展FragmentActivity的所有类都是MapActivitys.它可以创建一个单独的类(即FragmentMapActivity),但它需要对FragmentActivity代码进行一些重构.

  • 这也意味着您的应用程序不会与最新的支持库保持同步.虽然android-support-v4-googlemaps已多次更新,但它目前落后2个版本.我同意其他人的意见,这个修改过的库比使用已弃用的LocalActivityManager更大. (6认同)

小智 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 但唯一避免"LocalActivityManager"的解决方案(如此处讨论的那样:http://code.google.com/p/android/issues/detail?id = 15347)涉及扩展*all*`FragmentActivities`,这似乎更不理想. (2认同)

Pau*_*kov 8

截至2012年12月3日,谷歌发布了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"/>
Run Code Online (Sandbox Code Playgroud)