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

效果图如下:

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()));
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,444评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,867评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,157评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,312评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,673评论 3 289
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,802评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,470评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,696评论 2 250
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,187评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,538评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,188评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,127评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,889评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,741评论 2 274

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,582评论 25 707
  • 内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新...
    皇小弟阅读 46,425评论 22 663
  • 近日亲妈使劲儿跟我无理取闹,闹得我很是心焦。 都是小事,当然都是小事。无非就是她为了省钱去超市买的散装米吃起来有霉...
    温柔寒江雪阅读 1,106评论 4 4
  • 当时看电影竟然没有爱上的 又回来了 Sally's song
    喃言阅读 230评论 0 0
  • ​模式名称:特邀嘉宾(Royal audience) 总结: 安排管理层、公司同事与受邀而来做专家推动的嘉宾(大人...
    from1to100阅读 212评论 0 0