安卓ViewPager+RadioGroup实现多组图片滑动展示(每组图片不定量)

  • Post author:
  • Post category:其他



应公司项目需要,写了一个图集查看的功能,要求图片有分组,确定为6组,但是每个分组中图片的数量不确定,可多可少根据接口请求的数据来定,整个图集分组前后衔接,左右滑动可以查看所有图片,滑动到对应分组的图片,底部组别自动定位,点击组别可以切换至对应位置的图片,同时图片底下有几行文字主要是对每组图片的描述,所以随着组别的切换而改变,草图如下:




拿到这样的需求以后,我初步确定了实现方案,即用viewpager+radiogroup,因为上边要有滑动的效果而底部要有点选的效果,至于分组的问题,需要将适配给viewpager的图片集合的数据源分为6个并且记录下来每个集合的size,以便在合适的位置设置切换或者定位。


布局的代码:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    tools:context="com.millionideas.tc_show.show.ShowPicListActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center">
                <android.support.v4.view.ViewPager
                    android:id="@+id/vp_sp"
                    android:layout_width="match_parent"
                    android:layout_height="250dp"
                    android:layout_marginTop="20dp"
                    android:background="@color/line_gray" >
                </android.support.v4.view.ViewPager>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:textColor="@color/text_gray_aa"
                    android:layout_marginLeft="20dp"
                    android:layout_marginTop="20dp"
                    android:layout_marginRight="20dp"
                    android:text="场景介绍场景介绍场景介绍场景介绍场景介绍场景介绍场景介绍场景介绍场景介绍场景介绍"
                    android:id="@+id/tv_sp_description" />
            </LinearLayout>
        </LinearLayout>
        <RadioGroup
            android:id="@+id/rg_sp"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:orientation="horizontal"
            android:layout_marginLeft="@dimen/magin_left_large"
            android:layout_marginRight="@dimen/magin_left_large">
            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="主卧室"
                android:id="@+id/radioButton1"
                android:layout_weight="1"
                style="@style/myradio"
                android:tag="0"/>

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="客厅"
                android:id="@+id/radioButton2"
                android:layout_weight="1"
                style="@style/myradio"
                android:tag="1"/>

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="厨"
                android:id="@+id/radioButton3"
                android:layout_weight="1"
                style="@style/myradio"
                android:tag="2"/>

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="卫"
                android:id="@+id/radioButton4"
                android:layout_weight="1"
                style="@style/myradio"
                android:tag="3"/>

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="书房"
                android:id="@+id/radioButton5"
                android:layout_weight="1"
                style="@style/myradio"
                android:tag="4"/>

            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="茶坊"
                android:id="@+id/radioButton6"
                android:layout_weight="1"
                style="@style/myradio"
                android:tag="5"/>
        </RadioGroup>
    </LinearLayout>
</RelativeLayout>


布局的代码没有什么需要讲的主要就是几个控件的摆放,但是有一个地方需要特别注意,就是每一个RadioButton都需要给设置一个tag,这样在代码中方便根据tag来获取RadioButton的位置。


核心代码如下:


/**
 * Created by itBobby on 2016/7/28.
 */
@ContentView(R.layout.activity_show_piclist)
public class ShowPicListActivity extends BaseActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {
    @ViewInject(R.id.vp_sp)
    ViewPager vp_sp;
    @ViewInject(R.id.rg_sp)
    RadioGroup rg_sp;
    @ViewInject(R.id.tv_sp_description)
    TextView tv_sp_description;
    @ViewInject(R.id.radioButton1)
    RadioButton radioButton1;
    @ViewInject(R.id.radioButton2)
    RadioButton radioButton2;
    @ViewInject(R.id.radioButton3)
    RadioButton radioButton3;
    @ViewInject(R.id.radioButton4)
    RadioButton radioButton4;
    @ViewInject(R.id.radioButton5)
    RadioButton radioButton5;
    @ViewInject(R.id.radioButton6)
    RadioButton radioButton6;

    private List<ImageView> allimageViews;//图片总集合,API中返回的分组图片集合需要全部添加进来再适配给viewpager
    int badroom_size, livingroom_size, cookhouse_size, restroom_size, schoolroom_size, tearoom_size;//记录每个分组图片的张数
    private List<ImageView> imageViews1, imageViews2, imageViews3, imageViews4, imageViews5, imageViews6;//分组图片集合

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        setPic();//初始化图片方法,这里添加的是假数据,等API返回数据后再实际添加
        vp_sp.setAdapter(pagerAdapter);//给viewpager适配数据
        setPage();//因为上一页有六个入口,所以点击不同入口进入本页时需要有定位
        rg_sp.setOnCheckedChangeListener(this);//radiobutton设置选中监听
        vp_sp.addOnPageChangeListener(this);//viewpager设置页面切换监听
    }

    PagerAdapter pagerAdapter = new PagerAdapter() {//viewpager适配器
        @Override
        public int getCount() {
            return allimageViews.size();
        }

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

        @Override
        public Object instantiateItem(View arg0, final int arg1) {
            ImageView imageView = allimageViews.get(arg1);
            ((ViewPager) arg0).addView(imageView);//将所有的图片添加到view中
            return allimageViews.get(arg1);
        }

        @Override
        public void destroyItem(View arg0, int arg1, Object arg2) {
            ((ViewPager) arg0).removeView((View) arg2);
        }
    };

    public void setPage() {
        switch (getIntent().getStringExtra("type")) {//根据上一页跳转传过来的intent值进行定位
            case "bedroom":
                setCurrentItem(0);//此处的setCurrentItem是自定义的方法,该方法中调用了viewpager的setCurrentItem方法,参数为type对应六个分组
                initRadiobuttonColor(radioButton1);//该方法为初始化radiobutton的字体颜色,选中的radiobutton要和其余的颜色不同
                break;
            case "livingroom":
                setCurrentItem(1);
                initRadiobuttonColor(radioButton2);
                break;
            case "cookhouse":
                setCurrentItem(2);
                initRadiobuttonColor(radioButton3);
                break;
            case "restroom":
                setCurrentItem(3);
                initRadiobuttonColor(radioButton4);
                break;
            case "schoolroom":
                setCurrentItem(4);
                initRadiobuttonColor(radioButton5);
                break;
            case "tearoom":
                setCurrentItem(5);
                initRadiobuttonColor(radioButton6);
                break;
        }
    }

    public void initRadiobuttonColor(RadioButton button) {
        button.setTextColor(getResources().getColor(R.color.text_yellow));//设置RadioButton字体颜色为黄色
    }

    /*viewpager的setCurrentItem方法可以将pager定位到某一页,这里根据每个分组中图片个数的不同,页数会随之发生变化,所以用来记录每个分组图片的张数
    * 的变量此时便能排上用场了*/
    public void setCurrentItem(int type) {
        switch (type) {
            case 0:
                vp_sp.setCurrentItem(0);
                tv_sp_description.setText("主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;");
                break;
            case 1:
                vp_sp.setCurrentItem(badroom_size);//由于viewpager的索引是从0开始的,所以第二个分组就是从第一个分组数量长度的位置开始,后边以此类推
                tv_sp_description.setText("客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;");
                break;
            case 2:
                vp_sp.setCurrentItem(badroom_size + livingroom_size);
                tv_sp_description.setText("厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;");
                break;
            case 3:
                vp_sp.setCurrentItem(badroom_size + livingroom_size + cookhouse_size);
                tv_sp_description.setText("卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;");
                break;
            case 4:
                vp_sp.setCurrentItem(badroom_size + livingroom_size + cookhouse_size + restroom_size);
                tv_sp_description.setText("书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;");
                break;
            case 5:
                vp_sp.setCurrentItem(badroom_size + livingroom_size + cookhouse_size + restroom_size + schoolroom_size);
                tv_sp_description.setText("茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;");
                break;
        }
    }

    public void setPic() {
        int num[] = {1, 2, 3, 3, 2, 1};//这里指定了每个分组图片的数量,用数组方便随时更改进行测试
        imageViews1 = new ArrayList<ImageView>();
        for (int i = 0; i < num[0]; i++) {
            ImageView imageView = new ImageView(ShowPicListActivity.this);
            imageView.setImageResource(R.mipmap.temp_pic1);//指定图片资源
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);//设置图片显示属性,CENTER_CROP指按比例扩大图片的size并居中显示
            imageViews1.add(imageView);
        }
        badroom_size = imageViews1.size();//记录下图片个数

        imageViews2 = new ArrayList<ImageView>();
        for (int i = 0; i < num[1]; i++) {
            ImageView imageView = new ImageView(ShowPicListActivity.this);
            imageView.setImageResource(R.mipmap.temp_pic2);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews2.add(imageView);
        }
        livingroom_size = imageViews2.size();

        imageViews3 = new ArrayList<ImageView>();
        for (int i = 0; i < num[2]; i++) {
            ImageView imageView = new ImageView(ShowPicListActivity.this);
            imageView.setImageResource(R.mipmap.temp_pic3);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews3.add(imageView);
        }
        cookhouse_size = imageViews3.size();

        imageViews4 = new ArrayList<ImageView>();
        for (int i = 0; i < num[3]; i++) {
            ImageView imageView = new ImageView(ShowPicListActivity.this);
            imageView.setImageResource(R.mipmap.temp_pic4);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews4.add(imageView);
        }
        restroom_size = imageViews4.size();

        imageViews5 = new ArrayList<ImageView>();
        for (int i = 0; i < num[4]; i++) {
            ImageView imageView = new ImageView(ShowPicListActivity.this);
            imageView.setImageResource(R.mipmap.temp_pic5);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews5.add(imageView);
        }
        schoolroom_size = imageViews5.size();

        imageViews6 = new ArrayList<ImageView>();
        for (int i = 0; i < num[5]; i++) {
            ImageView imageView = new ImageView(ShowPicListActivity.this);
            imageView.setImageResource(R.mipmap.temp_pic6);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews6.add(imageView);
        }
        tearoom_size = imageViews6.size();

        allimageViews = new ArrayList<ImageView>();
        allimageViews.addAll(imageViews1);
        allimageViews.addAll(imageViews2);
        allimageViews.addAll(imageViews3);
        allimageViews.addAll(imageViews4);
        allimageViews.addAll(imageViews5);
        allimageViews.addAll(imageViews6);
    }

    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int i) {
        RadioButton r = (RadioButton) radioGroup.findViewById(i);
        for (int i1 = 0; i1 < rg_sp.getChildCount(); i1++) {//当一个radiobutton被选中的时候设置所有颜色为灰
            ((RadioButton) rg_sp.getChildAt(i1)).setTextColor(getResources().getColor(R.color.text_gray_aa));
        }
        initRadiobuttonColor(r);//再设置选中的radiobutton为黄色,以此达到选中效果
    }

    /*当viewpager进行左右滑动的时候并不代表滑动一页就是一个分组,而要根据分组图片的张数进行判断,
    * 在同一个分组中切换图片,底部的radiobutton不切换,只有当该分组图片浏览结束以后才会进入下一个分组,
    * 此时底部radiobutton跟随切换,而radiobutton切换的位置受position影响
    * 所以要根据position来设定区间(position是根据pager页变化的,向右切换一个pager也就是一张图片,position就加1)
    * 只有六个分组,radiobutton切换六次,position只能有0-5六个值,否则就会报异常,
    * 所以当position在一个范围内时就要给它重新赋值*/
    @Override
    public void onPageSelected(int position) {
        Log.e("onPageSelected--1", position + "");
        if (position < badroom_size) {//分组1的区间
            position = 0;
            initRadiobuttonColor(radioButton1);//同时选中的radiobutton设置颜色
            tv_sp_description.setText("主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;主卧室 场景介绍;");
        } else if (badroom_size <= position && position < badroom_size + livingroom_size) {//分组2的区间
            position = 1;
            initRadiobuttonColor(radioButton2);
            tv_sp_description.setText("客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;客厅 场景介绍;");
        } else if (badroom_size + livingroom_size <= position && position < badroom_size + livingroom_size + cookhouse_size) {//分组3的区间
            position = 2;
            initRadiobuttonColor(radioButton3);
            tv_sp_description.setText("厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;厨房 场景介绍;");
        } else if (badroom_size + livingroom_size + cookhouse_size <= position && position < badroom_size + livingroom_size + cookhouse_size + restroom_size) {//分组4的区间
            position = 3;
            initRadiobuttonColor(radioButton4);
            tv_sp_description.setText("卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;卫生间 场景介绍;");
        } else if (badroom_size + livingroom_size + cookhouse_size + restroom_size <= position && position < badroom_size + livingroom_size + cookhouse_size + restroom_size + schoolroom_size) {//分组5的区间
            position = 4;
            initRadiobuttonColor(radioButton5);
            tv_sp_description.setText("书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;书房 场景介绍;");
        } else if (badroom_size + livingroom_size + cookhouse_size + restroom_size + schoolroom_size <= position) {//分组6的区间
            position = 5;
            initRadiobuttonColor(radioButton6);
            tv_sp_description.setText("茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;茶坊 场景介绍;");
        }
        ((RadioButton) rg_sp.getChildAt(position)).setChecked(true);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /*这里的事件绑定和上边的控件绑定使用了xutils中的依赖注入*/
    @Event(value = {R.id.radioButton1, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4, R.id.radioButton5, R.id.radioButton6}, type = View.OnClickListener.class)
    private void onClick(View view) {
        switch (view.getId()) {
            case R.id.radioButton1:
                setCurrentItem(0);//给radiobutton设置点击事件实现点击分类切换至对应图片位置的效果
                break;
            case R.id.radioButton2:
                setCurrentItem(1);
                break;
            case R.id.radioButton3:
                setCurrentItem(2);
                break;
            case R.id.radioButton4:
                setCurrentItem(3);
                break;
            case R.id.radioButton5:
                setCurrentItem(4);
                break;
            case R.id.radioButton6:
                setCurrentItem(5);
                break;
        }
    }
}


以上代码中我写了大量的注释,所以这里就不再赘述了,至此预期的效果就已经实现了:


欢迎交流讨论!



版权声明:本文为u012193089原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。