美文网首页
Android中ViewPager的基本用法:图片轮播小案例

Android中ViewPager的基本用法:图片轮播小案例

作者: ldlywt | 来源:发表于2016-10-08 21:37 被阅读4375次

    效果图如下:

    viewpager.gif

    xml布局文件

    <?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"
        tools:context="com.example.myapplication.MainActivity">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="230dp">
    
        </android.support.v4.view.ViewPager>
    
        <LinearLayout
            android:layout_alignBottom="@id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:background="#77000000"
            android:padding="5dp"
            android:gravity="center_horizontal"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/tv_image_desc"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="16sp"
                android:textColor="#bbffffff"
                android:text="我是图片描述信息"/>
        </LinearLayout>
    </RelativeLayout>
    

    代码的实现


    工程结构如下图

    工程结构.png

    第一步:初始化数据

    /**
     *初始化数据
     */
    //初始化图片轮播的图片
    private void initData() {
        int[] imageResIDs = {
                R.mipmap.a,
                R.mipmap.b,
                R.mipmap.c,
                R.mipmap.d,
                R.mipmap.e
        };
        mImageList = new ArrayList<>();
        ImageView iv;
        for (int i = 0; i < imageResIDs.length; i++) {
            iv = new ImageView(this);
            iv.setBackgroundResource(imageResIDs[i]);
            mImageList.add(iv);
            
            //初始化显示每张图片下面现实的文字
            imageDescs= new String[]{
                    "今年二十七八岁,我最喜欢的事就是睡觉",
                    "懒虫,起床了,要上班了",
                    "我翻了个身,想着如果今天是周末多好",
                    "终于爬起来,坐在沙发上一脸懵逼",
                    "一个人早餐就随便吃点"
            };
        }
    }
    

    第二步:设置viewpager适配器

        /**
        *新建一个adapter包,新建适配类如下
        */
    public class MyPagerAdapter extends PagerAdapter {
        private List<ImageView> imageList;
        private ViewPager viewPager;
    
        public MyPagerAdapter(List<ImageView> imageList, ViewPager viewPager) {
            this.imageList = imageList;
            this.viewPager = viewPager;
        }
    
        /**
         * 返回的int的值, 会作为ViewPager的总长度来使用.
         */
        @Override
        public int getCount() {
            return Integer.MAX_VALUE;//Integer.MAX_VALUE伪无限循环
        }
    
        /**
         * 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    
        /**
         * 初始化一个条目
         * position 就是当前需要加载条目的索引
         */
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // 把position对应位置的ImageView添加到ViewPager中
            ImageView iv = imageList.get(position % imageList.size());
            viewPager.addView(iv);
            // 把当前添加ImageView返回回去.
            return iv;
        }
    
        /**
         * 销毁一个条目
         * position 就是当前需要被销毁的条目的索引
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // 把ImageView从ViewPager中移除掉
            viewPager.removeView(imageList.get(position % imageList.size()));
        }
    }
    

    第三步:给viewpager设置轮播监听器

    /**
     * 当ViewPager页面被选中时, 触发此方法.
     * @param position 当前被选中的页面的索引
     */
    @Override
    public void onPageSelected(int position) {
        //伪无限循环,滑到最后一张图片又从新进入第一张图片
        int newPosition = position % mImageList.size();
    
        // 把当前选中的点给切换了, 还有描述信息也切换
        mTvImageDesc.setText(imageDescs[newPosition]);//图片下面设置显示文本
    
        // 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
        previousPosition = newPosition;
    }
    
    @Override
    public void onPageScrollStateChanged(int state) {
    
    }
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
    }
    

    第四步:设置刚打开app时显示的图片和文字

    /**
     * 设置刚进入app时,显示的图片和文字
     */
    private void setFirstLocation() {
        mTvImageDesc.setText(imageDescs[previousPosition]);
        // 把ViewPager设置为默认选中Integer.MAX_VALUE / 2,从十几亿次开始轮播图片,达到无限循环目的;
        int m = (Integer.MAX_VALUE / 2) % mImageList.size();
        int currentPosition = Integer.MAX_VALUE / 2 - m;
        mViewPager.setCurrentItem(currentPosition);
    }
    

    第五步: 设置自动播放,每隔3秒换一张图片

    /**
     * 每隔3秒自动播放图片
     */
    private void autoPlayView() {
        //自动播放图片
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (!isStop){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
                        }
                    });
                    SystemClock.sleep(3000);
                }
            }
        }).start();
    }
    

    第六步: 当Activity销毁时取消图片自动播放

    /**
     *当Activity销毁时取消图片自动播放
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        isStop = true;
    }
    

    细节问题处理

    如果发现左边图片的索引是负数, 小于0, 就不会预加载.
    如果发现右边的图片是索引是大于等于总图片的个数,也不会预加载. 例如:总图片是:5, 右边的图片是第6张。

    图片无限循环实现

    1.设置是适配器返回的长度为Integer的最大值
    @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }
    2.将position设置为如下
    //伪无限循环,滑到最后一张图片又从新进入第一张图片
        int newPosition = position % mImageList.size();
    

    附上全部的代码

    MainActiviy

    public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener{
    
        @BindView(R.id.view_pager)
        ViewPager mViewPager;
        @BindView(R.id.tv_image_desc)
        TextView mTvImageDesc;
        private List<ImageView> mImageList;
        private String[] imageDescs;
        private int previousPosition = 0; // 前一个被选中的position
        private boolean isStop = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ButterKnife.bind(this);
            initView();
            autoPlayView();
    
    
        }
    
        /**
         * 第五步: 设置自动播放,每隔3秒换一张图片
         */
        private void autoPlayView() {
            //自动播放图片
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (!isStop){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
                            }
                        });
                        SystemClock.sleep(3000);
                    }
                }
            }).start();
        }
    
        private void initView() {
            initData();
            MyPagerAdapter mAdapter = new MyPagerAdapter(mImageList, mViewPager);
            mViewPager.setAdapter(mAdapter);//第二步:设置viewpager适配器
            mViewPager.addOnPageChangeListener(this);
            setFirstLocation();
        }
    
        /**
         * 第四步:设置刚打开app时显示的图片和文字
         */
        private void setFirstLocation() {
            mTvImageDesc.setText(imageDescs[previousPosition]);
            // 把ViewPager设置为默认选中Integer.MAX_VALUE / 2,从十几亿次开始轮播图片,达到无限循环目的;
            int m = (Integer.MAX_VALUE / 2) % mImageList.size();
            int currentPosition = Integer.MAX_VALUE / 2 - m;
            mViewPager.setCurrentItem(currentPosition);
        }
    
        /**
         * 第一步:初始化数据
         */
        //初始化图片轮播的图片
        private void initData() {
            int[] imageResIDs = {
                    R.mipmap.a,
                    R.mipmap.b,
                    R.mipmap.c,
                    R.mipmap.d,
                    R.mipmap.e
            };
            mImageList = new ArrayList<>();
            ImageView iv;
            for (int i = 0; i < imageResIDs.length; i++) {
                iv = new ImageView(this);
                iv.setBackgroundResource(imageResIDs[i]);
                mImageList.add(iv);
    
                //初始化显示每张图片下面现实的文字
                imageDescs= new String[]{
                        "今年二十七八岁,我最喜欢的事就是睡觉",
                        "懒虫,起床了,要上班了",
                        "我翻了个身,想着如果今天是周末多好",
                        "终于爬起来,坐在沙发上一脸懵逼",
                        "一个人早餐就随便吃点"
                };
            }
        }
    
    
        /**
         * 第三步:给viewpager设置轮播监听器
         * viewpager的监听器
         * 当ViewPager页面被选中时, 触发此方法.
         * @param position 当前被选中的页面的索引
         */
        @Override
        public void onPageSelected(int position) {
            //伪无限循环,滑到最后一张图片又从新进入第一张图片
            int newPosition = position % mImageList.size();
    
            // 把当前选中的点给切换了, 还有描述信息也切换
            mTvImageDesc.setText(imageDescs[newPosition]);//图片下面设置显示文本
    
            // 把当前的索引赋值给前一个索引变量, 方便下一次再切换.
            previousPosition = newPosition;
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
    
        }
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
        }
        
        /**
         * 第六步: 当Activity销毁时取消图片自动播放
         */
        @Override
        protected void onDestroy() {
            super.onDestroy();
            isStop = true;
        }
    }
    

    MyPagerAdapter

    public class MyPagerAdapter extends PagerAdapter {
        private List<ImageView> imageList;
        private ViewPager viewPager;
    
        public MyPagerAdapter(List<ImageView> imageList, ViewPager viewPager) {
            this.imageList = imageList;
            this.viewPager = viewPager;
        }
    
        /**
         * 返回的int的值, 会作为ViewPager的总长度来使用.
         */
        @Override
        public int getCount() {
            return Integer.MAX_VALUE;//Integer.MAX_VALUE伪无限循环
        }
    
        /**
         * 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    
        /**
         * 初始化一个条目
         * position 就是当前需要加载条目的索引
         */
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // 把position对应位置的ImageView添加到ViewPager中
            ImageView iv = imageList.get(position % imageList.size());
            viewPager.addView(iv);
            // 把当前添加ImageView返回回去.
            return iv;
        }
    
        /**
         * 销毁一个条目
         * position 就是当前需要被销毁的条目的索引
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // 把ImageView从ViewPager中移除掉
            viewPager.removeView(imageList.get(position % imageList.size()));
        }
    }

    相关文章

      网友评论

          本文标题:Android中ViewPager的基本用法:图片轮播小案例

          本文链接:https://www.haomeiwen.com/subject/toxpyttx.html