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;
                }
            }
        });
    }
}

现在运行你的代码,就到看到开头图片显示的效果了。快去试试吧!

扫描二维码关注公众号,回复: 10797606 查看本文章

千里之行始于足下!

发布了34 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/q296264785/article/details/73275678