ViewPager三种使用方式

本文详细介绍了ViewPager的三种使用方式:1) 常规左右滑动;2) 自定义垂直滑动;3) 结合Fragment实现内容切换。通过实例代码展示了如何实现这些功能,包括自定义VerticalViewPager和不滑动的NoScrollViewPager,适用于不同场景的界面布局需求。

ViewPager就是每个Pager配置不同的View,通过左右滑动可以切换View。介绍几种我用过的ViewPager的用法。

一、常规用法

左右滑动的View,使用Adapter配置View即可。

页面xml代码

        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewPager1"
            android:layout_width="match_parent"
            android:background="#999999"
            android:layout_height="150dp"/>

viewPager的View里面就是放了一个TextView,adapter实现如下


public class RegularPagerAdapter extends PagerAdapter {
    private Context context;
    private List<String> dataList;

    public RegularPagerAdapter(Context context, List<String> datas) {
        this.context = context;
        this.dataList = datas;
    }

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

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

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//        super.destroyItem(container, position, object);必须删除,否则报错
        container.removeView((View) object);
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup viewGroup, int position) {
        ItemPagerRegularBinding binding = DataBindingUtil.bind(LayoutInflater.from(context).inflate(R.layout.item_pager_regular, viewGroup, false));
        binding.tvName.setText(dataList.get(position));
        viewGroup.addView(binding.getRoot());
        return binding.getRoot();
    }
}

activity中使用

    private void setRegularPager() {
        List<String> dataList = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            dataList.add("这是我的第" + (i + 1) + "个Pager");
        }
        RegularPagerAdapter adapter = new RegularPagerAdapter(this, dataList);
        mBinding.viewPager1.setAdapter(adapter);
    }

页面实现效果

 二、上下滑动的ViewPager

ViewPager默认的滑动方向是左右滑动,但是有时候需要实现上下滑动的方式。那就继承ViewPager实现一个VerticalViewPager。这个代码是在网上找的别人实现的,可以拿过来直接用。

public class VerticalViewPager extends ViewPager {

    public VerticalViewPager(Context context) {
        super(context);
        init();
    }

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

    private void init() {
        // 最重要的设置,将viewpager翻转
        setPageTransformer(true, new VerticalPageTransformer());
        // 设置去掉滑到最左或最右时的滑动效果
        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    private class VerticalPageTransformer implements PageTransformer {

        @Override
        public void transformPage(View view, float position) {

            if (position < -1) { // [-Infinity,-1)
                // 当前页的上一页
                view.setAlpha(0);

            } else if (position <= 1) { // [-1,1]
                view.setAlpha(1);

                // 抵消默认幻灯片过渡
                view.setTranslationX(view.getWidth() * -position);

                //设置从上滑动到Y位置
                float yPosition = position * view.getHeight();
                view.setTranslationY(yPosition);

            } else { // (1,+Infinity]
                // 当前页的下一页
                view.setAlpha(0);
            }
        }
    }

    /**
     * 交换触摸事件的X和Y坐标
     */
    private MotionEvent swapXY(MotionEvent ev) {
        float width = getWidth();
        float height = getHeight();

        float newX = (ev.getY() / height) * width;
        float newY = (ev.getX() / width) * height;

        ev.setLocation(newX, newY);

        return ev;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
        swapXY(ev);
        return intercepted; //为所有子视图返回触摸的原始坐标
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(swapXY(ev));
    }
}

我遇到的情况是,本来是写了个Recyclerview实现网格布局实现上下滑动,但是老板说要两排一组,一组一组的滑动,那不就是得改成ViewPager么!这个先上个效果图吧

上面每个小View放的数据是ItemBean,里面属性是name和resId。每个View还都可以点击,或者数据更新改变状态什么的,这个就是直接更新数据源,然后ViewPager的Adapter设置notifyDataSetChanged()即可。

viewPager的Adapter

public class CategoryPagerAdapter extends PagerAdapter {
    private Context context;
    private ArrayList<ArrayList<ItemBean>> datas;
    private int spanCount;
    private OnPageItemClickListener listener;


    public CategoryPagerAdapter(Context context, ArrayList<ArrayList<ItemBean>> datas, int spanCount, OnPageItemClickListener listener) {
        this.context = context;
        this.datas = datas;
        this.spanCount = spanCount;
        this.listener = listener;
    }

    public void updateData(ArrayList<ArrayList<ItemBean>> datas, int spanCount){
        this.datas.clear();
        this.datas.addAll(datas);
        this.spanCount = spanCount;
        notifyDataSetChanged();
    }

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

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

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//        super.destroyItem(container, position, object);必须删除,否则报错
        container.removeView((View) object);
    }

    @Override
    public int getItemPosition(@NonNull Object object) {
        return POSITION_NONE;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup viewGroup, int page) {
        ItemPagerCategoryBinding binding = DataBindingUtil.bind(LayoutInflater.from(context).inflate(R.layout.item_pager_category, viewGroup, false));

        //recyclerview设置网格布局
        GridLayoutManager gridLayoutManager = new GridLayoutManager(context, spanCount);
        binding.rvPager.setLayoutManager(gridLayoutManager);
        binding.rvPager.getItemAnimator().setChangeDuration(0);
        ItemAdapter buttonsAdapter = new ItemAdapter(context, datas.get(page), (position, bean) -> listener.onItemClick(page, position, bean));
        buttonsAdapter.setHasStableIds(true);
        binding.rvPager.setAdapter(buttonsAdapter);

        viewGroup.addView(binding.getRoot());
        return binding.getRoot();
    }


    public interface OnPageItemClickListener {
        void onItemClick(int page, int position, ItemBean bean);
    }
}

 页面xml

<com.example.myapplication.viewpager.VerticalViewPager
            android:id="@+id/viewPager2"
            android:layout_width="match_parent"
            android:layout_height="112dp"
            android:layout_marginTop="10dp"/>

activity使用

    private void setCategoryPager() {
        ArrayList<ArrayList<ItemBean>> dataList = getCategoryPagerData(8);
        CategoryPagerAdapter adapter = new CategoryPagerAdapter(this, dataList, 4, (page, position, bean) -> {
            Toast.makeText(this, "点击:"+bean.getName() +",位置:"+position,Toast.LENGTH_SHORT).show();
        });
        mBinding.viewPager2.setAdapter(adapter);
    }

    private ArrayList<ArrayList<ItemBean>> getCategoryPagerData(int pageCount) {
        ArrayList<ArrayList<ItemBean>> dataList = new ArrayList<>();//viewPager的数据源
        ArrayList<ItemBean> list = new ArrayList<>();//recyclerview的数据源
        list.add(new ItemBean("箱包", R.mipmap.icon_bag));
        list.add(new ItemBean("美妆", R.mipmap.icon_beauty));
        list.add(new ItemBean("图书", R.mipmap.icon_book));
        list.add(new ItemBean("电子", R.mipmap.icon_computer));
        list.add(new ItemBean("厨具", R.mipmap.icon_cooking));
        list.add(new ItemBean("饮品", R.mipmap.icon_drink));
        list.add(new ItemBean("水果", R.mipmap.icon_fruits));
        list.add(new ItemBean("医药", R.mipmap.icon_medicine));
        list.add(new ItemBean("母婴", R.mipmap.icon_mother_and_baby));
        list.add(new ItemBean("户外", R.mipmap.icon_outdoors));
        list.add(new ItemBean("鞋子", R.mipmap.icon_shoes));
        list.add(new ItemBean("女装", R.mipmap.icon_skirt));
        list.add(new ItemBean("小家电", R.mipmap.icon_small_appliances));
        list.add(new ItemBean("零食", R.mipmap.icon_snacks));
        list.add(new ItemBean("男装", R.mipmap.icon_t_shirt));
        list.add(new ItemBean("玩具", R.mipmap.icon_toys));
        list.add(new ItemBean("蔬菜", R.mipmap.icon_vegetables));
        list.add(new ItemBean("风车", R.mipmap.icon_windmill));
        int bSize = list.size();
        int pageSize = bSize / pageCount + (bSize % pageCount == 0 ? 0 : 1);
        for (int i = 0; i < pageSize; i++) {
            ArrayList<ItemBean> itemBeans = new ArrayList<>();
            int length = pageCount;
            if (pageCount > bSize - i * pageCount) {
                length = bSize - i * pageCount;
            }
            for (int j = i * pageCount; j < i * pageCount + length; j++) {
                itemBeans.add(list.get(j));
            }
            dataList.add(itemBeans);
        }
        return dataList;
    }

getCategoryPagerData(int pageCount)这是数据源处理,pageCount是一个ViewPager里面放几个小View,如果横竖屏切换这个pageCount和recyclerview的spanCount就需要修改,spanCount=PageCount/2。本来ArrayList<ItemBean> list是recyclerview的数据源,改成ArrayList<ArrayList<ItemBean>> dataList的ViewPager的数据源,根据pageCount把list放到dataList里面去。

当然,如果需要左右滑动的效果,直接使用ViewPager就可以了。

三、ViewPager+Fragment

很多分步骤或者分页的需求,都是顶部几个按钮,点击不同的按钮下面展示不同的按钮,如下图

 

 上面是RadioGroup,下面是ViewPager嵌套的Fragment。这种的ViewPager不需要左右滑动,可是写一个不滑动的NoScrollViewPager,Fragment里面一般放的是Recyclerview或者其他任何视图。这个也很简单,直接贴页面代码吧

xml

<?xml version="1.0" encoding="utf-8"?>
<layout>

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

        <RadioGroup
            android:id="@+id/rg_page"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:paddingHorizontal="20dp"
            android:orientation="horizontal">

            <RadioButton
                android:id="@+id/rb_config"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:gravity="center"
                android:button="@null"
                android:checked="true"
                android:background="@drawable/selector_check_btn"
                android:text="推荐"
                android:textSize="16dp"
                android:textColor="@drawable/text_button_checked"/>

            <RadioButton
                android:id="@+id/rb_image"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:layout_marginHorizontal="10dp"
                android:gravity="center"
                android:button="@null"
                android:background="@drawable/selector_check_btn"
                android:text="必囤"
                android:textSize="16dp"
                android:textColor="@drawable/text_button_checked"/>

            <RadioButton
                android:id="@+id/rb_video"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:gravity="center"
                android:button="@null"
                android:background="@drawable/selector_check_btn"
                android:text="好物"
                android:textSize="16dp"
                android:textColor="@drawable/text_button_checked"/>

        </RadioGroup>

        <com.example.myapplication.viewpager.NoScrollViewPager
            android:id="@+id/viewPager3"
            android:layout_marginTop="5dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/btn_create" />

    </LinearLayout>

</layout>

activity页面

    private PagerFragment fragment1;
    private PagerFragment fragment2;
    private PagerFragment fragment3;
    private List<Fragment> fgList;
    private void setFragmentPager(){
        fragment1 = new PagerFragment(1);
        fragment2 = new PagerFragment(2);
        fragment3 = new PagerFragment(3);
        fgList = new ArrayList<>();
        fgList.add(fragment1);
        fgList.add(fragment2);
        fgList.add(fragment3);

        mBinding.viewPager3.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return fgList.get(position);
            }

            @Override
            public int getCount() {
                return fgList.size();
            }
        });
        selectPage(0);
        mBinding.rgPage.setOnCheckedChangeListener((radioGroup, checkedId) -> {
            if (checkedId == mBinding.rbConfig.getId()){
                selectPage(0);
            }else if (checkedId == mBinding.rbImage.getId()){
                selectPage(1);
            }else if (checkedId == mBinding.rbVideo.getId()){
                selectPage(2);
            }
        });
    }

    private void selectPage(int index){
        mBinding.viewPager3.setCurrentItem(index, false);
    }

源码下载:(135条消息) AndroidviewPager的三种使用方式-Android文档类资源-优快云文库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值