android使用Fragment實現底部菜單使用show()和hide()來切換以保持Fragment狀態


在android開發的布局中,國內大量的使用底部菜單,這個本來不符合android的規范,我個人是深惡痛絕的,但是產品是這樣設計的,也只能是這樣做了。在這篇博客中,我將結合網上的資料以及自己的使用經驗來實現一個底部菜單,解決了很多網友提出的各種問題,在文章中,我只貼出部分的實現代碼以及效果圖,免得占用大量的篇幅,讓大家看的不爽,在最后我會給出整個demo的源碼!!!

底部菜單的設計

一般來說,底部菜單是做多五個tab,這里面我做了四個tab,比較符合需求,實現的方式主要有tabhost,直接TextView,RadioButton等,我在這里使用的是RadioButton,覺得RadioButton比較簡單控制,又能很好的實現我們的需求,底部菜單的activity_main.xml的代碼如下:

<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"> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/divide" android:layout_alignParentTop="true"> </FrameLayout> <View android:id="@+id/divide" android:layout_width="match_parent" android:layout_height="1dp" android:layout_above="@+id/activity_group_radioGroup" android:background="#cccccc"/> <RadioGroup android:id="@+id/activity_group_radioGroup" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#ffffff" android:checkedButton="@+id/order_process" android:gravity="center" android:orientation="horizontal" android:paddingBottom="3dp" android:paddingTop="3dp"> <RadioButton android:id="@+id/order_process" style="@style/main_tab_bottom" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:drawableTop="@drawable/main_tab_1" android:gravity="center" android:text="訂單處理"/> <RadioButton android:id="@+id/order_query" style="@style/main_tab_bottom" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:checked="false" android:drawableTop="@drawable/main_tab_2" android:gravity="center" android:text="訂單查詢"/> <RadioButton android:id="@+id/merchant_manager" style="@style/main_tab_bottom" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:checked="false" android:drawableTop="@drawable/main_tab_3" android:gravity="center" android:text="門店管理"/> <RadioButton android:id="@+id/setting" style="@style/main_tab_bottom" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1.0" android:checked="false" android:drawableTop="@drawable/main_tab_4" android:gravity="center" android:text="設置"/> </RadioGroup> </RelativeLayout>

這個應該很好理解,就是在底部一個RadioGroup,內部放RadioButton來實現,上面放一個FrameLayout來放內容,這是xml部分。

Java代碼控制Fragment的切換

在進行tab切換的過程中,我使用show()和hide()來處理,這樣可以保存Fragment的狀態,核心代碼如下

            public void onCheckedChanged(RadioGroup group, int checkedId) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); Fragment fragment1 = fm.findFragmentByTag(fragment1Tag); Fragment fragment2 = fm.findFragmentByTag(fragment2Tag); Fragment fragment3 = fm.findFragmentByTag(fragment3Tag); Fragment fragment4 = fm.findFragmentByTag(fragment4Tag); if (fragment1 != null) { ft.hide(fragment1); } if (fragment2 != null) { ft.hide(fragment2); } if (fragment3 != null) { ft.hide(fragment3); } if (fragment4 != null) { ft.hide(fragment4); } switch (checkedId) { case R.id.order_process: if (fragment1 == null) { fragment1 = new Fragment1(); ft.add(R.id.container, fragment1, fragment1Tag); } else { ft.show(fragment1); } break; case R.id.order_query: if (fragment2 == null) { fragment2 = new Fragment2(); ft.add(R.id.container, fragment2, fragment2Tag); } else { ft.show(fragment2); } break; case R.id.merchant_manager: if (fragment3 == null) { fragment3 = new Fragment3(); ft.add(R.id.container, fragment3, fragment3Tag); } else { ft.show(fragment3); } break; case R.id.setting: if (fragment4 == null) { fragment4 = new Fragment4(); ft.add(R.id.container, fragment4, fragment4Tag); } else { ft.show(fragment4); } break; default: break; } ft.commit(); } });

切換的很完美,我們看下效果:
android底部菜單的效果圖

問題

1、上面的實現底部菜單,能夠很好的實現Fragment的切換,還能夠保存Fragment之前的狀態,但是有個很大的問題,就是,我們把app退到后台,我們去玩其他的app,過一段時間回來,這個時候我們的app已經被銷毀,我們按多任務鍵切換回來,發現界面上多個Fragment出現了重疊的情況,這是因為多個Fragment同時顯示了,出現了重疊的情況,解決的辦法如下:重寫Activity的onRestoreInstanceState方法

    @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); for (int i = 0; i < radioGroup.getChildCount(); i++) { RadioButton mTab = (RadioButton) radioGroup.getChildAt(i); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentByTag((String) mTab.getTag()); FragmentTransaction ft = fm.beginTransaction(); if (fragment != null) { if (!mTab.isChecked()) { ft.hide(fragment); } } ft.commit(); } }

很好的解決了Fragment重疊的情況
2、如果在Fragment有操作toolbar的菜單的情況,除了要在Fragment中設置setHasOptionsMenu(true);之外,還需要Fragment中重寫onHiddenChanged方法:

    @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); if (!hidden) { ((AppCompatActivity) getActivity()).setSupportActionBar(mToolbar); ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false); setHasOptionsMenu(true); } }

不然的話,在恢復Fragment的時候會出現菜單混亂的情況。
大功告成,大家有什么問題或者建議請給我留言!!!
最后給出源碼:下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM