8

我正在嘗試構建一個應用程序來實現Action Bar選項卡。其中一個選項卡應該包含一個MapFragment。MapFragment in Action Bar Tabs

如何使用選項卡實現一個操作欄,其中一個是地圖片段?

你能幫我解決這個問題嗎?

這是我到目前爲止有:

主類

package com.nfc.demo; 

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

public class NFCDemoActivity extends Activity { 

    Tab selectedTab = null; 

    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ActionBar bar = getActionBar(); 
    bar.setDisplayShowHomeEnabled(false); 
    bar.setDisplayShowTitleEnabled(false); 

    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

    bar.setCustomView(R.layout.main); 

    ActionBar.Tab mapTab = bar.newTab().setText("Map"); 
    ActionBar.Tab settingsTab = bar.newTab().setText("Settings"); 
    ActionBar.Tab aboutTab = bar.newTab().setText("About"); 

    MapFragment mapFragment = new MapFragment(); 
    SettingsFragment settingsFragment = new SettingsFragment(); 
    AboutFragment aboutFragment = new AboutFragment(); 

    mapTab.setTabListener(new TabListener(mapFragment)); 
    settingsTab.setTabListener(new TabListener(settingsFragment)); 
    aboutTab.setTabListener(new TabListener(aboutFragment)); 

    Tab selectedTab = (Tab) getLastNonConfigurationInstance(); 

    if (selectedTab == null) { 
     bar.addTab(mapTab, false); 
     bar.addTab(settingsTab, false); 
     bar.addTab(aboutTab, true); 
    } 

    setContentView(R.layout.main); 

    } 

    public Object onRetainNonConfigurationInstance() { 
    return selectedTab; 
    } 

    protected boolean isRouteDisplayed() { 
     return false; 
    } 

    protected class TabListener implements ActionBar.TabListener { 
    private Fragment fragment; 

    public TabListener(Fragment fragment) { 
     this.fragment = fragment; 
    } 

    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) { 
     fragmentTransaction.replace(R.id.mainFragment, this.fragment, null); 
     selectedTab = tab; 
    } 

    public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) { 
     fragmentTransaction.remove(this.fragment); 
    } 

    public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) { 
     //do nothing 
    } 
    } 
} 

片段類都只是使用.xml佈局返回吹氣。

XML佈局:

main.xml中(圖應該是在這個XML文件)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/mainFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" > 

</LinearLayout> 

的settings.xml和about.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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" 
    android:orientation="horizontal" > 

    <TextView 
     android:id="@+id/textView123" 
     android:text="asdfg" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

我一直在努力弄清楚如何進行幾天,但我真的很困惑。 任何幫助/提示將不勝感激。

另外,如何getLastNonConfigurationInstance()?它已被棄用。

+0

對不起,我想我的問題是:明確。我編輯它,但讓我知道是否需要進一步改進。 – hermann

+0

那麼,你的整體問題是很清楚的,但是你給我們提供了一堆代碼,並沒有解釋代碼的問題。將「MapFragment」放在操作欄選項卡中與將任何其他片段放入操作欄選項卡中沒有區別。 – CommonsWare

+0

雖然我似乎無法弄清楚如何去做。一旦我改變了main.xml並添加了一個片段,我得到了由java.lang.IllegalArgumentException引起的錯誤膨脹類片段錯誤:二進制XML文件行#2:重複ID爲0x7f040005,標記爲null,或者父母標識爲0x1020002與另一個fragment for com.google.android.gms.maps.MapFragment 12-28 21:14:07.991:E/AndroidRuntime(26189):\t at android.app.Activity.onCreateView(Activity.java:4722)' – hermann

回答

16

在以下解決方案中,可以將GoogleMap添加到操作欄選項卡/下拉列表中。這樣做的關鍵在於正確設置片段以在切換到操作欄中的另一個片段時銷燬MapFragment。

創建一個實現了操作欄功能的活動:

  1. 在Eclipse中創建一個項目,使用標籤的主要活動。如果您不這樣做,請繼續執行步驟2-5。
  2. 創建一個擴展爲Activity的類並實現ActionBar.OnNavigationListener
  3. 創建一個佈局XML文件,當您在它們之間切換時,它是您的選項卡片段的容器。
  4. 在Activity類中實現/覆蓋以下方法:public boolean onNavigationItemSelected(int position, long id)
  5. 在此方法中,在position對象之間切換以確定選定的選項卡,並使用FragmentManager將片段設置爲新實例,如下所示:getFragmentManager().beginTransaction().replace(R.id.container, fragment).commit()

創建包含地圖片段:

  1. 創建擴展Fragment作爲標籤的片段用一個類。閱讀[1]以更好地理解MapFragment。
  2. 創建一個包含片段元素的佈局XML文件(如[1])所示。使用該頁面中的XML創建佈局XML文件並將其用於片段類中。
  3. 通過覆蓋onCreateView來擴展片段類中的佈局XML文件。
  4. 您的應用程序現在應該在使用您的片段類的選項卡中顯示地圖,但切換到另一個選項卡並返回到地圖選項卡將導致重複的視圖ID。要解決這個問題,請繼續下一步。
  5. 在你的片段類,重寫下面的方法來專門破壞底層的GoogleMap對象,以便它可以被重新創建時,地圖標籤加載再次您的片段類:

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

謝謝! onDestroyView是我的代碼需要:-) – sourcerebels

+1

現在我正在使用:if(f!= null && f.isResumed())或者在關閉我的應用程序時按下返回按鈕時收到異常。 TY – sourcerebels

+1

這個工作,但如果我旋轉我的屏幕,我的應用程序崩潰與此異常:導致:java.lang.IllegalStateException:不能執行此操作後onSaveInstanceState – jramoyo

-1

不知道你是否已經解決它。 您必須添加谷歌播放服務作爲庫項目,使其工作。首先,我嘗試添加jar文件,但那不起作用。

+0

如果谷歌播放服務設置不正確,您的地圖無法加載。 –