Andoird開發 - 使用碎片和RadioGroup實現底部導航欄

設置底部的導航欄,點擊這一項需要高亮這一項。按照ViewPager裏面小白點的方式,新建幾個selector,因爲使用的是RadioGroup,因此需要通過android_state_checked屬性判斷是否點擊。這裏我只用文本爲例,因爲我沒有合適的圖片。
drawable文件夾新建background.xml,當enabled屬性爲true的時候,設置顏色爲草綠色,false時爲黑色。

filename:background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="@color/grassgreen"/>
    <item android:state_checked="false" android:color="@color/black"/>
</selector>

然後編寫activity_main.xml佈局文件,主要由兩部分,一部分爲主界面,爲一個碎片,另一部分爲一個RadioGroup控件。由於有2個相同的控件,因此可以將屬性寫成一個style,直接設置控件的style屬性即可。

filename:res/styles
<style name="BottomNavItemStyle">
        <item name="android:layout_weight">1</item>
        <item name="android:layout_height">match_parent</item>
        <item name="android:background">@color/palegoldenrod</item>
        <item name="android:textColor">@drawable/background</item>
        <item name="android:button">@null</item>
        <item name="android:gravity">center</item>
    </style>

RadioButton還想有個屬性是adnroid:drawableTop可以用來設置圖片的屬性,也是利用selector,哭了哭了,不會用RelativeLayout了,換成vertical的LinearLayout吧。

filename:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.k.androidpractie.MainActivity">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/MainFragment"></FrameLayout>
    <RadioGroup
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="50dp"
        android:id="@+id/BottonNav">
        <RadioButton
            android:id="@+id/Page_1"
            style="@style/BottomNavItemStyle"
            android:text="第一頁"/>
        <RadioButton
            android:id="@+id/Page_2"
            style="@style/BottomNavItemStyle"
            android:text="第二頁"/>
    </RadioGroup>
</LinearLayout>

然後創建2個Fragment,改一下text

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:layout_gravity="center"
        android:text="第一個"/>
</LinearLayout>

新建兩個碎片類,加載一下碎片

public class MainFrag_1 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.main_frag_1,container,false);
        return view;
    }
}

最後在MainActivity.java中編寫,其實獲取RadioButton實例沒用,獲取RadioGroup實例然後設置監聽,然後通過checkedId判斷是哪個RadioButton。
然後好像FragmentTransaction在commit()一次以後得重新獲取,不然他報錯已commit。
碎片實例可以通過add()方法添加,也可以通過replace()替換。
一個方法,先把所有碎片實例,如果存在,調用hide()方法隱藏。假設碎片實例爲a,可以先判斷a是否爲null,即是否存在,不存在的話new一個,存在的話直接show()。因爲有可能界面中需要保存原有的數據,如果每次都new可能會讓數據 丟失。

public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
    FrameLayout MainFragmentFrameLayout;
    RadioButton Page_1_Button,Page_2_Button;
    RadioGroup BottomNavRadioGroup;
    MainFrag_1 mainFrag_1;
    MainFrag_2 mainFrag_2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MainFragmentFrameLayout=findViewById(R.id.MainFragment);
        BottomNavRadioGroup=findViewById(R.id.BottonNav);
        Page_1_Button=findViewById(R.id.Page_1);
        Page_2_Button=findViewById(R.id.Page_2);
        Page_1_Button.setChecked(true);
        //fragmentTransaction.replace(R.id.MainFragment,new MainFrag_1());
        BottomNavRadioGroup.setOnCheckedChangeListener(this) ;
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        hideFragment(fragmentTransaction);
        switch(checkedId){
            case R.id.Page_1:
                if (mainFrag_1==null){
                    mainFrag_1=new MainFrag_1();
                    fragmentTransaction.add(R.id.MainFragment,mainFrag_1);
                }else{
                    fragmentTransaction.show(mainFrag_1);
                }
                break;
            case R.id.Page_2:
                if (mainFrag_2==null){
                    mainFrag_2=new MainFrag_2();
                    fragmentTransaction.add(R.id.MainFragment,mainFrag_2);
                }else{
                    fragmentTransaction.show(mainFrag_2);
                }
                break;
        }
        fragmentTransaction.commit();
    }
    public void hideFragment(FragmentTransaction fragmentTransaction){
        if (mainFrag_1!=null){
            fragmentTransaction.hide(mainFrag_1);
        }
        if (mainFrag_2!=null){
            fragmentTransaction.hide(mainFrag_2);
        }
    }
}

然後運行程序就可以看到效果了
但是要注意一點,我這的代碼裏面沒有對之前的碎片進行處理,也就是前一個碎片應該隱藏然後顯示新的碎片,但是並沒有,即現在可能會重疊。
在實際應用的時候,讓碎片寬高都match應該就能擋住了,或者在顯示新碎片的時候,設置上一個碎片爲hide即可。

在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章