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是最近…

MT1568 学生成绩

题目 有3个学生&#xff0c;每个学生有3门课的成绩&#xff0c;从键盘输入数据&#xff0c;包括学号、姓名、三门课成绩&#xff0c;学号整型&#xff0c;姓名字符型&#xff0c;成绩实型&#xff0c;计算3门课程总平均成绩&#xff0c;以及平均分最高的学生信息。不考虑非法成…

【webrtc】webrtc 与h265

参考 webrtc 支持H265(三) 总结_webrtc h265-CSDN博客 enable-chromium-hevc-hardware-decoding/README.zh_CN.md at main StaZhu/enable-chromium-hevc-hardware-decoding GitHub 《WebRTC系列》实战 Web 端支持 h265 硬解_webrtc-streamer h265编码-CSDN博客 webrtc分块…

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;理想情况下各个应用能够实现独立部署、独立开发(不同应用甚…

高项-信息系统工程知识要点

1、五大软件架构风格 数据流风格&#xff1a;批处理序列、管道/过滤器 ◆调用/返回风格&#xff1a;主程序X 子程序、数据抽象、面向对象、层次结构 ◆独立构件风格&#xff1a;进程通信、事件驱动 虚拟机风格&#xff1a;解释器、基于规则的系统 仓库风格&#xff1a;数据库系…

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

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

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

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

【Spring】springSecurity

1、概述 1.1定义和用途 Spring Security为基于Spring的企业应用系统提供声明式的安全访问控制解决方案。它提供了一组可以在Spring应用上下文中配置的Bean&#xff0c;充分利用了Spring IoC、DI&#xff08;控制反转和依赖注入&#xff09;和AOP&#xff08;面向切面编程&…

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;提取的属性包…

ML307R OpenCPU HTTP使用

一、函数介绍 二、示例代码 三、代码下载地址 一、函数介绍 具体函数可以参考cm_http.h文件,这里给出几个我用到的函数 1、创建客户端实例 /*** @brief 创建客户端实例** @param [in] url 服务器地址(服务器地址url需要填写完整,例如(服务器url仅为格式示…

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通过“两阶段提交”的机制来实现在事务提交…