轮播图(多个一起轮播)

效果图
在这里插入图片描述

class MainActivity : Activity(), Runnable {

    private lateinit var viewPager: ViewPager
    private lateinit var bannerAdapter: BannerAdapter
    private val images = ArrayList<Int>() // 存储图片资源的列表
    private val handler = Handler() // 用于定时发送消息的Handler
    private val DELAY_TIME = 3000L // 轮播的延迟时间,单位为毫秒

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var list= arrayListOf<Bean>()
        viewPager = findViewById(R.id.view_pager) // 获取ViewPager控件
        images.apply { // 初始化图片资源的列表
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
            add(R.mipmap.ic_launcher) // 添加图片资源
        }
        //处理数据
        //数据处理为3的倍数(加的方式)
        val value=images.size%3
        if (value==1){
            images.add(images[1])
            images.add(images[2])
        }else if (value==2){
            images.add(images[1])
        }
        for (i in 0 until images.size step 3){
            list.add(
                Bean(
                    BeanItem(images[i],"title$i"),
                    BeanItem(images[i+1],"title${i+1}"),
                    BeanItem(images[i+2],"title${i+2}")
                )
            )
        }

        bannerAdapter = BannerAdapter(this, list) // 创建适配器对象
        viewPager.adapter = bannerAdapter // 设置适配器
        viewPager.currentItem = images.size * 100 // 设置当前的位置,以保证可以向前滑动
//        viewPager.setPageTransformer(true, ZoomOutPageTransformer()) // 设置页面的转换效果,您可以自定义或使用第三方的库
        viewPager.pageMargin = 20 // 设置页面的间隔
        viewPager.offscreenPageLimit = 3 // 设置预加载的页面数
        handler.postDelayed({ // 发送一个延迟的Runnable对象
            val currentItem = viewPager.currentItem // 获取当前的位置
            viewPager.currentItem = currentItem + 1 // 设置下一个位置
            handler.postDelayed(this, DELAY_TIME) // 再次发送延迟的Runnable对象,实现循环
        }, DELAY_TIME)
    }

    override fun onDestroy() {
        super.onDestroy()
        handler.removeCallbacksAndMessages(null) // 移除所有的消息和回调,避免内存泄漏
    }
    private  val TAG = "MainActivity"
    override fun run() {
        handler.postDelayed({ // 发送一个延迟的Runnable对象
            val currentItem = viewPager.currentItem // 获取当前的位置
            viewPager.currentItem = currentItem + 1 // 设置下一个位置
            handler.postDelayed(this, DELAY_TIME) // 再次发送延迟的Runnable对象,实现循环
        }, DELAY_TIME)
    }
}



class BannerAdapter(private val context: Context, private val list: ArrayList<Bean>) : PagerAdapter() {

    override fun getCount(): Int {
        return Int.MAX_VALUE // 设置为一个很大的数,以实现无限循环
    }

    @SuppressLint("MissingInflatedId")
    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val view = LayoutInflater.from(context).inflate(R.layout.item_banner, container, false) // 加载自定义的布局文件
        val imageView1 = view.findViewById<ImageView>(R.id.image_view1) // 获取布局文件中的ImageView
        val imageView2 = view.findViewById<ImageView>(R.id.image_view2) // 获取布局文件中的ImageView
        val imageView3 = view.findViewById<ImageView>(R.id.image_view3) // 获取布局文件中的ImageView
        val tv1 = view.findViewById<TextView>(R.id.tv1) // 获取布局文件中的ImageView
        val tv2 = view.findViewById<TextView>(R.id.tv2) // 获取布局文件中的ImageView
        val tv3 = view.findViewById<TextView>(R.id.tv3) // 获取布局文件中的ImageView
        imageView1.setImageResource(list[position % list.size].item1.img) // 设置图片资源
        imageView2.setImageResource(list[position % list.size].item2.img) // 设置图片资源
        imageView3.setImageResource(list[position % list.size].item3.img) // 设置图片资源
        tv1.text=list[position % list.size].item1.title
        tv2.text=list[position % list.size].item2.title
        tv3.text=list[position % list.size].item3.title
        container.addView(view) // 将视图添加到容器中
        return view // 返回视图对象
    }

    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
        container.removeView(`object` as View) // 移除视图
    }

    override fun isViewFromObject(view: View, `object`: Any): Boolean {
        return view == `object` // 判断视图是否和对象相同
    }
}

bean

class Bean(val item1:BeanItem,val item2:BeanItem,val item3:BeanItem)
class BeanItem(val img:Int,val title:String)

自定义垂直viewPager

class VerticalViewPager(context: Context, attrs: AttributeSet?) : ViewPager(context, attrs) {

    private val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
            return if (abs(distanceX) > abs(distanceY)) {
                false
            } else {
                super.onScroll(e1, e2, distanceX, distanceY)
            }
        }
    })

    init {
        setPageTransformer(true, VerticalPageTransformer())
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        val intercepted = super.onInterceptTouchEvent(swapXY(ev))
        swapXY(ev)
        return intercepted
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        return if (gestureDetector.onTouchEvent(ev)) {
            super.onTouchEvent(swapXY(ev))
        } else {
            false
        }
    }

    private fun swapXY(event: MotionEvent?): MotionEvent? {
        event?.let {
            val width = width.toFloat()
            val height = height.toFloat()

            val newX = it.y / height * width
            val newY = it.x / width * height

            it.setLocation(newX, newY)
        }
        return event
    }
}
class VerticalPageTransformer : PageTransformer {
    override fun transformPage(view: View, position: Float) {
        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.alpha = 0f
        } else if (position <= 1) { // [-1,1]
            view.alpha = 1f
            // Counteract the default slide transition
            view.translationX = view.width * -position
            //set Y position to swipe in from top
            val yPosition = position * view.height
            view.translationY = yPosition
        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.alpha = 0f
        }
    }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <com.example.banner.view.VerticalViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"/>

</LinearLayout>

item_banner

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:paddingHorizontal="40dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_weight="1"
        android:gravity="center">
        <ImageView
            android:layout_marginHorizontal="10dp"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:id="@+id/image_view1"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher"
            android:layout_weight="1"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv1"
            android:text="hello"/>
    </LinearLayout>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_weight="1"
        android:gravity="center">
        <ImageView
            android:layout_marginHorizontal="10dp"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:id="@+id/image_view2"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher"
            android:layout_weight="1"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv2"
            android:text="hello"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_weight="1"
        android:gravity="center">
        <ImageView
            android:layout_marginHorizontal="10dp"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:id="@+id/image_view3"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher"
            android:layout_weight="1"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv3"
            android:text="hello"/>
    </LinearLayout>

</LinearLayout>

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

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

相关文章

Linux磁盘分区快速上手(讲解详细)

一、磁盘分区 在Linux中&#xff0c;磁盘是通过分区来使用的。分区是将一个硬盘划分成几个逻辑部分来使用&#xff0c;在每个分区中可以存储不同的文件系统。因此&#xff0c;在挂载磁盘之前&#xff0c;我们需要先对磁盘进行分区。磁盘分区的过程可以通过命令行工具或图形界面…

Unity中Shader矩阵的转置矩阵

文章目录 前言一、转置的表示二、转置矩阵三、转置矩阵的总结1、(A^T^)^T^ A2、(A B)^T^ A^T^ B^T^3、(kA)^T^ kA^T^ (k为实数)4、(AB)^T^ B^T^A^T^5、如果 A A^T^ 则称A为对称矩阵6、如果 AA^T^ I(单位矩阵)&#xff0c;则称 A 为正交矩阵&#xff0c;同时 A^T^ A^-1…

OpenCV中的像素重映射原理及实战分析

引言 映射是个数学术语&#xff0c;指两个元素的集之间元素相互“对应”的关系&#xff0c;为名词。映射&#xff0c;或者射影&#xff0c;在数学及相关的领域经常等同于函数。 基于此&#xff0c;部分映射就相当于部分函数&#xff0c;而完全映射相当于完全函数。 说的简单点…

MySQL 1、初识数据库

一、什么是数据库&#xff1f; 以特定的格式保存好的文件&#xff0c;我们就叫做数据库。 提供较为便捷的数据的存取服务的软件集合、解决方案&#xff0c;我们就叫它数据库。 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库。 文件或数据库都可以存储数据&#…

react+video.js h5自定义视频暂停图标

目录 参考网址 效果图&#xff0c;暂停时显示暂停图标&#xff0c;播放时隐藏暂停图标 代码说明&#xff0c;代码传入url后&#xff0c;可直接复制使用 VideoPausedIcon.ts 组件 VideoCom.tsx Video.module.less 参考网址 在Video.js播放器中定制自己的组件 - acgtofe 效…

nodejs+vue教室管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

用户 用户管理&#xff1a;查看&#xff0c;修改自己的个人信息 教室预约&#xff1a;可以预约今天明天的教室&#xff0c;按着时间段预约&#xff08;可多选&#xff09;&#xff0c;如果当前时间超过预约时间段不能预约该时间段的教室 预约教室的时候要有个预约用途&#xff…

所见即所得的动画效果:Animate.css

我们可以在集成Animate.css来改善界面的用户体验&#xff0c;省掉大量手写css动画的时间。 官网&#xff1a;Animate.css 使用 1、安装依赖 npm install animate.css --save2、引入依赖 import animate.css;3、在项目中使用 在class类名上animate__animated是必须的&#x…

腾讯云服务器新用户购买优惠多少钱?腾讯云新用户购买优惠

对于新用户来说&#xff0c;腾讯云服务器更是提供了一系列的优惠活动&#xff0c;让你在购买时享受到更多的优惠。那么&#xff0c;腾讯云服务器新用户购买优惠多少钱呢&#xff1f;接下来&#xff0c;让我们一起来了解一下。 腾讯云双十一领9999代金券 https://1111.mian100.…

ActiveMQ

目录 ActiveMQ简介 ActiveMQ安装 原生JMS API操作ActiveMQ SpringBoot与ActiveMQ整合 ActiveMQ消息组成与高级特性 ActiveMQ企业面试经典问题总结 ActiveMQ简介 消息中间件应用场景 异步处理 应用解耦 流量削锋 异步处理 场景说明&#xff1a;用户注册&#xff0c;需要执行…

iApp祁天社区UI成品源码 功能齐全的社区应用

iApp祁天社区UI成品源码是一个非常实用的资源&#xff0c;提供了完整的源代码&#xff0c;可以帮助您快速搭建一个功能齐全的社区应用。 这个源码具有丰富的UI设计&#xff0c;经过精心调整和优化&#xff0c;确保用户体验流畅而舒适。它不仅具备基本的社区功能&#xff0c;如…

MFC保存窗口客户区为图片

首先的窗口输出一些内容&#xff1b; 菜单单击函数代码&#xff1b; void CgetmypicView::OnTestGetmypic() {// TODO: 在此添加命令处理程序代码HWND hwnd this->GetSafeHwnd();HDC hDC ::GetWindowDC(hwnd);//获取DC RECT rect;::GetClientRect(hwnd, &rect)…

Mysql 索引优化——Explain

文章目录 Explain 简介Explain 概念Explain 示例 Explain 中列的含义idselect_typetabletypepossible_keyskeykey_lenrefrowExtra 索引最佳实践1.全值匹配2.最左前缀原则3.避免计算、函数、类型转换导致索引失效4.范围条件右边的索引列失效5.尽量使用覆盖索引 Explain 简介 Ex…

软件自动化测试作用简析,为什么要选择第三方软件测评机构?

软件自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常&#xff0c;在设计了测试用例并通过评审之后&#xff0c;由测试人员根据测试用例中描述的规程一步步执行测试&#xff0c;得到实际结果与期望结果的比较。 一、自动化测试的作用   1.测试效能大幅度提…

数据结构与算法【队列】的Java实现

队列&#xff1a;以顺序的方式维护的一组数据集合&#xff0c;在一端添加数据&#xff0c;从另一端移除数据。习惯来说&#xff0c;添加的一端称为尾&#xff0c;移除的一端称为头。 通用接口 public interface Queue<E> {/*** 插入队列*/boolean offer(E value);/*** 从…

2023年05月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 明明每天坚持背英语单词,他建立了英语单词错题本文件“mistakes.txt”,将每天记错的单词增加到该文件中,下列打开文件的语句最合适的是?( ) A: f = open(“mistakes.txt”) B: …

【论文阅读】A Survey on Video Diffusion Models

视频扩散模型&#xff08;Video Diffusion Model&#xff09;最新综述GitHub 论文汇总-A Survey on Video Diffusion Models。 paper&#xff1a;[2310.10647] A Survey on Video Diffusion Models (arxiv.org) 0. Abstract 本文介绍了AIGC时代视频扩散模型的全面回顾。简要介…

Git-概念与架构

GIT-概念与架构 一、背景和起源二、版本控制系统1.版本控制分类1.1 集中式版本控制1.2 分布式版本控制 2.Git和SVN对比2.1 SVN2.2 GIT 三、GIT框架1.工作区&#xff08;working directory&#xff09;2.暂存区&#xff08;staging area&#xff09;3.本地仓库&#xff08;local…

机器视觉公司怎么可能养我这闲人,连软件加密狗都用不起,项目都用盗版,为什么​?

正版价值观我是认同的&#xff0c;但是同行也不用软件加密狗&#xff0c;你让我承担过多的设备成本&#xff0c;终端客户不愿意承担加密狗的成本&#xff0c;公司更不愿意去承担&#xff0c;许多机器视觉公司“零元购”&#xff0c;机器视觉软件加密狗都用不起&#xff0c;项目…

51单片机应用从零开始(五)·加减乘除运算

51单片机应用从零开始&#xff08;一&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;二&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;三&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;四&#xff09;-CSDN博客 详解 KEIL C51 软件的使用建立工程…

微机原理_10

一、单项选择题(本大题共15小题,每小题3分,共45分。在每小题给出的四个备选项中,选出一个正确的答案。&#xff09; 1,将二进制数110110.01转换为十六进制为(&#xff09; A. 66.1H B. 36.4H C. 66.4 D. 36.2 2,一台计算机的字长是4个字节,含义是(&#xff09; A.能处理的最大…