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();@Overrideprotected 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);}@Overridepublic void onAttachedToWindow() {super.onAttachedToWindow();// 展示到屏幕上时,开始自动轮播mHandler.post(mLoopTask);}@Overridepublic void onDetachedFromWindow() {super.onDetachedFromWindow();// 不展示在屏幕上时,比如切后台,关闭自动轮播mHandler.removeCallbacks(mLoopTask);}private Runnable mLoopTask = new Runnable() {@Overridepublic 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*/@Overridepublic 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*/@Overridepublic 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@Overridepublic 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)}.*/@Overridepublic 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.ViewPagerandroid:id="@+id/loop_pager"android:layout_width="match_parent"android:layout_height="200dp"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><TextViewandroid: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>

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

无限轮播

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

    @Overridepublic 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@Overridepublic 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的延时方式实现,首先要明确,在用户不可见的情况要停止自动轮播,因此要在上屏/移出屏幕时做处理。

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】——链表经典OJ(leetcode)

文章目录 一、 相交链表二、 反转链表三、 回文链表四、 环形链表五、 环形链表 II六、 合并两个有序链表七、 两数相加八、 删除链表的倒数第N个节点九、 随机链表的复制 一、 相交链表 双指针法 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListN…

day02-Spark集群及参数

一、Spark运行环境变量问题(了解) 1-pycharm远程开发运行时&#xff0c;执行的是服务器的代码 2-通过本地传递指令到远程服务器运行代码时&#xff0c;会加载对应环境变量数据&#xff0c;加载环境变量文件是用户目录下的.bashrc文件 在/etc/bashrc 1-1 在代码中添加 使用os模块…

Python 算法交易实验74 QTV200第二步(改): 数据清洗并写入Mongo

说明 之前第二步是打算进入Clickhouse的&#xff0c;实测下来有一些bug 可以看到有一些分钟数据重复了。简单分析原因&#xff1a; 1 起异步任务时&#xff0c;还是会有两个任务重复的问题&#xff0c;这个在同步情况下是不会出现的2 数据库没有upsert模式。clickhouse是最近…

mysql GROUP_CONCAT函数详解

文章目录 概要使用技巧1. 建表、插入数据2.以id分组&#xff0c;把age字段的值拼成一行&#xff0c;逗号分隔(默认)3.以id分组&#xff0c;把age字段的值拼成 一行&#xff0c;分号分隔4.以id分组&#xff0c;把去冗余的age字段的值打印在一行5.以id分组&#xff0c;把age字段的…

算法:链表题目练习

目录 链表的技巧和操作总结 常用技巧&#xff1a; 链表中的常用操作 题目一&#xff1a;反转一个单链表 题目二&#xff1a;链表的中间结点 题目三&#xff1a;返回倒数第k个结点 题目四&#xff1a;合并两个有序链表 题目五&#xff1a;移除链表元素 题目六&#xff…

利用LLM本身训练SoTA embedding模型

今天分享一篇Microsoft公司的一篇文章&#xff0c;Title: Improving Text Embeddings with Large Language Models&#xff1a;使用大语言模型改善文本嵌入。 这篇文章探索了直接利用LLM来做embedding模型&#xff0c;其只需要利用合成数据和少于1000次的训练步骤就能获得高质…

语言模型:文本表征词嵌入技术调研

1 文本表征 文本表征是自然语言处理中的关键部分&#xff0c;尤其在当前大模型快速发展的背景下。由于大模型存在知识有限、处理文本长度有限、保密要求和大模型幻觉等问题&#xff0c;结合外部数据显得尤为重要。 为了便于存储和检索&#xff0c;除了保存纯文本外&#xff0…

Debug 调试代码

我们使用 debug 的目的, 认为就是查看代码的执行过程的。 步骤&#xff1a; 1. 打断点 断点的意义是, debug 运⾏的时候, 代码会在断点处停下来不执行如果是想要查看代码的执行过程, 建议将断点放在第⼀行在代码 和 行号之间 点击,出现的红色圆点 就是断点, 再次点击可以取消 …

Webpack: 构建微前端应用

Module Federation 通常译作“模块联邦”&#xff0c;是 Webpack 5 新引入的一种远程模块动态加载、运行技术。MF 允许我们将原本单个巨大应用按我们理想的方式拆分成多个体积更小、职责更内聚的小应用形式&#xff0c;理想情况下各个应用能够实现独立部署、独立开发(不同应用甚…

apipost的安装和测试添加接口能否正常使用

1.进入官网&#xff0c;点击免费使用&#xff08;我是windows 64位&#xff0c;选合适自己的配置&#xff09; 2.开始安装 选仅为我安装——下一步 选择自己的安装目录——点安装 等待 运行——完成 3.apipost一些基本操作——实现添加内容 &#xff08;1&#xff09;新建接口…

《人人都是产品经理》:项目一图流

《人人都是产品经理》&#xff1a;项目一图流 项目一图流 项目一图流

FreeSWITCH 1.10.10 简单图形化界面22-JsSIP的demo测试并记录坑

FreeSWITCH 1.10.10 简单图形化界面22-JsSIP的demo测试 00 FreeSWITCH GUI界面预览01、安装FreeSWITCH GUI先看使用手册02. 使用手册在这里0、设置FreeSWITCH账号1、jssip的demo网站2、设置jssip账号并登录3、整理坑3.1 掉线问题3.11 解决3.2 呼叫问题13.21 解决13.3 呼叫问题2…

PAE:从潮流报告中提炼有效产品属性

本文将介绍PAE&#xff0c;一种用于包含 PDF格式的文本和图像的产品属性提取算法。目前大部分的方法侧重于从标题或产品描述中提取属性&#xff0c;或利用现有产品图像中的视觉信息。与之前的工作相比&#xff0c;PAE从潮流趋势报告的PDF文件中提取属性&#xff0c;提取的属性包…

spl实现循环计算

需求 需要对一批数据进行价格计算 这里面的一部分单价来自于历史记录&#xff0c;但是另外一部分的单价&#xff0c;需要边计算边存储 数据库结构 CREATE TABLE tbl_mix_trace_price (lot_id_out varchar(255) DEFAULT NULL COMMENT 产出,lot_id_in varchar(255) DEFAULT NULL…

谈一下MySQL的两阶段提交机制

文章目录 为什么需要两阶段提交&#xff1f;两阶段提交流程&#xff1f;两阶段提交缺点&#xff1f; 为什么需要两阶段提交&#xff1f; 为了保证事务的持久性和一致性&#xff0c;MySQL需要确保redo log和binlog的同步持久化。MySQL通过“两阶段提交”的机制来实现在事务提交…

小迪安全v2023 javaWeb项目

小迪安全v2023 javaWeb项目 文章目录 小迪安全v2023 javaWeb项目1. webgoat靶场1. 环境配置与docker操作 2. jwt令牌1. jwt 第四关 签名没验证空加密2. jwt 第五关 爆破签名密钥3. jwt 第八关 kid参数可控 1. webgoat靶场 1. 环境配置与docker操作 自行下载配置vmware的kali-…

《mysql篇》--查询(进阶)

目录 将查询结果作为插入数据 聚合查询 聚合函数 count sum group by子句 having 联合查询 笛卡尔积 多表查询 join..on实现多表查询 内连接 外连接 自连接 子查询 合并查询 将查询结果作为插入数据 Insert into 表2 select * from 表1//将表1的查询数据插入…

Linux开发讲课20--- QSPI

SPI 是英语 Serial Peripheral interface 的缩写&#xff0c;顾名思义就是串行外围设备接口&#xff0c;一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;为 PCB 的布局上节省空间…

Springcloud-消息总线-Bus

1.消息总线在微服务中的应用 BUS- 消息总线-将消息变更发送给所有的服务节点。 在微服务架构的系统中&#xff0c;通常我们会使用消息代理来构建一个Topic&#xff0c;让所有 服务节点监听这个主题&#xff0c;当生产者向topic中发送变更时&#xff0c;这个主题产生的消息会被…

多线程引发的安全问题

前言&#x1f440;~ 上一章我们介绍了线程的一些基础知识点&#xff0c;例如创建线程、查看线程、中断线程、等待线程等知识点&#xff0c;今天我们讲解多线程下引发的安全问题 线程安全&#xff08;最复杂也最重要&#xff09; 产生线程安全问题的原因 锁&#xff08;重要…