Android使用ViewPager实现图片的轮播

2023-11-06

一.概述

在现在的Android项目中,首页图片轮播是随处可见的,今天我们看看如何实现,先看效果图:

这里写图片描述

二.实现

先给大家看看最简单的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="300dp">
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
        <RadioGroup
            android:id="@+id/group"
            android:layout_gravity="center_horizontal|bottom"
            android:layout_width="wrap_content"
            android:layout_marginBottom="10dp"
            android:orientation="horizontal"
            android:layout_height="wrap_content">
        </RadioGroup>
    </FrameLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        >
        <Button
            android:id="@+id/start"
            android:layout_width="wrap_content"
            android:onClick="click"
            android:text="开始自动轮播"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:onClick="click"
            android:text="停止自动轮播"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>

上面一个FrameLayout包裹着一个ViewPager和一个RadioGroup,注意这个RadioGroup我们还没有为其添加按钮,因为我们的按钮的个数是根据图片个数确定的,我们不知道图片有多少张,因为实际项目中图片都是从服务器获取来的。最下面是两个按钮,用于控制是否自动轮播。

接下来我们看看按钮的样式,这里的按钮我们使用了ImageView,背景我们使用了选择器。
当你要为一个图片设置选择器作为背景的话,使用下面的代码:

 imageview.setImageResource(R.drawable.rg_selector);

我们来看看这个选择器是如何写的,

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:drawable="@drawable/rb_default"/>
    <item android:state_enabled="true" android:drawable="@drawable/rb_select"/>
</selector>

这里我们设置了按钮选中和没有选中时的样式,下面我们看看分别是如何定义的:

//选中时样式rb_default
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >
    <solid android:color="@android:color/holo_blue_bright"/>
   <size android:height="20dp" android:width="20dp"/>
</shape>
//未选中样式rb_select
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >
    <solid android:color="@android:color/white"/>
    <size android:height="20dp" android:width="20dp"/>
</shape>

和xml布局文件有关的我们就介绍完了,下面看看java代码如何实现:

public class MainActivity extends Activity {
    private ViewPager viewPager;
    private RadioGroup group;
    //图片资源
    private int[] imageIds = {R.drawable.ym1,R.drawable.ym2,R.drawable.ym3,R.drawable.ym4};
    //存放图片的数组
    private List<ImageView> mList;
    //当前索引位置以及上一个索引位置
    private int index = 0,preIndex = 0;
    //是否需要轮播标志
    private boolean isContinue = true;
    //定时器,用于实现轮播
    private Timer timer;
     Handler mHandler  = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 1:
                    index++;
                    System.out.println("==========index: "+index);
                        viewPager.setCurrentItem(index);
                    }
            }
    };
    private Button btnStart;
    private Button btnStop;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        group = (RadioGroup) findViewById(R.id.group);
        mList = new ArrayList<>();
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(onPageChangeListener);
        viewPager.setOnTouchListener(onTouchListener);
        btnStart = (Button) findViewById(R.id.start);
        btnStop = (Button) findViewById(R.id.stop);
        initRadioButton(imageIds.length);
        btnStop.setEnabled(false);
    }
    public void click(View view){
        switch (view.getId()){
            case R.id.start:
                timer = new Timer();//创建Timer对象
                //执行定时任务
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        //首先判断是否需要轮播,是的话我们才发消息
                        if (isContinue) {
                            mHandler.sendEmptyMessage(1);
                        }
                    }
                },2000,2000);//延迟2秒,每隔2秒发一次消息
                btnStart.setEnabled(false);
                btnStop.setEnabled(true);
                break;
            case R.id.stop:
                timer.cancel();
                btnStart.setEnabled(true);
                btnStop.setEnabled(false);
                break;
        }
    }

    /**
     * 根据图片个数初始化按钮
     * @param length
     */
    private void initRadioButton(int length) {
        for(int i = 0;i<length;i++){
            ImageView imageview = new ImageView(this);
            imageview.setImageResource(R.drawable.rg_selector);//设置背景选择器
            imageview.setPadding(20,0,0,0);//设置每个按钮之间的间距
            //将按钮依次添加到RadioGroup中
            group.addView(imageview, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            //默认选中第一个按钮,因为默认显示第一张图片
            group.getChildAt(0).setEnabled(false);
        }
    }

    /**
     * 根据当前触摸事件判断是否要轮播
     */
    View.OnTouchListener onTouchListener  = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()){
                //手指按下和划动的时候停止图片的轮播
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                    isContinue = false;
                    break;
                default:
                    isContinue = true;
            }
            return false;
        }
    };
    /**
     *根据当前选中的页面设置按钮的选中
     */
    ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }
        @Override
        public void onPageSelected(int position) {
           index = position;//当前位置赋值给索引
            setCurrentDot(index%imageIds.length);
        }
        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };

    /**
     * 设置对应位置按钮的状态
     * @param i 当前位置
     */
    private void setCurrentDot(int i) {
        if(group.getChildAt(i)!=null){
            group.getChildAt(i).setEnabled(false);//当前按钮选中
        }
        if(group.getChildAt(preIndex)!=null){
            group.getChildAt(preIndex).setEnabled(true);//上一个取消选中
            preIndex = i;//当前位置变为上一个,继续下次轮播
        }
    }
    PagerAdapter pagerAdapter = new PagerAdapter() {
        @Override
        public int getCount() {
            //返回一个比较大的值,目的是为了实现无限轮播
            return Integer.MAX_VALUE;
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            position = position%imageIds.length;
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setImageResource(imageIds[position]);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            container.addView(imageView);
            mList.add(imageView);
            return imageView;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(mList.get(position));
        }
    };
}

由于注释写的还是比较详细的,我就不仔细讲了,大家有不懂的地方可以给我留言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android使用ViewPager实现图片的轮播 的相关文章

随机推荐

  • 自制Web桌面日历

    想要一个带农历的桌面日历 google了半天也没有找到中意的 但是经常浏览网站的时候发现很多不错的日历 直接保存到我的桌面上不就完了吗 下面是具体操作 将中意的日历页面 查看源文件 看是否可以看到script文件 如果可以 就保存到本地 用
  • 【雕爷学编程】Arduino动手做(202)---热释电效应、热释电元件与HC-SR505运动传感器模块

    37款传感器与模块的提法 在网络上广泛流传 其实Arduino能够兼容的传感器模块肯定是不止37种的 鉴于本人手头积累了一些传感器和执行器模块 依照实践出真知 一定要动手做 的理念 以学习和交流为目的 这里准备逐一动手试试多做实验 不管成功
  • vba中find方法查找1

  • QML ListView实现树形效果

    转自 http blog huati365 com 5jELjzLwnx3YGw import QtQuick 2 11 import QtQuick Controls 2 2 import QtQuick Controls Materia
  • Android抓包工具——Fiddler

    前言 在平时和其他大佬交流时 总会出现这么些话 抓个包看看就知道哪出问题了 抓流量啊 payload都在里面 这数据流怎么这么奇怪 这里出现的名词 其实都是差不多的意思啊 这都跟抓包这个词有关 说到抓包呢我们今天就先来了解一下抓包的一些基础
  • MySQL组成

    MySQL 的组成分为两部分 服务器端 服务的提供 相当于卖家 客户端 服务的使 相当于买家 消费者 服务器端只能有一个 而客户端可以有多个 安装了 MySQL 说明我们既是服务器端又是客户端 服务器端的服务体现就是 客户端是使 MySQL
  • 微软亚洲研究院实习生面试

    上周说到微软亚洲研究院 MSRA 一下就简称MSRA吧 网络面试我这边因为连不上而要重新安排面试 周五HR就给我电话约好今天中午1 00 3 00重新面试 于是提前做好各种准备 找了个拉ADSL的宿舍来上网 然后用了人家带摄像头的笔记本 还
  • B站创建视频分集播放列表

    上传视频在B站上创建视频分集列表方法 上传时创建分集列表 1 打开B站 2 登录B站后 点击投稿上传视频 3 上传视频或把视频直接拖拽到页面里 4 点击上传第一个视频后页面下会出现一个 号的按钮 点击 继续上传 上传视频就会出现两个正在上传
  • 浅谈 Node.js 热更新

    大厂技术 高级前端 Node进阶 点击上方 程序员成长指北 关注公众号 回复1 加入高级Node交流群 记得在 15 16 年那会 Node js 刚起步的时候 我在去前东家的入职面试也被问到了要如何实现 Node js 服务的热更新 其实
  • Tuple VS ValueTuple(元组类 VS 值元组)

    Tuple VS ValueTuple 元组类 VS 值元组 文章目录 Tuple VS ValueTuple 元组类 VS 值元组 Tuple 1 创建元组 2 表示一组数据 3 从方法返回多个值 4 用于单参数方法的多值传递 缺点 Va
  • 基于php的课程网站络管理系统的设计与实现

    摘 要 管理系统是根据课程网站的需求而设计和实现的 主要 用于实现课程系统办公人员对其办公系统内所有公务员进行管理 实现对员工信息的查询 录入 修改和删除 以及发布重要通知 最新信息和规章制度 通过 网上办公 无纸办公 大大提高办公效率 体
  • 电脑关机了,内存就没数据了吗?

    前言 大家好 我是周杰伦 提到网络攻击技术 你脑子里首先想到的是什么 是DDoS 是SQL注入 XSS 还是栈溢出 RCE 远程代码执行 这些最常见的网络攻击技术 基本上都是与网络 软件 代码 程序这些东西相关 这也好理解 计算机网络安全
  • Qt项目实战 杂谈一二:中文乱码事情小,处理不好头发少

    Qt开发者来说 特别是初学者 往往最头疼的是编码的问题 举个例子 1 控件上设置中文标签 发现显示出来是乱码 怎么解决 如果标签是常量字符串 含中文 怎么处理 如果标签是变量 且可能包含字符串 又咋处理 2 Qt应用与其他应用存在进程间交互
  • 浏览器无法打开网页,报错:DNS_PROBE_FINISHED_BAD_CONFIG

    症状 手机的正常上网 电脑连不上网 浏览器打不开网页 电脑 用ping命令不能发现主机 这时判断DNS解析有问题 用ping命令能发现主机 这时判断DNS解析没有问题 解决办法 方案1 ipconfig flushdns 方案2 ping
  • openwrt 软件安装依赖冲突

    今天在安装一个插件curl 安装失败了 报错内容如下 root R619AC co router tmp tmp opkg install curl Installing curl 7 68 0 1 to root Downloading
  • 使用react-markdown与markdown-navbar实现在线浏览markdown文件并自动生成侧边导航栏目录(react项目)

    使用react markdown与markdown navbar实现在线浏览markdown文件并自动生成侧边导航栏目录 react项目 在项目中需要一个需求 需要将markdown文件放在react前端项目中实现浏览器在线浏览 修改mar
  • Python爬虫框架Scrapy实例(爬取腾讯社招信息并保存为excel)

    前言 在学习python爬虫的时候 曾经爬取过腾讯社招的网站 很久很久没有写爬虫 心血来潮打算爬一个练手 想起之前爬过腾讯社招网站 打开一看网页变了 行动 重新写一遍 这个网站相对简单 做了简单测试没有设置反爬 比较适合初学者拿来练手 搜索
  • 利用webhook实现发送通知到Slack

    概要 最近办公交流应用 Slack在各团队里大行其道 非常火热 今天我们就来说说怎么用他的incoming webhook来做一些同步通知 发送通知给Slack 我们先来看看这种incoming webhook来发送通知的优势 团队成员可以
  • Vulhub Apache HTTPD 换行解析漏洞

    漏洞介绍 漏洞原理 运维人员为了解决 Apache 解析漏洞 会使用 配置 来限制匹配到的最后一个扩展名 这种方式虽然对多个扩展名的解析漏洞进行了防护 但是因为 的正则匹配规则可以将 php n 的扩展名同样可以匹配到 php 的规则 产生
  • Android使用ViewPager实现图片的轮播

    一 概述 在现在的Android项目中 首页图片轮播是随处可见的 今天我们看看如何实现 先看效果图 二 实现 先给大家看看最简单的布局文件