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

news2024/11/26 13:38:03

目标

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

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

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);
        }
    };

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

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

相关文章

快速了解《大模型赋能下的AI2.0数字人平台》白皮书

在生成式AI和大模型的赋能下&#xff0c;数字人迎来AI 2.0时代。它能否成为每个人的“数字分身”&#xff0c;转化为新型的AI劳动力工具&#xff1f;商汤科技与上海市人工智能技术协会、零壹智库、增强现实核心技术产业联盟联合发布《大模型赋能下的AI 2.0数字人平台》。《白皮…

利用微信开放标签<wx-open-launch-weapp>在H5中跳转微信小程序报错完美的解决方案

一、报错&#xff1a; [WXTAG] [JSCORE] The slot <template> or <script type"text/wxtag-template"> of <wx-open-launch-weapp> is missing 二、源码 官方源代码如下&#xff0c;<script type"text/wxtag-template"></sc…

智能社区服务小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;房屋信息管理&#xff0c;住户信息管理&#xff0c;家政服务管理&#xff0c;家政预约管理&#xff0c;报修信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;房屋信…

# Sharding-JDBC从入门到精通(3)- Sharding-JDBC 入门程序

Sharding-JDBC从入门到精通&#xff08;3&#xff09;- Sharding-JDBC 入门程序 一、Sharding-JDBC 入门程序&#xff08;水平分表&#xff09;-环境搭建 1、需求说明 使用 Sharding-JDBC 完成对订单表的水平分表&#xff0c;通过快速入门程序的开发&#xff0c;快速体验 Sh…

Unity制作一个简单抽卡系统(简单好抄)

业务流程&#xff1a;点击抽卡——>播放动画——>显示抽卡面板——>将随机结果添加到面板中——>关闭面板 1.准备素材并导入Unity中&#xff08;包含2个抽卡动画&#xff0c;抽卡结果的图片&#xff0c;一个背景图片&#xff0c;一个你的展示图片&#xff09; 2.给…

mac电脑游戏推荐:NBA 2K24 街机版下载

NBA 2K24 街机版是一款由2K Sports开发并发行的篮球游戏&#xff0c;属于著名的NBA 2K系列。这款游戏为玩家提供了与NBA联赛中真实球员和球队互动的机会&#xff0c;体验篮球比赛的激情与紧张。街机版的NBA 2K24通常会在游戏厅、商场等公共场所设置&#xff0c;供玩家投币游玩。…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-48全连接卷积神经网络(FCN)

48全连接卷积神经网络&#xff08;FCN&#xff09; 1.构造函数 import torch import torchvision from torch import nn from torch.nn import functional as F import matplotlib.pyplot as plt import liliPytorch as lp from d2l import torch as d2l# 构造模型 pretrained…

如何在 Linux 中后台运行进程?

一、后台进程 在后台运行进程是 Linux 系统中的常见要求。在后台运行进程允许您在进程独立运行时继续使用终端或执行其他命令。这对于长时间运行的任务或当您想要同时执行多个命令时特别有用。 在深入研究各种方法之前&#xff0c;让我们先了解一下什么是后台进程。在 Linux 中…

数字图像处理期末复习题1

个人名片&#xff1a; &#x1f393;作者简介&#xff1a;嵌入式领域优质创作者&#x1f310;个人主页&#xff1a;妄北y &#x1f4de;个人QQ&#xff1a;2061314755 &#x1f48c;个人邮箱&#xff1a;[mailto:2061314755qq.com] &#x1f4f1;个人微信&#xff1a;Vir2025WB…

甄选范文“论云上自动化运维及其应用”,软考高级论文,系统架构设计师论文

论文真题 云上自动化运维是传统IT运维和DevOps的延伸,通过云原生架构实现运维的再进化。云上自动化运维可以有效帮助企业降低IT运维成本,提升系统的灵活度,以及系统的交付速度,增强系统的可靠性,构建更加安全、可信、开放的业务平台。 请围绕“云上自动化运维及其应用”…

PICO 4S泄露信息更新,配备骁龙XR2 Gen 2,单眼分辨率2160×2160

根据最新的泄露信息汇总&#xff0c;PICO 4S确实有望成为一款高性能的VR头显&#xff0c;其核心规格和特性包括&#xff1a; 处理器与内存&#xff1a;搭载了高通骁龙XR2 Gen 2芯片组&#xff0c;这是针对VR/AR设备优化的高端处理器&#xff0c;能提供更强大的计算能力和效率。…

利用BFS或动态规划解决路径算法问题

最小路径和和不同路径 一、力扣64. 最小路径和1.找出DP状态2.找出DP状态转移方程3. 算法实现 二、力扣62. 不同路径思路1&#xff1a;BFS实现思路2&#xff1a;动态规划 一、力扣64. 最小路径和 给定一个包含非负整数的 m x n 网格&#xff0c;请找出一条从左上角到右下角的路…

浅谈如何在linux上部署java环境

文章目录 一、部署环境1.1、JDK1.2、Tomcat1.3、MySQL 二、将自己写的的程序部署到云服务器上 一、部署环境 为了在linux上部署 Java web 程序&#xff0c;需要安装一下环境。 1.1、JDK 直接使用 yum 命令安装 openjdk。我们 windows系统上 下载的是 oracle 官方的 jdk。而 …

Redisson框架

1. Redisson锁与Redis订阅与发布模式的联系&#xff1a; Redisson锁中&#xff0c;使用订阅发布模式去通知等待锁的客户端&#xff1a;锁已经释放&#xff0c;可以进行抢锁。 publish channel_name message&#xff1a;将消息发送到指定频道 解锁时&#xff0c;在Lua解锁脚本…

vue开发网站--关于window.print()调取打印

1.vue点击按钮调取打印 点击按钮&#xff1a; 调取打印该页面&#xff1a; <div click"clickDown()">下载</div>methods: {//下载-调取打印clickDown() {window.print()}, }<style>/* 点击打印的样式 */media print {.clickDown {display: no…

昇思25天学习打卡营第七天|模型训练

背景 提供免费算力支持&#xff0c;有交流群有值班教师答疑的华为昇思训练营进入第七天了。 今天是第七天&#xff0c;前六天的学习内容可以看链接 昇思25天学习打卡营第一天|快速入门 昇思25天学习打卡营第二天|张量 Tensor 昇思25天学习打卡营第三天|数据集Dataset 昇思25天…

Altair SimSolid无网格快速结构仿真软件

Altair SimSolid软件作为一款快速无网格划分工具&#xff0c;凭借其独特的算法和计算能力&#xff0c;简化了工程师和分析师在进行复杂结构分析时的操作。它不仅提高了分析效率&#xff0c;降低了出错的可能性&#xff0c;还为用户提供了丰富的分析功能和直观易用的操作体验。在…

3、Redis集群原理分析

槽定位 (Slot Mapping): Redis Cluster 将所有数据划分为 16384 个槽位&#xff08;slots&#xff09;&#xff0c;每个槽位由一个或多个节点负责管理。Redis 集群通过 CRC16 哈希算法来计算每个 key 的哈希值&#xff0c;并对 16384 取模以确定该 key 应该存储在哪个槽位上。…

名企面试必问30题(十)——你有自己的方法论吗?

1.思路 第一&#xff0c;方法论指的是做某些事情或业务的套路&#xff0c;但它没有绝对的正确性&#xff0c;每个人都可以拥有专属的方法论。 第二&#xff0c;方法论必定源自于自身实战经验的总结。 2.参考解答 “在软件测试工作中&#xff0c;我逐渐形成了自己的一套方法论。…

Elasticsearch 聚合查询简介

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…