RadioGroup的RadioButton简单用法——学习笔记

关于RadioButton,它的具体例子嘛,就好像是QQ啊、微信之类的app底部那几个按钮,不过他们是不是用RadioButton来实现的我不太清楚,但是RadioButton基本上就是这样的效果

接下来就接着上一篇来实现一下RadioButton吧,使用RadioButton必须在RadioGroup组件中。

首先,上一篇将MainActiviy主界面替换成ContentFragment后,现在要把ContentFragment的代码重新修改一下,以便于显示RadioButton,在此之前,先创建一个ContentFragment的布局文件吧。

布局文件——content_fragment.xml:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/content_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <RadioGroup
        android:id="@+id/rd_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_blue_dark"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/rd_news"
            android:text="新闻"
            android:drawableTop="@drawable/rb_news_drawable_selector"
            style="@style/button_tag_style"/>
        <RadioButton
            android:id="@+id/rd_weather"
            android:text="天气"
            android:drawableTop="@drawable/rb_weather_drawable_selector"
            style="@style/button_tag_style"/>
        <RadioButton
            android:id="@+id/rd_picture"
            android:text="图片"
            android:drawableTop="@drawable/rb_picture_drawable_selector"
            style="@style/button_tag_style"/>
        <RadioButton
            android:id="@+id/rd_vedio"
            android:text="视频"
            android:drawableTop="@drawable/rb_vedio_drawable_selector"
            style="@style/button_tag_style"/>
        <RadioButton
            android:id="@+id/rd_shopping"
            android:text="购物"
            android:drawableTop="@drawable/rb_shopping_drawable_selector"
            style="@style/button_tag_style"/>

    RadioGroup>

LinearLayout>

从上面的代码其实可以很明显的看到,RadioButton位于RadioGroup中,而RadioButton是配合ViewPager来使用的,每点击一个RadioButton,就切换另外一个页面,其中有几点需要注意的。

1.整个布局是放在LinearLayout中的,因为需要用到权重,也就是weight这个属性,所以最外层的布局是LinearLayout。

2.其实点开RadioGroup会看到【public class RadioGroup extends LinearLayout{…}】,这说明RadioGroup继承的LinearLayout,所以在RadioGroup的属性里面,需要设置方向,也就是orientation的设置,由于底部按钮是一横排,这里自然是设置水平方向horizontal了。

3.你会发现每一个RadioButton的属性设置只有短短几行代码,其实是因为每个RadioButton设置的属性,有一大部分是重复的,于是将些重复的部分写在了values下的style.xml中,比如一个RadioButton原来的代码是:

"@+id/rd_shopping"
            android:text="购物"
            android:drawableTop="@drawable/rb_shopping_drawable_selector"
            android:layout_height="wrap_content"
            android:layout_width="0dp"
            android:layout_gravity="center"
            android:textSize="14sp"
            android:gravity="center"
            android:button="@null"
            android:drawablePadding="4dp"
            android:textColor="@drawable/rb_text_drawable_selector"
            android:layout_weight="1"/>

除开前面三行,剩下的都是可以重复写的部分。
不过有几点需要注意:

1.android:drawableTop这条属性,是将图片或某个控件绘制在某组件的上部,这里是将RadioButton绘制在RadioGroup的上部,相当于覆盖。

2.android:button=”@null”这条属性,如果不加上这条属性,你会发现RadioButton旁边会有一个小圆圈按钮,看着蛋疼,加上这条属性用来将其隐藏。

然后将重复的部分写在style.xml中,接着引用即可,于是在style.xml中写如下代码:

其中android:textColor指定的是drawable下的rb_text_drawable_selector.xml文件,创建这个文件,具体的代码如下:


<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false" android:color="@android:color/black"/>
    <item android:state_checked="true" android:color="@android:color/white"/>
selector>

和这个布局内容相似的是每个RadioButton设置的android:drawableTop属性,比如说第一个RadioButton,id是android:id=”@+id/rd_news”,表示新闻按钮,它的drawableTop属性的布局文件是rb_news_drawable_selector.xml,具体代码如下:


<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false" android:drawable="@drawable/rb_news_black"/>
    <item android:state_checked="true" android:drawable="@drawable/rb_news_white"/>
selector>

关键点在于,这里指定的是否按下状态用的不是android:state_pressed=”false或者true”,而是使用的android:state_checked属性,这点十分重要,因为它是RadioButton!存在于一个RadioGroup中,所以用了选中——check,而不是按下——pressed。

基本上每一个RadioButton的android:drawableTop布局代码都一样,不同的只是选中和没选中这两种状态所用的图片。

接下来就是ContentFragment的具体代码了,如下:

public class ContentMenuFragment extends BaseFragment {


    private ViewPager content_viewpager;
    private RadioGroup rd_group;

    @Override
    public View initView() {
        LogUtil.e("主页面被初始化");
        View view = View.inflate(context, R.layout.content_fragment, null);
        content_viewpager = (ViewPager)view.findViewById(R.id.content_viewpager);
        rd_group = (RadioGroup)view.findViewById(R.id.rd_group);

        return view;
    }

    @Override
    public void initData() {
        super.initData();
        rd_group.check(R.id.rd_news);
        LogUtil.e("主页面数据被初始化");
    }
}

上面的代码中,有一点是需要注意的,那就是rd_group.check(R.id.rd_news),这里使用的check方法的作用是设置一个默认选中的RadioButton,这里传入的id是新闻按钮的id,就表示新闻按钮是被默认选中的。
最后来看一下运行界面:
RadioGroup的RadioButton简单用法——学习笔记_第1张图片
WTF?!!!
虚拟按键把按钮给挡住了,在网上找了一下解决这个问题的方法,解决办法就是在MainActivity的onCreate方法里面的setContentView()前添加这行代码:

     getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

再看一下运行界面——
RadioGroup的RadioButton简单用法——学习笔记_第2张图片

大概就是这么个点击效果~~
ps:找图片素材可花了不少时间!!!

不过这样明显是不行的,接下来可以给ViewPager加上页面,然后给每个按钮添加点击事件,用于切换页面,做完这些,RadioButton的使用效果才会更加明显。
首先,是添加页面,由于每一个按钮对应一个页面,所以要创建五个页面,不过这五个页面当中,每一个的布局都有重复的部分,比如标题栏就需要重复写五遍,为了减少这类麻烦,可以和之前创建基类Fragment一样,为页面写一个基类布局,接下来就是这个基类——BasePager的代码:

public class BasePager {

    //都要写成public,不然子类无法调用
    public final Context context;
    public Toolbar toolbar;
    public TextView title_text;
    public CircleImageView menu_circle_image;
    public FrameLayout base_content_fl; //用来加载各个不同的子页面

    public View rootView; //代表各个不同子页面的视图

    //构造方法
    public BasePager(Context context){
        this.context = context;
        rootView = initView();
    }

    public View initView(){
        View view = View.inflate(context, R.layout.base_pager, null);
        toolbar = (Toolbar) view.findViewById(R.id.base_title_toolbar);
        title_text = (TextView) view.findViewById(R.id.title_text);
        menu_circle_image = (CircleImageView) view.findViewById(R.id.menu_circle_image);
        base_content_fl = (FrameLayout) view.findViewById(R.id.base_content_fl);
        menu_circle_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity mainActivity = (MainActivity) context;
                mainActivity.getSlidingMenu().toggle();
            }
        });
        return view;
    }

    public void initData(){
    }
}

上面的代码中,初始化了一个圆形图片,并且为这个图片添加了点击事件,用来替代标题栏的导航按钮,代码中还写了一个rootView,如果A页面继承了这个BasePager,那么A的视图就用A的rootView来表示,所以rootView的作用是方便调用。
使用圆形化图片需要添加依赖:

compile 'de.hdodenhof:circleimageview:2.1.0'

下面是BasePager的布局base_pager.xml的代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <include layout="@layout/titlebar"/>

    <FrameLayout
        android:id="@+id/base_content_fl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

LinearLayout>

上面的布局中,将标题的布局代码抽出来放入了titlebar.xml中,然后include进来,不过这一步不是必须的,下面是标题栏的布局:


<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/base_title_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@android:color/holo_blue_dark"
    android:theme="@style/ThemeOverlay.AppCompat.Light"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

        <TextView
            android:id="@+id/title_text"
            android:text="标题"
            android:layout_gravity="center"
            android:textSize="20sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/menu_circle_image"
            android:src="@drawable/huaji1"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            android:layout_width="45dp"
            android:layout_height="wrap_content"/>

android.support.v7.widget.Toolbar>

标题栏使用的是ToolBar,里面插入了一个TextView用于显示标题,以及一个圆形化图片用于装逼。
基本上BasePager算是布局完成了,然后创建五个页面,分别对应每一个RadioButton,每一个页面代码几乎一样,下面是其中NewsPager的代码:

public class NewsPager extends BasePager {
    public NewsPager(Context context) {
        super(context);
    }

    @Override
    public void initData() {
        super.initData();
        title_text.setText("新闻");

        TextView textView = new TextView(context);
        textView.setText("我是新闻页面");
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(30);
        textView.setTextColor(Color.RED);

        base_content_fl.addView(textView);//添加视图
    }
}

五个页面创建完成后,自然是要添加到ContentFragment对应布局中的ViewPager中,然后给ViewPager设置适配器,用于将五个页面绑定到ViewPager上,接下来顺便给每个RadioButton设置点击事件,用来切换页面,下面是ContentFragment的代码:

public class ContentMenuFragment extends BaseFragment {


    private ViewPager content_viewpager;
    private RadioGroup rd_group;
    private ArrayList pagers;

    @Override
    public View initView() {
        LogUtil.e("主页面被初始化");
        View view = View.inflate(context, R.layout.content_fragment, null);
        content_viewpager = (ViewPager)view.findViewById(R.id.content_viewpager);
        rd_group = (RadioGroup)view.findViewById(R.id.rd_group);


        return view;
    }

    @Override
    public void initData() {
        super.initData();
        LogUtil.e("主页面数据被初始化");
        rd_group.check(R.id.rd_news);
        pagers = new ArrayList<>();
        pagers.add(new NewsPager(context));
        pagers.add(new WeatherPager(context));
        pagers.add(new PicturePager(context));
        pagers.add(new VedioPager(context));
        pagers.add(new ShoppingPager(context));


        content_viewpager.setAdapter(new ContentFragmentAdapter());
        rd_group.setOnCheckedChangeListener(new MyOnCheckedChangeListener());
    }

    class MyOnCheckedChangeListener implements RadioGroup.OnCheckedChangeListener{

        @Override
        public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
            switch (checkedId){
                case R.id.rd_news:
                    content_viewpager.setCurrentItem(0, false);
                    isEnableScroll(SlidingMenu.TOUCHMODE_FULLSCREEN);
                    break;
                case R.id.rd_weather:
                    content_viewpager.setCurrentItem(1, false);
                    isEnableScroll(SlidingMenu.TOUCHMODE_NONE);
                    break;
                case R.id.rd_picture:
                    content_viewpager.setCurrentItem(2, false);
                    isEnableScroll(SlidingMenu.TOUCHMODE_NONE);
                    break;
                case R.id.rd_vedio:
                    content_viewpager.setCurrentItem(3, false);
                    isEnableScroll(SlidingMenu.TOUCHMODE_NONE);
                    break;
                case R.id.rd_shopping:
                    content_viewpager.setCurrentItem(4, false);
                    isEnableScroll(SlidingMenu.TOUCHMODE_NONE);
                    break;
                default:

            }
        }
    }

    private void isEnableScroll(int tochMode){
        MainActivity mainActivity = (MainActivity) context;
        mainActivity.getSlidingMenu().setTouchModeAbove(tochMode);
    }

    class ContentFragmentAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            return pagers.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            BasePager pager = pagers.get(position);
            pager.initData();
            View rootView = pager.rootView;
            container.addView(rootView);
            return rootView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}

上面的代码中,为了防止点击页面出现的滑动动画,所以setCurrentItem第二个参数设置为false;并且,为了防止每个页面的SlidingMenu都能滑动从而覆盖掉ViewPager的滑动事件,只在新闻页面设置了能滑动SlidingMenu;同时需要注意,在ViewPager的适配器中的instantiateItem方法里面,绑定页面的同时需要调用页面的InitData方法,这样才能显示文字,否则initData中的TextView就白设置了。
下面是运行效果:
RadioGroup的RadioButton简单用法——学习笔记_第3张图片

但是还有很多问题没有处理!比如状态栏颜色的问题,按钮能切换页面但是滑动页面却无法切换按钮等等,颜色状态的问题下次再解决,先来看一下切换页面却无法改变对应按钮状态的情况:
RadioGroup的RadioButton简单用法——学习笔记_第4张图片

先解决掉切换切换页面时对应的滑动页面却无法切换这个问题,其实很简单,既然可以通过按钮来切换页面,那就没必要再设置滑动切换页面的功能了,只需要将滑动时间屏蔽就行。
因为这里使用的是ViewPager,所以只需要再创建一个类让其继承ViewPager,同时在该类中解决滑动问题,然后把ContentFragment中的ViewPager和布局中的ViewPager全替换成这个类即可,于是创建一个叫NoScrollViewPager的类:

public class NoScrollViewPager extends ViewPager {


    public NoScrollViewPager(Context context) {
        super(context);
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }
}

上面的类中,除了必须重写的两个构造方法之外,还重写了onTouch()方法和onInterceptTouchEvent()方法,其中onInterceptTouchEvent()是ViewGroup提供的方法,返回false表示不拦截事件,而onTouch()是View提供的方法,返回true表示消耗掉事件。这样,就不会有滑动效果了。

接下来,是如何更改顶部状态栏的问题,其实如果是在继承了AppcompatActivity的Activity中倒是好修改,不过这些布局都是和Fragment相关联的,找了一天的办法,目前只有一个能用,而且颜色要自己去设置,并不是自动去填充或者自己变透明什么的。现在来介绍一下方法:

首先,在res目录下创建一个values-v21目录,然后在这个目录下创建styles.xml文件,如果android的API版本在21以上会自动去加载这个文件,否则加载values文件下的styles.xml。接着在values-v21文件里的styles中设置:



其中第一条可以让虚拟按键不去遮挡底部的布局,第二条就是设置顶部系统状态栏的颜色,如果把这个属性设置成@android:color/transparent表示设置成透明状态,但是不知道为什么这么设置后效果是这样的
RadioGroup的RadioButton简单用法——学习笔记_第5张图片

显示出来的图片顶部全是白色的,由于文章背景是白色的,所以看起来好像没了,但其实非常蛋疼!!使用这条属性的同时我也试过在根布局加上了 android:fitsSystemWindows=”true”这条属性,不过依旧没有效果,最后干脆把颜色设置成和标题栏一样的颜色,不过与此同时,还需要在values下的styles.xml中添加如下代码:

<style name="MainActivityTheme" parent="Theme.AppCompat.Light.NoActionBar">
    style>

这样API版本不到21的时候会加载这个文件,之所以这样设置是因为android:statusBarColor这条属性只在API21及以上才会生效。
最后看一下效果吧:
RadioGroup的RadioButton简单用法——学习笔记_第6张图片

如果有哪位大牛有更好的设计方法,请务必告诉我,找了一天了,最后还是用的书上面的方法,真是崩溃!!!

你可能感兴趣的:(学习笔记)