android轮播图入门1——简单无限自动轮播图

目标

目标是实现一个简单的轮播图,特征如下:

  • 只展示本地图片
  • 可以无限轮播,在第一帧时也可以向前轮播
  • 可以自动轮播

code

先上代码,需要事先准备几张本地图片当素材

MainActivity:

package com.example.loopapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;

import com.example.loopapplication.looper.LooperPagerAdapter;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private ViewPager mViewPager;
    private LooperPagerAdapter mLooperPagerAdapter;
    private List<Integer> mPictures = new ArrayList<>();

    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 初始化数据
        mPictures.add(R.mipmap.pic1);
        mPictures.add(R.mipmap.pic2);
        mPictures.add(R.mipmap.pic3);
        mPictures.add(R.mipmap.pic4);
        mPictures.add(R.mipmap.pic5);
        mPictures.add(R.mipmap.pic6);
        // 初始化视图
        initView();
    }

    private void initView() {
        // 找到控件
        mViewPager = this.findViewById(R.id.loop_pager);
        // 创建适配器
        mLooperPagerAdapter = new LooperPagerAdapter();
        // 控件设置适配器
        mViewPager.setAdapter(mLooperPagerAdapter);
        // 适配器设置数据
        mLooperPagerAdapter.setData(mPictures);
        // 设置数据之后要通知轮播图数据已经更新
        mLooperPagerAdapter.notifyDataSetChanged();
        // 将一开始的轮播组件序号设置为较大值,可以做到在第一帧向前滑动
        mViewPager.setCurrentItem(mLooperPagerAdapter.getDataSize() * 100);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        // 展示到屏幕上时,开始自动轮播
        mHandler.post(mLoopTask);
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // 不展示在屏幕上时,比如切后台,关闭自动轮播
        mHandler.removeCallbacks(mLoopTask);
    }

    private Runnable mLoopTask = new Runnable() {
        @Override
        public void run() {
            int currentItems = mViewPager.getCurrentItem();
            // 将当前组件序号自增,达到自动轮播的效果
            mViewPager.setCurrentItem(++currentItems);
            // 自动轮播间隔1秒
            mHandler.postDelayed(this, 1000);
        }
    };
}

LooperPagerAdapter

package com.example.loopapplication.looper;

import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;

import java.util.List;

public class LooperPagerAdapter extends PagerAdapter {
    private List<Integer> mPictures = null;

    /**
     * 获取轮播组件的个数,返回多少就可以滑动多少次
     *
     * @return
     */
    @Override
    public int getCount() {
        if (mPictures != null) {
            // 设置为整型的最大值 近似于无限滑动
            return Integer.MAX_VALUE;
        }
        return 0;
    }

    /**
     * 判断当前轮播组件是否是视图
     *
     * @param view   Page View to check for association with <code>object</code>
     * @param object Object to check for association with <code>view</code>
     * @return
     */
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    /**
     * 初始化轮播组件
     *
     * @param container The containing View in which the page will be shown.
     * @param position  The page position to be instantiated.
     * @return
     */
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        // 需要将当前的位置取余 得到数据数组里真实的位置
        int realPosition = position % mPictures.size();

        ImageView imageView = new ImageView(container.getContext());
        imageView.setImageResource(mPictures.get(realPosition));
        container.addView(imageView);
        return imageView;
    }

    /**
     * 销毁轮播组件
     *
     * @param container The containing View from which the page will be removed.
     * @param position  The page position to be removed.
     * @param object    The same object that was returned by
     *                  {@link #instantiateItem(View, int)}.
     */
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }

    /**
     * 业务层设置轮播图数据
     *
     * @param pictures
     */
    public void setData(List<Integer> pictures) {
        this.mPictures = pictures;
    }

    /**
     * 获取轮播图数据数量
     * @return
     */
    public int getDataSize() {
        if (mPictures != null) {
            return mPictures.size();
        }
        return 0;
    }
}

视图xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/loop_pager"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="轮播图!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

基本的轮播图实现不加赘述,这里仅记录下如何实现轮播图的一些功能 

无限轮播

想要做到无限轮播,说明这个轮播图要有无限的轮播组件,这样才能一直轮播下去。

    @Override
    public int getCount() {
        if (mPictures != null) {
            // 设置为整型的最大值 近似于无限滑动
            return Integer.MAX_VALUE;
        }
        return 0;
    }

改写getCount方法,返回的数值就是轮播图的组件数量,我们设置为int的最大值,视作无限多。

这样会带来一个问题,我们的数据数组只有6个,当轮播超过6次之后怎么绑定正确的数据呢?需要在instantiateItem里做处理,通过取余操作获取数据在数组里的真实位置。

    /**
     * 初始化轮播组件
     *
     * @param container The containing View in which the page will be shown.
     * @param position  The page position to be instantiated.
     * @return
     */
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        // 需要将当前的位置取余 得到数据数组里真实的位置
        int realPosition = position % mPictures.size();

        ImageView imageView = new ImageView(container.getContext());
        imageView.setImageResource(mPictures.get(realPosition));
        container.addView(imageView);
        return imageView;
    }

另外还有一个问题,就是我们希望轮播图一开始可以往左滑动,而不是只能向右滑动,这样可以给用户一种无限循环的感觉。

因此在视图初始化时,应该手动给轮播图当前的组件设定一个足够大的值,使得用户可以不断地向左滑。

        // 将一开始的轮播组件序号设置为较大值,可以做到在第一帧向前滑动
        mViewPager.setCurrentItem(mLooperPagerAdapter.getDataSize() * 100);

 需要注意,设定的值需要是数据数组长度的倍数,这样才能定位到第一个轮播组件。

自动轮播

自动定时轮播可以通过Handler的延时方式实现,首先要明确,在用户不可见的情况要停止自动轮播,因此要在上屏/移出屏幕时做处理。

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        // 展示到屏幕上时,开始自动轮播
        mHandler.post(mLoopTask);
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // 不展示在屏幕上时,比如切后台,关闭自动轮播
        mHandler.removeCallbacks(mLoopTask);
    }

在每个时间间隔自增轮播图的组件号,就可以实现自动轮播了。

    private Runnable mLoopTask = new Runnable() {
        @Override
        public void run() {
            int currentItems = mViewPager.getCurrentItem();
            // 将当前组件序号自增,达到自动轮播的效果
            mViewPager.setCurrentItem(++currentItems);
            // 自动轮播间隔1秒
            mHandler.postDelayed(this, 1000);
        }
    };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/757107.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1-Pandas是什么

Pandas是什么 Pandas 是一个开源的第三方 Python 库&#xff0c;从 Numpy 和 Matplotlib 的基础上构建而来&#xff0c;享有数据分析“三剑客之一”的盛名&#xff08;NumPy、Matplotlib、Pandas&#xff09;。Pandas 已经成为 Python 数据分析的必备高级工具&#xff0c;它的…

nginx 1024 worker_connections are not enough while connecting to upstream

现象 请求api响应慢&#xff0c;甚至出现504 gateway timeout&#xff0c;重启后端服务不能恢复&#xff0c;但重启nginx可以恢复。 解决方案 worker_connections使用了默认值 1024&#xff0c;当流量增长时&#xff0c;导致连接不够 在nginx.conf中修改连接数就可以了&…

pg_rman:备份和恢复管理工具#postgresql培训

pg_rman 是 PostgreSQL 的在线备份和恢复工具。 pg_rman 项目的目标是提供一种与 pg_dump 一样简单的在线备份和 PITR 方法。此外&#xff0c;它还为每个数据库集群维护一个备份目录。用户只需一个命令即可维护包括存档日志在内的旧备份。 #PG培训#PG考试#postgresql考试#pos…

基于Spring Boot与Vue的智能房产匹配平台+文档

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐&#xff1a;最热的500个选题…

深度解析:机器学习如何助力GPT-5实现语言理解的飞跃

文章目录 文章前言机器学习在GPT-5中的具体应用模型训练与优化机器翻译与跨语言交流&#xff1a;情感分析与问答系统&#xff1a;集成机器学习功能&#xff1a;文本生成语言理解任务适应 机器学习对GPT-5性能的影响存在的挑战及解决方案技术细节与示例 文章前言 GPT-5是OpenAI公…

【教学类65-04】20240625秘密花园涂色书04(通义万相)(图纸16:9,A4横板1张,一大168张纸168份)

背景需求 【教学类65-01】20240622秘密花园涂色书01&#xff08;通义万相&#xff09;&#xff08;A4横版2张&#xff0c;一大3小 38张纸76份&#xff09;-CSDN博客文章浏览阅读118次。【教学类65-01】20240622秘密花园涂色书01&#xff08;通义万相&#xff09;&#xff08;A…

ValidateAntiForgeryToken、AntiForgeryToken 防止CSRF(跨网站请求伪造)

用途&#xff1a;防止CSRF&#xff08;跨网站请求伪造&#xff09;。 用法&#xff1a;在View->Form表单中: aspx&#xff1a;<%:Html.AntiForgeryToken()%> razor&#xff1a;Html.AntiForgeryToken() 在Controller->Action动作上&#xff1a;[ValidateAntiForge…

AI复活亲人市场分析:技术、成本与伦理挑战

“起死回生”这种事&#xff0c;过去只存在于科幻电影里&#xff0c;但今年&#xff0c;被“复活”的案例却越来越多。 2月底&#xff0c;知名音乐人包晓柏利用AI“复活”了她的女儿&#xff0c;让她在妈妈生日时唱了一首生日歌&#xff1b;3月初&#xff0c;商汤科技的年会上…

windows 10 安装tcping 使用教程

1 官网下载:tcping下载 2 复制tcping 到win10系统目录C:\Windows\System32 3 tcping 网址测试,可以指定端口 4 tcping 测试端口联通 5 tcping http模式

JFreeChart 生成Word图表

文章目录 1 思路1.1 概述1.2 支持的图表类型1.3 特性 2 准备模板3 导入依赖4 图表生成工具类 ChartWithChineseExample步骤 1: 准备字体文件步骤 2: 注册字体到FontFactory步骤 3: 设置图表具体位置的字体柱状图&#xff1a;饼图&#xff1a;折线图&#xff1a;完整代码&#x…

实验2 色彩模式转换

1. 实验目的 ①了解常用的色彩模式&#xff0c;理解色彩模式转换原理&#xff1b; ②掌握Photoshop中常用的颜色管理工具和色彩模式转换方法&#xff1b; ③掌握使用Matlab/PythonOpenCV编程实现色彩模式转换的方法。 2. 实验内容 ①使用Photoshop中的颜色管理工具&#xff…

如何高效安全的开展HPC数据传输,保护数据安全?

高性能计算&#xff08;HPC&#xff09;在多个行业和领域中都有广泛的应用&#xff0c;像科学研究机构、芯片IC设计企业、金融、生物制药、能源、航天航空等。HPC&#xff08;高性能计算&#xff09;环境中的数据传输是一个关键环节&#xff0c;它涉及到将数据快速、安全地在不…

淘宝扭蛋机小程序开发:为消费者带来新的潮玩乐趣

在当下的消费市场&#xff0c;潮玩消费已经成为了年轻人的新宠&#xff0c;预计在近几年间潮玩市场的销售额将达到千亿元&#xff01;其中扭蛋机市场更是吸引了各个阶段的消费群体&#xff0c;在市场巨大的发展前景下&#xff0c;同时也吸引了众多投资者入局&#xff0c;市场竞…

linux普通: rocketmq的安装测试与可视化界面安装,git的 (linux) 安装

全文目录,一步到位 1.前言简介1.2 常规mq对比1.3 专栏传送门(rabbitmq) 2. rocketmq使用及安装2.0 开放端口2.1 rocketmq版本说明2.2 具体操作2.2.1 修改文件2.2.2 具体启动指令ps: 查看日志 2.3.3 jps查看java进程2.3.4 测试运行情况> 步骤一: 临时指定nameserver注册中心位…

Ai中式吐槽漫画项目,Stable Diffusion自动生成漫画,10分钟一个原创

一、AI中式吐槽漫画&#xff1a;释放情绪的新途径 年轻人的生活充斥着工作、学习和家庭的压力&#xff0c;我们迫切需要一种方式来释放这些负面情绪。AI中式吐槽漫画&#xff0c;以其幽默诙谐的方式&#xff0c;将生活中的烦恼和压力转化为一幅幅引人发笑的漫画&#xff0c;不…

[OtterCTF 2018]General Info

基本信息要求查找ip 和主机名 查看 hivelist volatility.exe -f .\OtterCTF.vmem --profileWin7SP1x64 hivelist 0xfffff8a000024010 0x000000002d50c010 \REGISTRY\MACHINE\SYSTEM打印出注册表信息 volatility.exe -f .\OtterCTF.vmem --profileWin7SP1x64 printkey -o 0xff…

汽车电子工程师入门系列——AUTOSAR通信服务框架(上)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

Java 基本数据类型【基础篇】

目录 Java 数据类型基本数据类型整数类型【byte、short、int、long】浮点类型【float、double】布尔类型【boolean】字符类型【char】 引用数据类型 Java 数据类型 Java 语言支持的数据类型分为两种&#xff1a;基本数据类型 和 引用数据类型。其数据类型结构如下图所示&#x…

【计算机毕业设计】基于微信小程序的电子购物系统的设计与实现【源码+lw+部署文档】

包含论文源码的压缩包较大&#xff0c;请私信或者加我的绿色小软件获取 免责声明&#xff1a;资料部分来源于合法的互联网渠道收集和整理&#xff0c;部分自己学习积累成果&#xff0c;供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

Java基础知识-集合类

1、HashMap 和 Hashtable 的区别&#xff1f; HashMap 和 Hashtable是Map接口的实现类&#xff0c;它们大体有一下几个区别&#xff1a; 1. 继承的父类不同。HashMap是继承自AbstractMap类&#xff0c;而HashTable是继承自Dictionary类。 2. 线程安全性不同。Hashtable 中的方…