Android实现滑动的四种方式
Posted 我想月薪过万
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实现滑动的四种方式相关的知识,希望对你有一定的参考价值。
效果展示
做android自定义View开发,实现布局的滑动是必不可少的一项手艺。下面我为大家准备了五种移动布局的方法:
- layout 法 CoordinatorLayout原理的简析
- LayoutParams 法 CoordinatorLayout原理的简析
- scrollTo/scrollBy
- Scroller 类
- ViewDragHelper 类 : ViewDragHelper 类
activity_main.xml布局文件
<?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"
tools:context=".MainActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.wust.SelfCoordinator.CanDragView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#f00"/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0f0"
android:layout_marginTop="200dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
这里面存在 CoordinatorLayout 这个布局,是因为我准备写 CoordinatorLayout 布局的教程的,Android滑动方式只是个小插曲,所以,布局文件可以不用按照我的写,仅供参考。
1、layout 法
自定义View的 java 代码
package com.wust.SelfCoordinator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
/**
* ClassName: CanDragView <br/>
* Description: <br/>
* date: 2021/6/29 9:45<br/>
*
* @author yiqi<br />
* @QQ 1820762465
*/
public class CanDragView extends View {
int startX;
int startY;
public CanDragView(Context context) {
this(context,null);
}
public CanDragView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CanDragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
{
startX =(int) event.getX();
startY =(int) event.getY();
}
break;
case MotionEvent.ACTION_MOVE:
{
int endX = (int) event.getX();
int endY = (int) event.getY();
int moveX = endX - startX;
int moveY = endY - startY;
System.out.println("moveX ->" + moveX + "moveY ->" + moveY);
//移动布局的关键性代码
layout(getLeft()+moveX,getTop()+moveY,getRight()+moveX,getBottom()+moveY);
}
break;
}
return true;
}
}
2、LayoutParams 法
package com.wust.SelfCoordinator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
/**
* ClassName: CanDragView <br/>
* Description: <br/>
* date: 2021/6/29 9:45<br/>
*
* @author yiqi<br />
* @QQ 1820762465
*/
public class CanDragView extends View {
int startX;
int startY;
public CanDragView(Context context) {
this(context,null);
}
public CanDragView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CanDragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
{
startX =(int) event.getX();
startY =(int) event.getY();
}
break;
case MotionEvent.ACTION_MOVE:
{
int endX = (int) event.getX();
int endY = (int) event.getY();
int moveX = endX - startX;
int moveY = endY - startY;
System.out.println("moveX ->" + moveX + "moveY ->" + moveY);
//移动布局的关键性代码,如果布局已经在 xml 文件中存在,你直接用 getLayoutParams() 获取参数信息就可以了,不要在重新 new
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) getLayoutParams();
params.leftMargin = getLeft()+moveX;
params.topMargin = getTop()+moveY;
setLayoutParams(params);
}
break;
}
return true;
}
}
3、scrollTo/scrollBy
package com.wust.SelfCoordinator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
/**
* ClassName: CanDragView <br/>
* Description: <br/>
* date: 2021/6/29 9:45<br/>
*
* @author yiqi<br />
* @QQ 1820762465
*/
@SuppressLint("AppCompatCustomView")
public class CanDragView extends TextView {
int startX;
int startY;
public CanDragView(Context context) {
this(context,null);
}
public CanDragView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CanDragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
{
startX =(int) event.getX();
startY =(int) event.getY();
}
break;
case MotionEvent.ACTION_MOVE:
{
int endX = (int) event.getX();
int endY = (int) event.getY();
int moveX = endX - startX;
int moveY = endY - startY;
System.out.println("moveX ->" + moveX + "moveY ->" + moveY);
//移动布局的关键性代码,scrollTo/scrollBy 移动的是 View中的内容 ViewGroup中的子View
scrollTo(-(getLeft()+moveX),-(getTop()+moveY));
invalidate();
}
break;
}
return true;
}
}
需要注意的两点:
- 这个方法移动的 布局 的内容,不是自己
- 得加负号,大家自己尝试一下就明白了
Scroller 类
原理大家可以参考这篇文章 : Scroller与computeScroll处理滑动
package com.wust.SelfCoordinator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
/**
* ClassName: CanDragView <br/>
* Description: <br/>
* date: 2021/6/29 9:45<br/>
*
* @author yiqi<br />
* @QQ 1820762465
*/
@SuppressLint("AppCompatCustomView")
public class CanDragView extends TextView {
int startX;
int startY;
private Scroller scroller;
private int moveX;
private int moveY;
public CanDragView(Context context) {
this(context,null);
}
public CanDragView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CanDragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//第一步:创建 scroller 对象
scroller = new Scroller(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
{
startX =(int) event.getX();
startY =(int) event.getY();
}
break;
case MotionEvent.ACTION_MOVE:
{
int endX = (int) event.getX();
int endY = (int) event.getY();
moveX = endX - startX;
moveY = endY - startY;
System.out.println("moveX ->" + moveX + "moveY ->" + moveY);
//移动布局的关键性代码,scrollTo/scrollBy 移动的是 View中的内容 ViewGroup中的子View
//第二步:开始滚动
scroller.startScroll(getLeft(),getTop(), moveX, moveY);
//这个不能少,因为这个会调用 computeScroll()
invalidate();
}
break;
}
return true;
}
@Override
public void computeScroll() {
//第三步:编写 computeScroll,反复矫正
if (scroller.computeScrollOffset()){
scrollTo(getLeft()+moveX,getTop()+moveY);
invalidate();
}
super.computeScroll();
}
}
这个方法也是移动内容,和 scrollTo / scrollBy 一样。
ViewDragHelper 类
大家参考链接自行尝试。
以上是关于Android实现滑动的四种方式的主要内容,如果未能解决你的问题,请参考以下文章