Android (FragmentTabHost+RadioGroup)實現底部bar

從java算起,自學android有一年了。從一開始的信息滿滿到現在的迷茫,不知道爲了啥?改行做android?根本沒底氣不自信。放棄?那我一年辛苦不是白費了?閒話不扯。

大部分的app底部都有一個導航欄,像微信,QQ。以前我都是自己用textView加一些亂七八糟的東西實現的,代碼耦合度高,實現繁雜,可複用性低。因爲基礎的東西學的差不多了,最近開始接觸一些簡單的項目,發現框架真的是個好東西。雖然起步更難,但是後期維護,代碼複用,橫向拓展都非常方便,秒殺我的山寨Bar……

這是我在一個開源項目中抽取出來的用FragmentTabHost+RadioGroup實現的底部Bar,分離出來方便以後查找。先上圖,沒圖說個啥?
這裏寫圖片描述

簡單說一下原理:底下3個按鈕是RadioGroup,FragmentTabHost通過setup方法關聯到主視圖(屏幕中最大那一塊),FragmentTabHost的addTab方法可以向FragmentTabHost中添加需要切換顯示的Fragment。然後在RadioGroup的事件監聽中就可以通過FragmentTabHost的setCurrentTab方法來切換顯示的Fragment.

Activity的佈局:

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

    <FrameLayout
        android:id="@+id/frameLayout_nr"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"></FrameLayout>

    <android.support.v4.app.FragmentTabHost
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"></android.support.v4.app.FragmentTabHost>

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/rbHome"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:drawablePadding="4dp"
            android:drawableTop="@drawable/home"
            android:gravity="center"
            android:text="主頁"
            android:textColor="@drawable/text"
            android:textSize="16sp" />

        <RadioButton
            android:id="@+id/rbMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawablePadding="4dp"
            android:drawableTop="@drawable/message"
            android:gravity="center"
            android:text="信息"
            android:textColor="@drawable/text"
            android:textSize="16sp" />

        <RadioButton
            android:id="@+id/rbProfile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawablePadding="4dp"
            android:drawableTop="@drawable/profile"
            android:gravity="center"
            android:text="我的"
            android:textColor="@drawable/text"
            android:textSize="16sp" />
    </RadioGroup>
</LinearLayout>

佈局中FrameLayout佈局是用來關聯給FragmentTabHost顯示內容的,就是上文中提到的屏幕中的最大塊。
FragmentTabHost不多說,需要注意的是其中android:visibility=”gone”,因爲FragmentTabHost本來是一個滑動塊的佈局,我們並不想要顯示滑動塊,所以把FragmentTabHost隱藏起來不顯示。爲什麼要放入一個組件缺隱藏起來呢?因爲我們要使用FragmentTabHost的一些方法,簡單來說就是能通過setCurrentTab方法來切換顯示我們事先關聯到FragmentTabHost中的一些Fragment.
再下來是一個RadioGroup,包含三個RadioButton,就是我們看到的底部的三個按鈕了。其中 android:drawableTop=”@drawable/profile”和
android:textColor=”@drawable/text”設置了按鍵顏色的切換:

圖片狀態切換

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/ic_tabbar_home_selected" android:state_checked="true"/>
    <item android:drawable="@mipmap/ic_tabbar_home_normal" android:state_checked="false"/>
</selector>

文字狀態切換

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#ffab00" android:state_checked="true"/>
    <item android:color="#000" android:state_checked="false"/>
</selector>

接下來我們還需要給三個RadioButton提供三個Fragment,只需要顯示一些簡單的東西能讓自己分辨界面已經切換了就可以,源碼不貼。

然後是Activity

public class MainActivity extends AppCompatActivity{
    private FrameLayout frameLayout_nr;
    private FragmentTabHost tabHost;
    private RadioGroup radioGroup;
    private Class fragments[];
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
        initialize();
    }
    private void initialize(){
        fragments = new Class[]{HomeFragment.class,MessageFragment.class,ProfileFragment.class};
        frameLayout_nr = (FrameLayout)findViewById(R.id.frameLayout_nr);
        tabHost = (FragmentTabHost) findViewById(R.id.tab);
        radioGroup = (RadioGroup) findViewById(R.id.radioGroup);

        tabHost.setup(getApplicationContext(),getSupportFragmentManager(),R.id.frameLayout_nr);  //tabHost關聯上下文,FragmentManager和顯示區域
        for (int i = 0; i < fragments.length ; i++) {   //向TabHost中添加fragment和標誌位
            TabHost.TabSpec tabSpec = tabHost.newTabSpec(String.valueOf(i)).setIndicator(String.valueOf(i));
            tabHost.addTab(tabSpec,fragments[i],null);
        }
        tabHost.setCurrentTab(0);//設置初始選中項
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId){
                    case R.id.rbHome:
                        tabHost.setCurrentTab(0);
                        break;
                    case R.id.rbMessage:
                        tabHost.setCurrentTab(1);
                        break;
                    case R.id.rbProfile:
                        tabHost.setCurrentTab(2);
                        break;
                }
            }
        });
    }
}

現在運行你的代碼,就到看到開頭圖片顯示的效果了。快去試試吧!

千里之行始於足下!

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