dev控件swiftplot图滚动方法_无限轮播图使用Scroller就这么简单

前言

这几天又拾起老本行,复习复习Android,才发现忘的差不多了,上午做了一个小Demo,配合Scroller做了一个轮播图,效果如下,但是不知为何,录制的GIF成这样,凑乎一下看看。

beda6d4a89f33bea64d2893995c41859.gif

原理是继承ViewGroup,然后自己摆放子View,也就是摆放在一条线上,开启一个定时器,每隔X秒通过Scroller进行滚动,当然还有处理Touch事件,在手指按下的时候定时器停止,抬起的时候定时器重新启动。

Scroller简介

我们知道View中提供了scrollTo()和scrollBy()两个方法用来滚动,也就是说任何一个控件都是可以滚动的,他两的区别在于,scrollBy()让View相对于当前的位置滚动一段距离,scrollTo()则是让View相对于初始的位置滚动一段距离。

注意这里的滚动是内容的滚动,不是自身位置。

还有一个类是Scroller,用于处理滚动效果的工具类,但是这个类并不能直接使View滚动,而是提供计算滚动的值,我们拿到这个值在调用scrollTo或scrollBy进行滚动。

Scroller的两个重要方法是startScroll和computeScrollOffset,startScroll()方法是用来初始化滚动数据的,第一个参数是滚动开始时X的坐标,第二个参数是滚动开始时Y的坐标,如果我们的控件只支持X轴滚动,那么Y永远是0,,第三个参数是横向滚动的距离,第四个参数是纵向滚动的距离,通常这个方法后面会调用invalidate()方法来刷新界面。

最后就是重写computeScroll()方法,这个方法根据注释的意思是在父级请求子级更新其mScrollX值时候调用,在这个方法下通过不断调用Scroller的computeScrollOffset()方法来判断滚动操作是否完成了,如果还没完成的话,那就继续调用scrollTo()方法,传入Scroller的curX和curY,这样就完成了内容的平滑滚动。

另外Scroller还支持Interpolator,使滚动更具有效果。

实现

package com.example.androiddemo;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;

import androidx.annotation.NonNull;

import java.util.Timer;
import java.util.TimerTask;

public class BannerView extends ViewGroup {
    private static final int INVALIDATE_MSG = 1000;

    private static final int DEFAULT_DURATION = 1000;
    private static final int DEFAULT_PERIOD = 2000;
    private static final String TAG = "TAG";

    private int mPeriod;
    private int mDuration;

    private boolean isTouch = false;

    private int mDownX;

    private Scroller mScroller;
    private Timer mTimer;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case INVALIDATE_MSG:
                    nextItem();
                    break;
            }
        }
    };

    public BannerView(Context context) {
        super(context);
        init();
    }

    public BannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public BannerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPeriod = DEFAULT_PERIOD;
        mDuration = DEFAULT_DURATION;

        mScroller = new Scroller(getContext());

        startTimer(0);
    }

    private void startTimer(int delay) {
        mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (!isTouch)
                    handler.sendEmptyMessage(INVALIDATE_MSG);
            }
        }, delay, mPeriod);
    }

    private void nextItem() {
        mScroller.startScroll(getScrollX(), 0, getMeasuredWidth(), 0, mDuration);
        invalidate();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = 0;

        for (int i = 0; i             View childAt = getChildAt(i);
            childAt.layout(left, t, r + left, b);
            left += r;
        }
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
        if (mScroller.isFinished() && getScrollX() == getMeasuredWidth() * (getChildCount() - 1)) {
            Log.i(TAG, "computeScroll: " + getScrollX());
            scrollTo(0, 0);
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = (int) event.getX();
                mTimer.cancel();
                break;
            case MotionEvent.ACTION_UP:
                int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();
                int dx = targetIndex * getWidth() - getScrollX();
                mScroller.startScroll(getScrollX(), 0, dx, 0, mDuration);
                invalidate();
                startTimer(mPeriod);
                break;
            case MotionEvent.ACTION_MOVE:
                scrollBy((int) (mDownX - event.getX()), 0);
                mDownX = (int) event.getX();
                break;
        }
        return true;
    }
}

<?xml  version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:orientation="vertical"android:background="#FFFFFF"android:paddingLeft="10dp"android:paddingRight="10dp"android:paddingTop="20dp"tools:context=".MainActivity">

    <RelativeLayoutandroid:layout_width="match_parent"android:layout_height="150dp">
        <com.example.androiddemo.BannerViewandroid:layout_width="match_parent"android:layout_height="match_parent">
            <ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner1"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>

            <ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner2"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
            <ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner3"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
            <ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner4"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
            <ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner1"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
        com.example.androiddemo.BannerView>

    RelativeLayout>

LinearLayout>

- END -

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

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

相关文章

JVM——CPU缓存架构与Java 内存模型

导航一、CPU缓存架构与一致性协议1.1 CPU缓存架构1.2 缓存行与伪共享问题1.3 MESI 缓存一致性协议1.4 伪共享的解决办法二、JMM Java 内存模型2.1 JMM 简介2.2 原子性、可见性、有序性2.3 八大内存交互操作2.4 happens-before 原则一、CPU缓存架构与一致性协议 1.1 CPU缓存架构…

白噪声检测_科学家尝试用智能扬声器的白噪声来监测婴儿的呼吸运动

华盛顿大学的一支研究团队&#xff0c;刚刚介绍了他们开发的一种新型智能扬声器技术。这种设备能够借助白噪声来安抚熟睡的婴儿&#xff0c;并监测他们的呼吸和运动。具体说来是&#xff0c;通过智能扬声器发出的白噪声&#xff0c;原型设备能够将之与生命体征监测仪的数据相匹…

最大值_285期 博最大值2路,已经箭在弦上!

往期数据P-5掉码 跨度 和尾 012断路 余数和 位数86072 1 8 4 200 断1路2 5 对214对 双双双79703 0 2 3 101 断2路2 4 对215对 单单单62386 0 4 1 020 断1路2 4 错216对 双双单71903 0 8 7 110 断2路2 5 错217对 单单单64838 0 4 8 012 来3路3 4 错218对 双双双02052 0 2 2 020 …

商品领域ddd_为 Gopher 打造 DDD 系列:领域模型-资源库

前言&#xff1a; 作为领域模型中最重要的环节之一的Repository&#xff0c;其通过对外暴露接口屏蔽了内部的复杂性&#xff0c;又有其隐式写时复制的巧妙代码设计&#xff0c;完美的将DDD中的Repository的概念与代码相结合&#xff01;Repository资源库通常标识一个存储的区域…

mysql5.7主从全备恢复_Mysql5.7—运维常用备份方式(超全)

小生博客&#xff1a;http://xsboke.blog.51cto.com小生 Q Q&#xff1a;1770058260-------谢谢您的参考&#xff0c;如有疑问&#xff0c;欢迎交流一、 Mysqldump备份结合binlog日志恢复使用mysqldump进行全库备份&#xff0c;并使用binlog日志备份&#xff0c;还原时&#xf…

docker 运行容器_Docker之运行 Django 容器

首先此篇笔记默认你已经安装好了 Docker&#xff0c;并了解 Docker 的基础概念&#xff0c;诸如镜像、容器、以及他们之间的关系等。如果不太了解&#xff0c;等我回头了解清楚以后&#xff0c;可以再写一篇文章阐述一下。&#xff08;狗头当然&#xff0c;对于这篇文章&#x…

mysql8.0与mysql7.0_MySQL 5.7 vs 8.0,哪个性能更牛?

测试mysql5.7和mysql8.0分别在读写&#xff0c;选定&#xff0c;只写模式下不同并发时的性能(tps&#xff0c;qps)最早测试使用版本为mysql5.7.22和mysql8.0.15sysbench测试前先重启mysql服务&#xff0c;并清除os的缓存(避免多次测试时命中缓存)每次进行测试都是新生成测试数据…

springmvc使用requestmapping无法访问控制类_研究人员称人类使用的新烟碱类杀虫剂让蜜蜂无法入睡...

来自布里斯托尔大学的科学家进行了研究&#xff0c;显示常见的杀虫剂可以阻止蜜蜂和苍蝇睡个好觉。就像人类一样&#xff0c;许多昆虫也需要睡眠才能正常工作。然而&#xff0c;如果它们接触过新烟碱类杀虫剂&#xff0c;它们的睡眠就会受到影响&#xff0c;新烟碱类杀虫剂是一…

linux 监控mysql脚本_Linux系统MySQL主从同步监控shell脚本

操作系统&#xff1a;CentOS系统目的&#xff1a;定时监控MySQL数据库主从是否同步&#xff0c;如果不同步&#xff0c;记录故障时间&#xff0c;并执行命令使主从恢复同步状态1、创建脚本文件vi /home/crontab/check_mysql_slave.sh #编辑&#xff0c;添加下面代码#!/bin/sh…

python协成_Python协程(上)

几个概念&#xff1a;event_loop 事件循环&#xff1a;程序开启一个无限的循环&#xff0c;程序员会把一些函数注册到事件循环上。当满足事件发生的时候&#xff0c;调用相应的协程函数。coroutine 协程&#xff1a;协程对象&#xff0c;指一个使用async关键字定义的函数&#…

js父元素获取子元素img_css,前端_父标签div中包含一个子元素img标签,子元素div标签,为什么img要加上浮动,子元素div才会处于正常位置?,css,前端 - phpStudy...

父标签div中包含一个子元素img标签&#xff0c;子元素div标签&#xff0c;为什么img要加上浮动&#xff0c;子元素div才会处于正常位置&#xff1f;dom结构如图img加上float 子元素div显示正常。不加float div显示错位。附上我写的一个dome测试用的&#xff0c;大家可本地看下究…

android运营商获取本机号码_一键登录已成大势所趋,Android端操作指南来啦!

根据极光(Aurora Mobile)发布的《2019年Q2移动互联网行业数据研究报告》&#xff0c;2019年第二季度&#xff0c;移动网民人均安装APP总量已达56款。面对如此繁多的APP&#xff0c;想在用户的手机中占据一席之地&#xff0c;移动开发者们就不得不努力提升用户体验。而现实却是&…

spring批量写入mysql数据库_MyBatis-spring和spring JDBC批量插入Mysql的效率比较

工具框架用spring-batch&#xff0c;数据库是mysql(未做特殊优化)。比较数据框架mybatis和spring jdbc的插入效率。Mybatis三种实现&#xff1a;1、mybatis的官方写法Java代码publicvoidbatchInsert1(List poilist)throwsException {SqlSession sqlSession sqlSessionFactory.…

金额转换java_java金额转换

像商品价格&#xff0c;订单&#xff0c;结算都会涉及到一些金额的问题&#xff0c;为了避免精度丢失通常会做一些处理&#xff0c;常规的系统中金额一般精确到小数点后两位&#xff0c;也就是分&#xff1b;这样数据库在设计的时候金额就直接存储整型数据类型&#xff0c;前端…

java bloomfilter_爬虫技术之——bloom filter(含java代码)

在爬虫系统中&#xff0c;在内存中维护着两个关于URL的队列&#xff0c;ToDo队列和Visited队列&#xff0c;ToDo队列存放的是爬虫从已经爬取的网页中解析出来的即将爬取的URL&#xff0c;但是网页是互联的&#xff0c;很可能解析出来的URL是已经爬取到的&#xff0c;因此需要VI…

java php js_【javascript/PHP】当一个JavaScripter初次进入PHP的世界,他将看到这样的风景...

本文将从以下11点介绍javascript和PHP在基础语法和基本操作上的异同&#xff1a;1.数据类型的异同2.常量和变量的定义的不同&#xff0c;字符串连接运算符不同3.对象的创建方法的不同4.PHP与JS在变量声明提升和函数声明提升的差异5.var在JS和PHP中使用的差异6.PHP和JS在访问对象…

从零开始学java 框架_从零开始学 Java - 搭建 Spring MVC 框架

如果创建一个 Spring 项目Spring MVC 框架在 Java 的 Web 项目中应该是无人不知的吧&#xff0c;你不会搭建一个 Spring 框架&#xff1f;作为身为一个刚刚学习Java的我都会&#xff0c;如果你不会的话&#xff0c;那可真令人忧伤。1.在 MyEclipse 创建项目后&#xff0c;可以以…

java 系统类型_Java获取操作系统类型

Java获取操作系统完整版系统枚举类&#xff1a;public enum EPlatform {Any("any"),Linux("Linux"),Mac_OS("Mac OS"),Mac_OS_X("Mac OS X"),Windows("Windows"),OS2("OS/2"),Solaris("Solaris"),SunOS…

azure mysql on vnet_管理 VNet 终结点 - Azure 门户 - Azure Database for MySQL | Microsoft Docs

您现在访问的是微软AZURE全球版技术文档网站&#xff0c;若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站&#xff0c;请访问 https://docs.azure.cn.使用 Azure 门户创建和管理 Azure Database for MySQL VNet 服务终结点和 VNet 规则Create and manage Azure D…

java jmap jc_利用jmap命令查看JVM内存使用详情

介绍打印出某个java进程(使用pid)内存内的&#xff0c;所有‘对象’的情况(如&#xff1a;产生那些对象&#xff0c;及其数量)。它的用途是为了展示java进程的内存映射信息&#xff0c;或者堆内存详情。可以输出所有内存中对象的工具&#xff0c;甚至可以将VM 中的heap&#xf…