2013-04-25 42 views
1

我有一個Activity,它加載ActionBar中的2個選項卡。標籤1載入Fragment,這將使WebView膨脹,而標籤2使用地圖載入Fragment。最初,我遇到了更改導致應用程序崩潰的選項卡的問題。我遵循指示here並實施onDestroyView()帶有地圖的片段在按下後退按鈕或方向更改時崩潰應用程序

現在的問題是,如果我按Tab 1(WebView)後退按鈕,它會正確退出Activity。但如果我在選項卡2(地圖)上執行此操作,該應用會崩潰。當我改變方向時,完全相同的情況適用。我確信它與onDestroyView()有關,但我不確定它是什麼。

我甚至試圖Override後退按鈕,但沒有任何作品。

這裏是我的代碼,以提供一些背景:

Activity類:

public class MyActivity extends Activity { 

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

    //Displaying the tabs by calling ActionBar 
    ActionBar actionBar = getActionBar(); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

    //Details Tab 
    String label1 = getResources().getString(R.string.details); 
    Tab tab = actionBar.newTab(); 
    tab.setText(label1); 
    TabListener<DetailsFragment> t1 = new TabListener<DetailsFragment>(this, label1, DetailsFragment.class); 
    tab.setTabListener(t1); 
    actionBar.addTab(tab); 

    //Map Tab 
    String label2 = getResources().getString(R.string.map); 
    tab = actionBar.newTab(); 
    tab.setText(label2); 
    TabListener<MapFragment> t2 = new TabListener<MapFragment>(this, label2, MapFragment.class); 
    tab.setTabListener(t2); 
    actionBar.addTab(tab); 
} 

private 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; 
    } 

    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. 
    } 
} 

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

DetailsFragment:

public class DetailsFragment extends Fragment { 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    View v = inflater.inflate(R.layout.morning, container, false); 
    WebView webview = (WebView) v.findViewById(R.id.details); 
    webview.loadUrl("file:///android_asset/pools/details.html"); 
    return v; 
} } 

MapFragment:

public class MapFragment extends Fragment { 

static final LatLng mapLatLng = new LatLng("some numbers", "some numbers"); 
private GoogleMap map; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    View v = inflater.inflate(R.layout.map, container, false); 
    map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap(); 
    Marker amksc = map.addMarker(new MarkerOptions().position(mapLatLng).title("Map")); 

    map.moveCamera(CameraUpdateFactory.newLatLngZoom(mapLatLng, 18)); 
    return v; 
} 


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

感謝讀這麼長的帖子。任何幫助是極大的讚賞。我會離開一段時間沒有我的筆記本電腦(準確的15天),所以我可能無法迴應和測試你的答案,但放心,我會=)

在此先感謝!

編輯,包括錯誤日誌(不知道如何格式化)

04-25 11:27:54.333: E/AndroidRuntime(21779): FATAL EXCEPTION: main 

04-25 11:27:54.333: E/AndroidRuntime(21779): java.lang.NullPointerException 

04-25 11:27:54.333: E/AndroidRuntime(21779): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1380) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:430) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at android.os.Handler.handleCallback(Handler.java:615) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at android.os.Handler.dispatchMessage(Handler.java:92) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at android.os.Looper.loop(Looper.java:213) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at android.app.ActivityThread.main(ActivityThread.java:4786) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at java.lang.reflect.Method.invokeNative(Native Method) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at java.lang.reflect.Method.invoke(Method.java:511) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) 

04-25 11:27:54.333: E/AndroidRuntime(21779): at dalvik.system.NativeStart.main(Native Method) 
+0

你也可以發佈錯誤日誌嗎? – Sharj 2013-04-25 03:22:45

+0

我在問題中添加了LogCat錯誤。謝謝! – SilverHood 2013-04-25 03:35:26

+0

它看起來並不像完整的錯誤堆棧。你可以像你的代碼一樣格式化它。 – Sharj 2013-04-25 03:38:38

回答

1

我似乎已經解決了後退按鈕和方向更改問題。

這裏的技巧是不使用onDestroyView(),而是改變片段的處理方式。而不是ft.attach(mFragment)ft.detach(mFragment),我將它們更改爲ft.show(mFragment)ft.hide(mFragment)

至於導致應用程序崩潰的方向更改,我相信(如果我錯了,請更正我)只要您沒有其他橫向佈局,您可以將android:configChanges="orientation|screenSize"添加到此活動的清單中,像這樣:

<activity 
     android:theme="@style/AppTheme" 
     android:name="MyFragmentActivity" 
     android:label="@string/fragmentActivity" 
     android:configChanges="orientation|screenSize"> 
    </activity> 
0

的GoogleMap的需要的一點點時間來加載,所以如果你想使用它,它可以返回null。 嘗試在MapFragment

map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap(); 
Marker amksc = map.addMarker(new MarkerOptions().position(mapLatLng).title("Map")); 

map.moveCamera(CameraUpdateFactory.newLatLngZoom(mapLatLng, 18)); 

的onActivityCreated()方法來對我的工作提出這個代碼。 一定要看看Fragment Lifecycle

0

這是我的工作..試試吧 下面的代碼寫在onDestory()方法中

@Override 
    public void onDestroy() { 
if (fragment != null 
         && getFragmentManager().findFragmentById(
           fragment.getId()) != null) { 

        getFragmentManager().beginTransaction().remove(fragment) 
          .commit(); 
        fragment = null; 
       } 
} 
相關問題