Android 实现滑动的六种方式
作者:FranzLiszt1847 发布时间:2021-12-05 08:27:48
目录
1、效果视频
2、剖析Android坐标系
3、实现方式
3.1 layout
3.2 scrollBy
3.3 offsetLeftAndRight offsetTopAndButton
3.4 LayoutParams
3.5 Scroller
3.6 平移动画
1、效果视频
2、剖析Android坐标系
滑动的本质是移动,滑动的原理就是通过不断的改变View的坐标而实现。
Android
系统提供了很多方法获取坐标值,可以将其分为两种类别,具体如下:
View 提供的获取坐标的方法:
getTop():
获取到的是View自身的顶边到其父布局顶边的距离getLeft():
获取到的是View自身的左边到其父布局左边的距离getRight():
获取到的是View自身的右边到其父布局左边的距离getBottom():
获取到的是View自身的底边到其父布局顶边的距离
MotionEvent 提供的方法:
getX():
获取点击事件距离控件左边的距离,即视图坐标getY():
获取点击事件距离控件顶边的距离,即视图坐标getRawX():
获取点击事件距离整个屏幕左边的距离,即绝对坐标getRawY():
获取点击事件距离整个屏幕顶边的距离,即绝对坐标
3、实现方式
3.1 layout
使用绝对坐标系,每次执行移动逻辑后需要重新设置初始化坐标
@Override
public boolean onTouchEvent(MotionEvent event) {
int rawX = (int) (event.getRawX());
int rawY = (int) (event.getRawY());
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_MOVE:
int offsetX = rawX - lastX;
int offsetY = rawY - lastY;
layout( getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY );
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
3.2 scrollBy
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
((View) getParent()).scrollBy( -offsetX, -offsetY );
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
3.3 offsetLeftAndRight offsetTopAndButton
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
offsetLeftAndRight( offsetX );
offsetTopAndBottom( offsetY );
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
3.4 LayoutParams
通过getLayoutParams()
获取LayoutParams
时,需要根据不同的父类型使用设置不同的类型,比如父布局为LinearLayout则设置类型为 LinearLayout.LayoutParams
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
int offsetX = x - lastX;
int offsetY = y - lastY;
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)getLayoutParams();
layoutParams.leftMargin = getLeft()+offsetX;
layoutParams.topMargin = getTop()+offsetY;
setLayoutParams( layoutParams );
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
更方便的是直接使用ViewGroup
,不需要判断父布局类型
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)getLayoutParams();
layoutParams.leftMargin = getLeft()+offsetX;
layoutParams.topMargin = getTop()+offsetY;
setLayoutParams( layoutParams );
3.5 Scroller
初始化Scroller:
scroller = new Scroller( context );
重写computeScroll()
方法
使用computeScrollOffset()
判定是否完成了整个滑动:
@Override
public void computeScroll() {
if (scroller.computeScrollOffset()) {
((View) getParent()).scrollTo( scroller.getCurrX(), scroller.getCurrY() );
invalidate();
}
super.computeScroll();
}
@Override
public boolean onTouchEvent(MotionEvent mv) {
View parent = (View) getParent();
switch (mv.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) mv.getX();
lastY = (int) mv.getY();
break;
case MotionEvent.ACTION_MOVE:
int upX = (int) (mv.getX() - lastX);
int upY = (int) (mv.getY() - lastY);
parent.scrollBy( -upX, -upY );
break;
case MotionEvent.ACTION_UP:
scroller.startScroll( parent.getScrollX(), parent.getScrollY(), -parent.getScrollX(), -parent.getScrollY(), 1000 );
invalidate();
break;
}
return super.onTouchEvent( mv );
}
3.6 平移动画
效果视频:
private void InitAnimation(){
animation = new TranslateAnimation( 0,200,0,200 );
animation.setDuration( 1000 );
}
moveButton.startAnimation( animation );
来源:https://blog.csdn.net/News53231323/article/details/121208702


猜你喜欢
- 本文以C#及VB.NET后端程序代码示例展示如何将HTML转为XML文件。转换时,调用Word API -Free Spire.Doc fo
- 一、Application是什么?Application类在每一次开发当中是我们都会遇到的,每一个APP都会有一个Application实例
- Mutex 中文为互斥,Mutex 类叫做互斥锁。它还可用于进程间同步的同步基元。Mutex 跟 lock 相似,但是 Mutex 支持多个
- 本文实例讲述了C#读写INI文件的方法。分享给大家供大家参考。具体如下:虽然微软早已经建议在WINDOWS中用注册表代替INI文件,但是在实
- 在C#中,@符号不仅可以加在字符串常量之前,使字符串不作转义之用,还可以加在变量名之前,使变量名与关键字不冲突,这种用法称为“逐字标识符”。
- Java多线程深入理解本文主要从三个方面了解和掌握多线程:1. 多线程的实现方式,通过继承Thread类和通过实现Runnable接口的方式
- ES 简介Elasticsearch 是一个基于 Lucene 实现的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 REST
- 该接口实现了序列化,声明为 public interface Key extends SerializableKey 是所有密钥的顶层接口。
- 本文实例总结了Android开发之资源文件用法。分享给大家供大家参考,具体如下:这里记录在Android开发中经常用到的一些用法arrays
- spring boot实现自动输出word文档功能本文用到Apache POI组件组件依赖在pom.xml文件中添加<dependen
- 前言在项目的开发时,遇到实现服务器主动发送数据到前端页面的功能的需求。实现该功能不外乎使用轮询和websocket技术,但在考虑
- 1. 通过字节流实现文件的拷贝 /** * 通过字节流实现文件的拷贝 * @param sourcePath 源
- 本文实例分析了Android TabHost选项卡标签图标始终不出现的解决方法。分享给大家供大家参考,具体如下:在学习Android Tab
- 本文实例讲述了C++实现的链表类。分享给大家供大家参考。具体如下:#include <iostream>using namesp
- private void button2_Click(object sender, EventArgs e) &nbs
- Intersect子句一、简介Intersect返回交集,交集是指同时出现在两个集合中的元素,和数据库中的Intersect方法实现功能一样
- 我们讲一下Criteria查询,这个对于不是太熟悉SQL语句的我们这些程序员来说是很容易上手的。 废话不多说,看一下例子:&nbs
- 目录概述事件监听的结构Publisher,Event和Listener的关系事件发布者监听者总结概述ApplicationEvent以及Li
- 关于Windows10 Java环境变量配置问题的解决办法由于最近有一些时间,所以想要把之前学过一段时间的Java重新捡起来看看,之前的学习
- 目录1、需求2、问题2、获取1)导入依赖为了获取客户端类型、操作系统类型、ip、port2)封装获取body字符串的工具类3) * 类4)继