2013-11-25 24 views
3

我有一個應用程序,頂部有一個標籤欄。當其中一個選項卡被點擊時,它會加載一個ListView。然後當單擊其中一個列表視圖項目並加載詳細信息頁面時。詳細信息頁面的另一個工具欄位於標籤欄下方的頂部,後退按鈕可返回列表。其中一個列表選項雖然是'方向'。而不是正常的詳細信息頁面加載一個視圖,其中包含頂部的相同工具欄(包括一個獲取方向按鈕)和一個谷歌地圖,其餘部分以標記爲中心位置。這最初起作用很大。如果我點擊後退按鈕,它會進入清單,我可以回到方向。但是,有兩件事情可以打破這一點。Android:谷歌地圖在Tabs/SupportFragments中的問題

  1. 我在路線頁面上。我點擊另一個標籤。然後我點擊回到前一個標籤。現在列表再次呈現(應該如此)。然後我點擊'方向'按鈕。我沒有顯示工具欄和地圖,而是在標籤欄下方出現一個空白屏幕。

  2. 再次,我在路線頁面上。我點擊回到列表。然後我點擊另一個標籤。然後我點擊回到前一個標籤。我再次點擊'路線'。該應用程序崩潰拋出NullPointerException。例外是我試圖通過它的id檢索地圖的行。

這裏是被稱爲隨時隨地方向列表項被點擊的代碼和方向的頁面加載:

try { 
      mLocationClient.connect(); 
      v = inflater.inflate(R.layout.directions, container, false); 
      GoogleMap mMap; 
      mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.directionsmap)).getMap(); 
      Geocoder coder = new Geocoder(getActivity()); 
      List<Address> address; 

      try { 
       String myAddress = "1 Monument Cir Indianapolis, IN 46204"; 
       address = coder.getFromLocationName(myAddress, 1); 
       Address museumLocation = address.get(0); 
       mMap.addMarker(new MarkerOptions() 
         .position(new LatLng(museumLocation.getLatitude(), museumLocation.getLongitude())) 
         .title(getResources().getString(R.string.museumTitle))); 
      } catch(Exception e) { 
       // 
      } 
      Button backButton = (Button)v.findViewById(R.id.backtoexhibits); 
      backButton.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        //Fragment fragment = (getFragmentManager().findFragmentById(R.id.directionsmap)); 
        FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); 
        //ft.remove(fragment); 

        InfoTab infoTab = new InfoTab(); 
        ft.replace(R.id.realtabcontent, infoTab); 
        ft.commit(); 
       } 
      }); 

      Button directionsButton = (Button)v.findViewById(R.id.getdirections); 
      directionsButton.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        try { 
         openDirectionsDialog(); 
        } catch (UnsupportedEncodingException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      }); 
     } catch (InflateException e){ 
      /* map is already there, just return view as it is */ 
      Log.d("DEBUG",e.getLocalizedMessage()); 
     } 

這裏是我的方向片段的xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:map="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 
<LinearLayout 
    android:id="@+id/directionsheader" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@color/tcmblue" 
    android:orientation="horizontal" > 
    <Button 
     android:id="@+id/backtoexhibits" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/backtext" 
     android:layout_margin="5dp" 
     android:textColor="@color/white" 
     android:background="@drawable/buttonselector" 
     android:paddingLeft="10dp" 
     android:paddingRight="10dp" 
     android:paddingTop="5dp" 
     android:paddingBottom="5dp" /> 
    <Button 
     android:id="@+id/getdirections" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/getdirections" 
     android:layout_margin="5dp" 
     android:textColor="@color/white" 
     android:background="@drawable/buttonselector" 
     android:paddingLeft="10dp" 
     android:paddingRight="10dp" 
     android:paddingTop="5dp" 
     android:paddingBottom="5dp" /> 

</LinearLayout> 
<fragment 
    class="com.google.android.gms.maps.SupportMapFragment" 
    android:id="@+id/directionsmap" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    map:cameraTargetLat="39.810166" 
    map:cameraTargetLng="-86.156708" 
    map:cameraZoom="15" 
    map:mapType="normal" /> 

</LinearLayout> 

編輯

這裏是我的標籤活動的代碼。

import android.content.Intent; 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentTabHost; 
import android.support.v4.app.FragmentTransaction; 
import android.widget.TabHost.OnTabChangeListener; 
import android.widget.TabWidget; 
import android.widget.TextView; 

public class TabsActivity extends FragmentActivity { 
    private FragmentTabHost mTabHost; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.tabs); 
     mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); 
     mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 

     mTabHost.addTab(mTabHost.newTabSpec("Home").setIndicator("Home", getResources().getDrawable(R.drawable.hometab)),HomeTab.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Explore").setIndicator("Explore", getResources().getDrawable(R.drawable.exploretab)),ExploreTab.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Info").setIndicator("Info", getResources().getDrawable(R.drawable.infotab)),InfoTab.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Social").setIndicator("Social", getResources().getDrawable(R.drawable.socialtab)),SocialTab.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Contact").setIndicator("Contact", getResources().getDrawable(R.drawable.contacttab)),ContactTab.class, null); 

     TabWidget tabWidget = mTabHost.getTabWidget(); 
     tabWidget.setStripEnabled(false); 
     for(int i=0; i < tabWidget.getChildCount(); i++){ 
      tabWidget.getChildAt(i).setBackgroundResource(R.drawable.tab_bg); 
      TextView tv = (TextView)tabWidget.getChildAt(i).findViewById(android.R.id.title); 
      tv.setTextColor(this.getResources().getColor(R.color.white)); 
     } 

     mTabHost.setOnTabChangedListener(new OnTabChangeListener() { 

      @Override 
      public void onTabChanged(String tabId) { 
       FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
       if(tabId=="Home"){ 
        finish(); 
       } else if(tabId=="Explore") { 
        ExploreTab exploreTab = new ExploreTab(); 
        ft.replace(R.id.realtabcontent, exploreTab); 
       } else if(tabId=="Info") { 
        InfoTab infoTab = new InfoTab(); 
        ft.replace(R.id.realtabcontent, infoTab); 
       } else if(tabId=="Social") { 
        SocialTab socialTab = new SocialTab(); 
        ft.replace(R.id.realtabcontent, socialTab); 
       } else if(tabId=="Contact") { 
        ContactTab contactTab = new ContactTab(); 
        ft.replace(R.id.realtabcontent, contactTab); 
       } 
       ft.commit(); 
       TabWidget tw = mTabHost.getTabWidget(); 
       for(int i=0; i < tw.getChildCount(); i++){ 
        TextView tabText = (TextView)tw.getChildAt(i).findViewById(android.R.id.title); 
        if(tabText.getText()==tabId){ 
         tabText.setTextColor(TabsActivity.this.getResources().getColor(R.color.tcmgreen)); 
        } else { 
         tabText.setTextColor(TabsActivity.this.getResources().getColor(R.color.white)); 
        } 

       } 
      } 
     }); 

     Intent intent = getIntent(); 
     String tag = intent.getStringExtra("tab"); 
     mTabHost.setCurrentTabByTag(tag); 

    } 

    } 

編輯2:

我註釋掉的背面按鈕刪除片段的部分。該應用程序不再崩潰。不過,我可以一次去指路。之後,如果我打回或另一個選項卡,然後回到方向我得到一個空白屏幕的地圖應該是。這裏是什麼出來的堆棧跟蹤:

12-09 16:29:56.056: W/System.err(16474): android.view.InflateException: Binary XML file line #39: Error inflating class fragment 
12-09 16:29:56.066: W/System.err(16474): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713) 
12-09 16:29:56.066: W/System.err(16474): at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) 
12-09 16:29:56.066: W/System.err(16474): at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
12-09 16:29:56.066: W/System.err(16474): at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
12-09 16:29:56.066: W/System.err(16474): at org.childrensmuseum.visittcmindy.PageDetails.onCreateView(PageDetails.java:117) 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478) 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460) 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) 
12-09 16:29:56.066: W/System.err(16474): at android.os.Handler.handleCallback(Handler.java:733) 
12-09 16:29:56.066: W/System.err(16474): at android.os.Handler.dispatchMessage(Handler.java:95) 
12-09 16:29:56.066: W/System.err(16474): at android.os.Looper.loop(Looper.java:137) 
12-09 16:29:56.066: W/System.err(16474): at android.app.ActivityThread.main(ActivityThread.java:4998) 
12-09 16:29:56.066: W/System.err(16474): at java.lang.reflect.Method.invokeNative(Native Method) 
12-09 16:29:56.066: W/System.err(16474): at java.lang.reflect.Method.invoke(Method.java:515) 
12-09 16:29:56.066: W/System.err(16474): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) 
12-09 16:29:56.066: W/System.err(16474): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) 
12-09 16:29:56.066: W/System.err(16474): at dalvik.system.NativeStart.main(Native Method) 
12-09 16:29:56.066: W/System.err(16474): Caused by: java.lang.IllegalArgumentException: Binary XML file line #39: Duplicate id 0x7f050058, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment 
12-09 16:29:56.066: W/System.err(16474): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:290) 
12-09 16:29:56.066: W/System.err(16474): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685) 

編輯3

我現在固定的,因此你可以單擊後退後回到地圖。修復相當簡單。你看不到的是,在try語句之外,我的視圖'v'是在onCreateView函數中聲明的。我把它拿出來,並且把它變成了一個私有的靜態變量。現在它不會迷路。我使用這個線程的答案:Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment

雖然在哪裏如果你去地圖,點擊返回,然後回到它後面的按鈕導致崩潰的地方發展了一個新問題。它在創建FragmentTransaction的地方觸發一個空指針異常。我會爲此開始一個新的線程。

+0

你可以發佈活動的完整代碼嗎? –

+0

添加了處理我所有選項卡的活動的代碼。這是否夠用,還是有其他你想看的東西。 – LoneWolfPR

回答

2

這是我第一次嘗試回答SO問題,所以我很抱歉,如果我在這裏的基礎!

我並不完全熟悉如何在這種情況下使用FragmentTransaction,但我懷疑是撥打英尺。除去(片段);實際上是打破後續調用來查找片段。

要細說,它看起來像你按後退按鈕時執行以下操作(從高位):

  • 查找地圖片段
  • 開始交易
  • 取出地圖從片段經理片段(我想這就是問題的所在
  • 這樣的片段內容交換(因爲我希望你這樣做)
  • 提交事務

如果要刪除的地圖碎片,你覺得你確實需要刪除它,當你重新創建片段並將其添加回經理以備將來使用?

+0

我正在刪除這個片段,因爲我認爲這是在我點擊後退按鈕時調用了一個衝突,然後試圖返回。我註釋了該部分。現在發生的是,如果我點擊方向,地圖加載正常。我回擊了。然後我再次點擊指示。我得到的只是地圖片段應該放置的空白區域。但是我在堆棧跟蹤中得到了這個結果:'二進制XML文件行#39:錯誤的擴展類片段' – LoneWolfPR

+0

感謝您的更新。我會再檢查一次。不要在這裏抽取我自己的博客,但這是我處理Android中的選項卡的定製解決方案:[link](http://devleader.ca/2013/11/04/fragments-tabbed-android-user-interface /)。 **編輯:**它看起來像你正在處理交換信息選項卡兩次。一旦進入後退按鈕,一旦進入監聽器事件處理程序。這是怎麼回事?這將解釋重複的ID問題。 –

+0

加載信息頁後出現一個列表。如果您單擊列表項目,則會使用詳細信息視圖交換片段內容。詳細信息視圖有一個工具欄,其中包含後退按鈕和下方的內容。點擊後退按鈕就會再次將列表中的片段內容替換爲列表。編輯:應該指出的是,地圖是唯一一個有問題的地方。其他列表項只是加載一些內容的滾動視圖。他們之間來回點擊很好。 – LoneWolfPR