Android底部導航欄——FrameLayout + RadioGroup


原創文章,轉載請注明出處http://www.cnblogs.com/baipengzhan/p/6285881.html                      

Android底部導航欄有多種實現方式,本文詳細介紹FrameLayout + RadioGroup結構的實現方式。

 

主要的思路是,創建一個Fragment的容器,點擊RadioButton,動態地向容器中添加Fragment對象。

這種結構不同於ViewPager + RadioButton結構,本結構的Fragment展示部分不能左右滑動,只能

通過點擊RadioButton切換頁面,是一種單向傳遞的方式。

Fragment頁面可以滑動的底部導航欄結構(ViewPager + RadioButton)可以參考文章:

http://www.cnblogs.com/baipengzhan/p/6270201.html  

 

我們先看一下最終做出來的效果吧,以便有個最初的印象。

 

好啦,那下面我們開始制作這種結構的底部導航欄吧。

本結構特點:
1,我們無法直接手動切換FrameLayout中的Fragment頁面,只能借助於RadioGroup;
2,當用戶點擊RadioGroup部分中的RadioButton,被點擊的RadioButton出現被選中時的狀態,FrameLayout界面對應於RadioButton的頁面會出現在當前界面。
 
可以看到,FrameLayout和RadioGroup是單向傳遞。

 

下面我們通過一個實例完全弄懂FrameLayout + RadioGroup結構的用法
 
首先創建出我們界面的布局,上邊一個FrameLayout,中間 一條分隔線,下邊一個RadioGroup 
我們在一個Activity的布局中創建如下的xml文件: 

 

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

    <!--使用FrameLayout當做盛放Fragment對象的容器-->
    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
    <!--中間為一條分割線-->
    <View
        android:background="@color/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"/>

    <!--最下邊為RadioGroup-->
    <RadioGroup
        android:id="@+id/radioGroup"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!--第一個RadioButton-->
        <RadioButton
            android:id="@+id/button_1"
            android:text="button_1"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!--第二個RadioButton-->
        <RadioButton
            android:id="@+id/button_2"
            android:text="button_2"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!--第三個RadioButton-->
        <RadioButton
            android:id="@+id/button_3"
            android:text="button_3"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!--第四個RadioButton-->
        <RadioButton
            android:id="@+id/button_4"
            android:text="button_4"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </RadioGroup>
</LinearLayout>

  

布局中重要屬性說明:


 ①FrameLayout的android:layout_height屬性值為0,android:layout_weight屬性值為1。這兩個屬性值配合使用的意義是:
  在豎直方向上FrameLayout占滿父控件的剩余空間,也就是占據LinearLayout中除去分隔線和RadioGroup的剩余空間。
  關於android:layout_weight屬性的詳細用法請參考http://www.cnblogs.com/baipengzhan/p/6282826.html        

              
 ②RadioButton的android:button屬性值為@null。這個屬性值的意義是,去除RadioGroup默認自帶顯示的小圓圈。


 ③RadioButton的android:gravity屬性值為center。這個屬性值的意義是,使RadioButton的內容(圖片和文字)居中。注意,內容默認情況沒有居中。


 ④RadioGroup的android:orientation屬性值為horizontal。意為,水平布置其中的RadioButton。


 ⑤RadioButton的android:textColor屬性值為@color/radiobutton_color_selector,是一個顏色狀態選擇器。顏色狀態選擇器就是一個定義在res/color目錄
      下的xml文件,color目錄需要我們手動創建。顏色狀態選擇器的代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#f00" android:state_checked="true"/>
    <item android:color="#f00" android:state_pressed="true"/>
    <item android:color="#f00" android:state_selected="true"/>
 
    <!--沒被選中時的顏色-->
    <item android:color="#000"/>
 
</selector>

關於狀態選擇器的更詳細知識,請參考文章http://www.cnblogs.com/baipengzhan/p/6284682.html     

                  
RadioButton的android:background屬性值為@drawable/radiobutton_bg_selector,這一個背景狀態選擇器,用來改變背景顏色,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@color/radiobutton_bg_selected"/>
    <item android:state_checked="true" android:drawable="@color/radiobutton_bg_selected"/>
    <item android:state_pressed="true" android:drawable="@color/radiobutton_bg_selected"/>
 
    <!--未被選中-->
    <item android:drawable="@color/radiobutton_bg_normal" />
 
</selector>

這個狀態選擇器是放置在res/drawable目錄下的一個普通狀態選擇器,該選擇器的屬性android:drawable的屬性值不能直接設置顏色,
顏色要封裝在values目錄下的colors.xml文件中,否則出錯。


RadioButton的android:drawableTop屬性值為@drawable/radiobutton_pic_selector,是一個普通的狀態選擇器,用來改變圖片,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@mipmap/ic_selected"/>
    <item android:state_checked="true" android:drawable="@mipmap/ic_selected"/>
    <item android:state_pressed="true" android:drawable="@mipmap/ic_selected"/>
 
    <!--未被選中-->
    <item android:drawable="@mipmap/ic_launcher"/>
 
</selector>

該狀態選擇器同樣放置在res/drawable目錄下,選擇器的屬性值android:drawable屬性值變為了圖片,注意代碼寫到此處時,系統可能不會提示,
需要手動將該屬性值添加進來。
 
更多關於狀態選擇器的知識請參考文章http://www.cnblogs.com/baipengzhan/p/6284682.html 


創建出FrameLayout頁面盛放的Fragment 


我們創建出對應於四個RadioButton的四個Fragment,每個Fragment中盛放一個TextView。下邊只列出一個Fragment的寫法,剩余的相似,請各位朋友自己寫寫哦。

public class Fragment_1 extends Fragment {

    private View mView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //注意View對象的重復使用,以便節省資源
        if(mView == null) {
            mView = inflater.inflate(R.layout.fragment_1_layout,container,false);
        }

        return mView;
    }
}

Fragment_1對應的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!--創建TextView-->
    <TextView
        android:text="pager_1"
        android:textSize="28sp"
        android:textColor="#00f"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
 
</LinearLayout>

 

在Activity中進行主要邏輯處理


我們在Activity中主要進行的工作如下:
監聽RadioGroup中的RadioButton,改變FrameLayout中盛放的Fragment對象;

package com.example.radiogroup_framelayout;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private RadioGroup radioGroup;
    private RadioButton button_1;
    private RadioButton button_2;
    private RadioButton button_3;
    private RadioButton button_4;
    private Fragment_1 fragment_1;
    private Fragment_2 fragment_2;
    private Fragment_3 fragment_3;
    private Fragment_4 fragment_4;
    private List<Fragment> list;
    private FrameLayout frameLayout;

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

        //初始化頁面
        initView();
    }

    //初始化頁面
    private void initView() {
        frameLayout = (FrameLayout) findViewById(R.id.framelayout);
        radioGroup = (RadioGroup) findViewById(R.id.radioGroup);

        //找到四個按鈕
        button_1 = (RadioButton) findViewById(R.id.button_1);
        button_2 = (RadioButton) findViewById(R.id.button_2);
        button_3 = (RadioButton) findViewById(R.id.button_3);
        button_4 = (RadioButton) findViewById(R.id.button_4);

        //創建Fragment對象及集合
        fragment_1 = new Fragment_1();
        fragment_2 = new Fragment_2();
        fragment_3 = new Fragment_3();
        fragment_4 = new Fragment_4();

        //將Fragment對象添加到list中
        list = new ArrayList<>();
        list.add(fragment_1);
        list.add(fragment_2);
        list.add(fragment_3);
        list.add(fragment_4);

        //設置RadioGroup開始時設置的按鈕,設置第一個按鈕為默認值
        radioGroup.check(R.id.button_1);


        //設置按鈕點擊監聽
        button_1.setOnClickListener(this);
        button_2.setOnClickListener(this);
        button_3.setOnClickListener(this);
        button_4.setOnClickListener(this);

        //初始時向容器中添加第一個Fragment對象
        addFragment(fragment_1);
    }

    @Override
    public void finish() {
        ViewGroup viewGroup = (ViewGroup) getWindow().getDecorView();
        viewGroup.removeAllViews();
        super.finish();
    }

    //點擊事件處理
    @Override
    public void onClick(View v) {
        //我們根據參數的id區別不同按鈕
        //不同按鈕對應着不同的Fragment對象頁面
        switch (v.getId()) {
            case R.id.button_1:
                addFragment(fragment_1);
                break;
            case R.id.button_2:
                addFragment(fragment_2);
                break;
            case R.id.button_3:
                addFragment(fragment_3);
                break;
            case R.id.button_4:
                addFragment(fragment_4);
                break;
            default:
                break;
        }

    }

    //向Activity中添加Fragment的方法
    public void addFragment(Fragment fragment) {

        //獲得Fragment管理器
        FragmentManager fragmentManager = getSupportFragmentManager();
        //使用管理器開啟事務
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //使用事務替換Fragment容器中Fragment對象
        fragmentTransaction.replace(R.id.framelayout,fragment);
        //提交事務,否則事務不生效
        fragmentTransaction.commit();
    }



}

注意: 
以上代碼中很多可以優化,比如xml文件中大量的屬性可以提取樣式,等等,這里列出只是為了方便更多水平的讀者讀懂,請諒解。

其實Fragment對象的容器不止FrameLayout一種,只是這種結構容器對Fragment支持比較好,更為常用,各位小伙伴可以使用其他容器嘗試哦,原理是一樣的。

本方式利用動態添加Fragment對象到Activity中,其實我們也可以有個設想,使用靜態方法添加到容器中,各個Fragment相互重疊,只有一個顯示,我還沒嘗試,

今后有機會了可以這樣試一下,各位小伙伴可以試試哦。
 
好啦,FrameLayout + RadioGroup結構我們到此就講解完成了,感謝閱讀!  

   

  

  

  

  

  

 


免責聲明!

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



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