使用Maps V2和Fragments的问题

时间:2013-02-28 20:37:49

标签: android google-maps android-actionbar fragment

我有以下情况:

  • 我有一个使用android actionbar
  • 的3个标签的简单应用
  • 第一个标签(不是标签,但下面的GUI)应包含地图

我不确定如何使用Activities,Fragments(Java)和Fragments(xml)进行设置。您从google playservices获得的地图示例都只使用了一个Activity。

使用操作栏(选项卡导航)时,应使用片段。是吗?

所以我实现了以下不能正常工作的组件。

package ch.bfh.femtho.skiguide;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;

public class MainActivity extends Activity {

public static Context appContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    appContext = getApplicationContext();

    // Set up the action bar to show tabs.
    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // For each of the sections in the app, add a tab to the action bar.

    ActionBar.Tab mapTab = actionBar.newTab().setText(R.string.tab_title_map);
    ActionBar.Tab poiListeTab = actionBar.newTab().setText(R.string.tab_title_poiliste);
    ActionBar.Tab meetingpointTab =    actionBar.newTab().setText(R.string.tab_title_meetingpoint);


    mapTab.setTabListener(new TabListener<MyMapFragment>(
            this, "map", MyMapFragment.class));
    poiListeTab.setTabListener(new TabListener<PoiListeFragment>(
            this, "poiliste", PoiListeFragment.class));
    meetingpointTab.setTabListener(new TabListener<MeetingpointFragment>(
            this, "meetingpoint", MeetingpointFragment.class));

    actionBar.addTab(mapTab);
    actionBar.addTab(poiListeTab);
    actionBar.addTab(meetingpointTab);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}

}

TabListener:

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;

public class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    /** Constructor used each time a new tab is created.
      * @param activity  The host Activity, used to instantiate the fragment
      * @param tag  The identifier tag for the fragment
      * @param clz  The fragment's Class, used to instantiate the fragment
      */
    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    /* The following are each of the ActionBar.TabListener callbacks */

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            ft.attach(mFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            // Detach the fragment, because another one is being attached
            ft.detach(mFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

片段:

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class MyMapFragment extends Fragment {

private MapView mMapView;
private GoogleMap mMap;
private Bundle mBundle;
private UiSettings mUiSettings;

int mCurCheckPosition = 0;

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("curChoice", mCurCheckPosition);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (savedInstanceState != null) {
            // Restore last state for checked position.
        mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);

    try {
        MapsInitializer.initialize(getActivity());
    } catch (GooglePlayServicesNotAvailableException e) {
        // TODO handle this situation
    }

    mMapView = (MapView) inflatedView.findViewById(R.id.map);
    mMapView.onCreate(mBundle);
    setUpMapIfNeeded(inflatedView);

    return inflatedView;
}



@Override
public void onDestroyView() {
    super.onDestroyView();
    MyMapFragment f = (MyMapFragment) getFragmentManager().findFragmentById(R.id.map);
    if (f != null) {
        getFragmentManager().beginTransaction().remove(f).commit();
    }
}



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mBundle = savedInstanceState;
}

private void setUpMapIfNeeded(View inflatedView) {
    if (mMap == null) {
        mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
        if (mMap != null) {
            setUpMap();
        }
    }
}

private void setUpMap() {
    mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    mMap.setOnMapClickListener(this);
    mMap.setOnMapLongClickListener(this);
    mMap.setMyLocationEnabled(true);
    mUiSettings = mMap.getUiSettings();
    mUiSettings.setMyLocationButtonEnabled(true);
}

@Override
public void onResume() {
    super.onResume();
    mMapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mMapView.onPause();
}

@Override
public void onDestroy() {
    mMapView.onDestroy();
    super.onDestroy();
}

}

Fragment(xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity" >

   <fragment
       android:id="@+id/map"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       class="com.google.android.gms.maps.MapFragment" />

</RelativeLayout>

导航到另一个标签然后返回地图时会出现问题。添加的标记消失,相机位置丢失,......

有人可以帮我这个吗?

感谢

1 个答案:

答案 0 :(得分:0)

我想你应该做的是覆盖mapFragment中的onSaveInstanceState方法,并将所有你想要的数据保存在savedInstantState对象中(包括你创建的位置和标记位置,而不仅仅是你要保存的int),以及onCreate方法你应该重用所有这些数据。

有关保存状态的更多信息,请访问:

http://www.eigo.co.uk/labs/managing-state-in-an-android-activity/