Android底部導航欄創建——ViewPager + RadioGroup


原創文章,引用請注明出處:http://www.cnblogs.com/baipengzhan/p/6270201.html                      

Android底部導航欄有多種實現方式,本文詳解其中的ViewPager + RadioGroup方式的實現步驟。

 

我們先來看以下看一下最終做出的效果,使大家有個基本概念。

 

本結構特點:

1,ViewPager部分觸摸左右滑動切換頁面,RadioGroup部分中的RadioButton隨着自己對應的ViewPager頁面出現選中時的狀態,包括改變背景顏色,

改變文字顏色,改變圖片。其他RadioButton則是未被選中時的狀態;

2,當用戶點擊RadioGroup部分中的RadioButton,被點擊的RadioButton出現被選中時的顏色,ViewPager界面對應於RadioButton的頁面會出現在當前界面。

 

可以看到,ViewPager和RadioGroup可以雙向聯動,不是單向傳遞。

 

下面我們通過一個實例完全弄懂ViewPager + RadioGroup結構的用法

 

首先創建出我們界面的布局,上邊一個ViewPager,中間 一條分隔線,下邊一個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"
>

<!--上邊為ViewPager-->

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
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>

 布局中重要屬性說明:

 ①ViewPager的android:layout_height屬性值為0,android:layout_weight屬性值為1。這兩個屬性值配合使用的意義是:

  在豎直方向上ViewPager占滿父控件的剩余空間,也就是占據LinearLayout中除去分隔線和RadioGroup的剩余空間。

  關於android:layout_weight屬性的詳細用法請參考:http://www.cnblogs.com/baipengzhan/p/Android_layout_weight.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  

 

創建出ViewPager頁面盛放的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中主要進行的工作如下:

①監聽ViewPager,改變RadioGroup中的RadioButton;

②監聽RadioGroup中的RadioButton,改變ViewPager;

 

代碼如下:

package com.example.chironmy.bottomnavigation;

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

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

public class MainActivity extends AppCompatActivity implements View.OnClickListener,ViewPager.OnPageChangeListener{

    private ViewPager viewPager;
    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;

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

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

    //初始化界面
    private void initView() {
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        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);

        //給viewPager設置適配器,以顯示內容
        MyViewPagerAdapter adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(adapter);

        //設置RadioGroup開始時設置的按鈕,設置第一個按鈕為默認值
        radioGroup.check(R.id.button_1);
        //設置Viewpager第一次顯示的頁面
        viewPager.setCurrentItem(0,true);


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

        //設置ViewPager頁面監聽
        viewPager.addOnPageChangeListener(this);

    }


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


    //創建ViewPager盛放Fragment的適配器類
    public class MyViewPagerAdapter extends FragmentPagerAdapter {

        public MyViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        //返回每個position對應的Fragment對象
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        //返回list的長度,也就是Fragment對象的個數
        @Override
        public int getCount() {
            return list.size();
        }
    }


    //處理點擊的方法
    @Override
    public void onClick(View v) {
        //我們根據參數的id區別不同按鈕
        //不同按鈕對應着不同的ViewPager頁面
        switch (v.getId()) {
            case R.id.button_1:
                viewPager.setCurrentItem(0,true);
                break;
            case R.id.button_2:
                viewPager.setCurrentItem(1,true);
                break;
            case R.id.button_3:
                viewPager.setCurrentItem(2,true);
                break;
            case R.id.button_4:
                viewPager.setCurrentItem(3,true);
                break;
            default:
                break;
        }

    }


    //處理頁面變化的方法
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    //本文章中我們使用這個方法,本方法處理頁面變化后,也就是切換了不同的頁面后所做的操作
    @Override
    public void onPageSelected(int position) {

        //根據當前展示的ViewPager頁面,使RadioGroup對應的按鈕被選中
        switch (position) {
            case 0:
                radioGroup.check(R.id.button_1);
                break;
            case 1:
                radioGroup.check(R.id.button_2);
                break;
            case 2:
                radioGroup.check(R.id.button_3);
                break;
            case 3:
                radioGroup.check(R.id.button_4);
                break;
            default:
                break;

        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

}

注意:在onClick方法中,viewPager的setCurrentItem方法中的第二個參數的意義是:

            當該參數為true時,viewPager換頁時是平滑的換頁,會有頁面移動的效果;

            該參數為false時,viewPager換頁效果沒有平滑的移動,頁面會直接出現。

            該方法有一個參數的重載方法,默認有平滑換頁效果。  

 

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

 

好啦,ViewPager + RadioGroup結構我們到此就講解完成了,感謝閱讀!

 

  

  


免責聲明!

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



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