Android实现控件滑动的几种方法

View滑动动画的选择及其left, marginLeft, translationX参数的总结 最近由于项目需要,做一个比较复杂的3D动画,核心就是根据手指的滑动来翻转3D效果。因此,又回顾了一下view滑动效果,而且根据不同的方式实现了一下,发现其中很多参数容易搞混,比如改变view的left,marginLeft,translationX中的任意一个值,对另外2个值及其getX是否有影响,因此,做了一下实验,发现挺有意思,结果如下:从上面的数据来看,这几个view的参数之间的值相互之间不影 阅读详情

当我们用手指滑动一个控件View,从本质上来说就是移动一个View,改变其当前所处的位置,它的实现原理与动画效果的实现类似,都是通过不断的改变View的坐标来实现这个效果。相比于老版本中的控件的操作是点击和长按,而目前基本上应用都利用了滑动的操作方式来增加用户的体验,所以有必要来了解下Android的控件滑动的几种方法。

在实现滑动效果之前,首先先认识下Android中窗口坐标体系和屏幕的触摸事件----MotionEvent.

Android获取控件的位置,一般有两类方法,一个是通过getRawX()、getRawY()方法,一个是通过getX()、getY()方法。而这两种方法获取的值,在意义上说是由区别的,前者是以系统屏幕上左上角顶点为原点;后者以父视图的左上角为坐标原点的。如下图所示:


触摸控制事件主要有以下几种动作::ACTION_DOWN,   ACTION_UP,   ACTION_MOVE,   ACTION_CANCEL,   ACTION_OUTSIDE,   ACTION_POINTER_DOWN , ACTION_POINTER_UP

       通常情况下,我们会在onTounchEvent(MotionEvent event)方法中通过event.getAction()的方法来获取触摸控件事件的类型,并使用switch-case方法进行筛选。代码如下:

 @Override
    public boolean onTouchEvent(MotionEvent event) {
       
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN://处理手指按下事件
               
                break;
            case MotionEvent.ACTION_MOVE://处理手指移动事件
              
                break;
            case MotionEvent.ACTION_UP://处理手指离开事件
               
               
                break;
        }
        return true;//表示本控件拦截触摸事件
    }

我们可以通过系统提供的API进行View的滑动,实现方法有多种,但基本思想都是一致的,即当触摸View时,系统记下当前触摸点的坐标,当手指移动时,系统记下移动后的触摸点坐标,从而获取到相对于前一次坐标点的偏移量,并通过偏移量来修改View的坐标,这样不断的重复,从而实现滑动的效果。

具体实现:首先新建一个View,在activity_main中新建。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="22dp"
        android:text="Button" />

    <com.example.news.DragView1
        android:id="@+id/my_drag_view"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignRight="@+id/button1"
        android:layout_below="@+id/button1"
        android:background="#354126" />

</LinearLayout>
这里多加了个button做参考物。

1.利用layout()方法

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class DragView1 extends View {

    private int lastX;
    private int lastY;

    public DragView1(Context context) {
        super(context);
    }

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

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

    // 视图坐标方式
    @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;
                // 在当前left、top、right、bottom的基础上加上偏移量
                layout(getLeft() + offsetX,
                        getTop() + offsetY,
                        getRight() + offsetX,
                        getBottom() + offsetY);
                break;
        }
        return true;
    }
}
上面使用的是getX()、getY()方法获取的坐标值,即通过视图View的坐标来获取的偏移量。当然,同样可以使用getRawX()、getRawY()方法老获取坐标。如下所示:

	
    @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 = rawY - lastX;
                int offsetY = rawY - lastY;
                // 在当前left、top、right、bottom的基础上加上偏移量
                layout(getLeft() + offsetX,
                        getTop() + offsetY,
                        getRight() + offsetX,
                        getBottom() + offsetY);
                //重新设置初始坐标
                lastX = rawX;
                lastY = rawY;
                break;
        }
        return true;
    }

注意:使用绝对坐标系后,在ACTION_MOVE的逻辑后,一定要重新设置初始坐标,这样才能准确地获取偏移量。


这里也可以利用setX(),setY()方法进行控件的滑动。

 float downX, downY;
    float moveX, moveY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            downX = event.getRawX();
            downY = event.getRawY();
        }

        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            moveX = event.getRawX();
            moveY = event.getRawY();

            this.setX(getX() + (moveX - downX));
            this.setY(getY() + (moveY - downY));
            downX = moveX;
            downY = moveY;
        }

        return true;// 返回true 表示 处理Touch事件
        // return super.onTouchEvent(event);
    }

2.offsetLeftAndRight()和offsetTopAndBottom()方法
这个相当于系统提供的对左右、上下移动API的封装,当计算出偏移量后,只要使用如下代码就可以完成View的重新布局,效果与使用Layout方法一样。代码如下:

//同时对left和right进行偏移设置
offsetLeftAndRight(offsetX);
//同时对Top和Bottom进行偏移设置
offsetTopAndBottom(offsetY);
3.LayoutParams
LayoutParams保存了一个View的布局参数,因此可以通过改变LayoutParams来动态地修改一个布局的位置参数,从而达到改变View位置的效果。可以通过getLayoutParams来获取一个Viewd LayoutParams。这里计算偏移量的方法和第一个Layout方法中的一样。当获取到偏移量后,通过设置setLayoutParams来改变其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 = (int) event.getX();
                lastY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                // 计算偏移量
                int offsetX = x - lastX;
                int offsetY = y - lastY;
		LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
              //ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
                setLayoutParams(layoutParams);
                break;
        }
        return true;
    }
如果我们使用下面的ViewGroup.Margin的话,使用更加方便,不需要考虑父布局。

4.scrollTo与scrollBy

在一个View中,系统提供了scrollTo、scrollBy两种方式来改变一个View的位置。这两个方法的区别也很好理解,scrollTo(x,y)表示移动到坐标点(x,y),scrollBy(x,y)表示移动的增量为x、y。

与前几种方式相同,在获取到偏移量后使用scrollBy来移动View,代码如下:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = (int) event.getX();
                lastY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - lastX;
                int offsetY = y - lastY;
                ((View) getParent()).scrollBy(-offsetX, -offsetY);
                break;
        }
        return true;
    }
可以看到的是在scrollBy中的参数设置的是为负数,这是因为我们要将画布内容相对于坐标轴正向移动,为此需要将偏移量改为负值。

5.属性动画
同样,使用属性动画,我们也可以控制View的移动效果。



文章参考自《Android群英传》




android之用scrollview实现控件滑动固定效果 项目中最近用到需要布局滑动到某一个地方的时候某个控件固定在屏幕顶部不动,就去研究了下,思路其实挺简单的,我置顶的悬浮控件上边还需要留个控件,比如搜索框之类的,看个人需求了 阅读详情

相关推荐

【Android 控件】解决 RecyclerView 和子控件之间的滑动冲突问题

如果没有调用 requestDisallowInterceptTouchEvent(true),当用户在 ProgressBar 上滑动时,RecyclerView 可能会拦截这些事件,导致 ProgressBar 无法正常滑动。这种冲突通常发生在 RecyclerView 的子项本身也支持滑动操作时,例如子项是一个 ProgressBar、WebView 或其他自定义的滑动视图。当用户在子控件上滑动时,可能会触发 RecyclerView 的滑动,从而导致子控件滑动异常。

casual_clover的博客 1491

Android知识点记录-滚动控件(RecylerView)

安卓知识点记录-滚动控件:ListView和RecyclerView。

weixin_45762669的博客 1497

【Android】自定义控件实现可滑动的开关(switch)

~转载请注明来源:http://blog.youkuaiyun.com/u013015161/article/details/46704745介绍最近项目里有要用到滑动开关, 即SlideSwitch,就自己写了一个。效果如下: 实现实现的思路其实很简单,监听控件上的touch事件,并不断刷新,让滑块在手指的位置上绘出,达到滑块跟着手指滑动的显示效果。 先看一下代码: SlideSwitch.javapa

Lankton 8425

滑动选择控件的简单使用

com.github.gzuliyujiang.wheelview.widget.WheelView滑动选择控件的简单使用

oAiYinSiTan12的博客 696

android开源堆叠滑动控件,类似探探

StackCardsView堆叠滑动控件,类似于社交软件探探的效果,并增加以下扩展: 支持滑动方向控制 支持消失方向控制 支持嵌入到ViewPager等滑动控件 支持内嵌ListView,RecycleView等滑动控件 效果演示         如何使用 xml引入StackCardsView: <com.beyondsw.lib.widget.StackCardsView

wensefu的技术专栏 3946

Android技术知识点:什么是外边距(margin)

Android技术知识点:什么是外边距(margin)

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 3840

android 上下滑动如何实现

上下滑动其实就是一个控件: &lt;ScrollView android:id="@+id/sv" android:layout_width="fill_parent" android:layout_height="wrap_content" &gt; &lt;!--这里是你自己要加的内容,只要内容大于一屏,就会滚动--&gt; &lt;/ScrollView&gt; 对于安卓滑动界面,很常见、简..

qq_41256114的博客 1万+

android左右滑动的选择控件

android实现的可左右滑动的选择控件

Android ScrollView向上滑动控件顶部悬浮效果实现

本文参考了:《上滑停靠顶端的悬浮框》的代码,在此表示感谢。【上滑停靠顶端的悬浮框】里的实现方法是使用两个控件,滑动时,监听ScrollView的滚动Y值,从而通过对两个控件的显示隐藏来实现控件的顶部悬浮。但是实际应用场景中,有可能需要悬浮的控件里面的内容是比较多的,如果通过显示隐藏的方式来实现的话,操作控件里的内容时,需要重复定义两套变量,对控件里的内容进行修改时也是要操作再次,非常麻烦。 本文的方法是通过addView和removeView来实现的。

梦想天涯的专栏 1万+

Android 滑动效果 自定义控件

Android 滑动效果 自定义控件 ViewGroup 属性

cpp中auto, auto &和const auto &的区别

笔者初学cpp,如有纰漏,请见谅并指正。 用在哪 auto用于推断类型,具体可用于声明变量时根据初始化表达式自动推断该变量的类型,也就是可用在for循环。 也可以用于声明函数返回值的占位符。 怎么用 这里主要讲for循环中三者的区别 直接说结论 auto auto用于copy一份集合中的数据,对于这种情况,在循环体中不论怎么修改copy的数据,是不会影响到原有集合中的数据的。 举个简单的例子 int arr[5] = {0, 1, 2, 3, 4}; cout << "使用auto" <&

NinoSun的博客 3176

SlidingDrawerLayout上下滑动的菜单控件

有一种控件需求,通过上下滑动来打开上下菜单。这个控件要求自动打开上下两个菜单,而且还要随着手势(注意:多触点)上下滑动菜单。之前Android系统有提供一个叫SlidingDrawer(完整路径:android.widget.SlidingDrawer)的控件,似乎有类似的效果,但是它不仅过时了,而且远远达不到我提出的要求。为了满足这个需求,我设计了一款自名为SlidingDrawerLayout的控件。

ljj1396847724的博客 5391

告别手动归档:基于Allegro Skill的XTools一键生成Gerber与生产文件实践

本文详细介绍了基于Allegro Skill的XTools工具如何实现一键生成Gerber与生产文件,大幅提升PCB设计效率。通过自动化流程,解决了传统手动归档中的重复劳动、人为失误和标准不统一等问题,特别适合需要频繁输出生产文件的工程师。文章包含安装配置、实战操作、问题排查及进阶技巧,帮助用户快速掌握这一高效工具。

weixin_30505225的博客 461

Android自定义控件之滑动解锁

代码参考地址 https://github.com/liuzhiyuan0932/SlideUnLock 代码效果图> 自定义滑动解锁的控件继承自Viewpublic class SlideUnlockView extends View 自定义SlideUnLockView的属性 在values文件夹中定义属性 <?xml version="1.0" encoding="

zhiyuan0932的博客 6万+

【项目立项管理、项目整合管理】30天通过软考高项-第二天

①项目或阶段的概述;②范围目标、范围的评估标准,证明达到完⼯标准的证据;③质量目标、项目和产品质量的评估标准、相关核实信息和实际里程碑交付日期以及偏差原因;④成本目标,包括可接受的成本区间、实际成本,产⽣任何偏差的原因等;⑤最终产品、服务或成果的确认信息的总结;⑥进度计划目标,包括成果是否实现项目预期效益:如果在项目结束时未能实现效益,则指出效益实现程度并预计未来实现情况;

weixin_42520723的博客 1000

别再搞混了!MATLAB通信仿真中EbN0转SNR的保姆级公式推导与避坑指南

本文深入解析MATLAB通信仿真中EbN0与SNR转换的核心公式,揭示数字仿真与理论系统的关键差异。通过真实案例展示错误参数设置导致的隐蔽问题,并提供完整的参数自查清单和正确实现代码,帮助工程师和学生避免常见错误,确保仿真结果准确可靠。

weixin_28746223的博客 348

Android中实现滑动的7种方法

Android中实现滑动的7种方法前置知识Android坐标系视图坐标系触控事件---MotionEvent获取坐标的方法实现滑动的7种方法layout方法offsetLeftAndRight()和offsetTopAndBottom()LayoutParamsscrollTo和scrollByScroller属性动画ViewDragHelper参考 前置知识 Android坐标系 Android坐标系以屏幕的左上角这个点为原点,向右为x轴正方向,向下为y轴正方向;可以使用getLocationOnScre

wsb_2526的博客 3109

第二十届全国大学生智能汽车竞赛极速光电组:MicroPython与恩智浦RT1021的硬件编程实战指南

本文为参加第二十届全国大学生智能汽车竞赛极速光电组的同学提供了一份详尽的MicroPython与恩智浦RT1021硬件编程实战指南。文章深入剖析了选择MicroPython与RT1021这对组合的优势,详细讲解了从开发环境搭建、基础硬件控制(如GPIO、PWM、编码器、CCD)到系统集成(平衡控制、循迹算法)与多任务调试的全过程,旨在帮助参赛者降低嵌入式开发门槛,高效备赛。

wdx0123456的博客 843

安卓ScrollView向上滑动控件顶部悬浮效果实现

文章目录效果图实现思路代码布局、逻辑布局文件自定义ViewNorthernScrollViewListener.javaMainActivity.java 效果图 如果你要的不是以下的效果,请停止浏览文章,不要浪费时间! 从上打下动漫依次是:《东京喰种》《魁拔》《海贼王》《名侦探柯南》《学院默示录》《你的名字》《神兵小将》《铁臂阿童木》《猫和老鼠》《虹猫蓝兔七侠传》《太空历险记》《洛洛历险记》《...

两行代码 踏踏实实de工作 7055

YOLOv12改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

1️⃣ 什么!不知道如何改进模型⁉️ 本专栏所使用并改进的每一个模块均包含详细的模块分析、原理讲解、个人总结、多种改进方式以及完整的修改流程,所有改进100%可直接运行,性价比极高。2️⃣ 找不到合适的模块⁉️ 所有改进点均为近三年顶会,顶刊提出的先进算法,将其融入到中,并进行二次创新,新颖度高,创新度高,能够适应不同的任务场景。3️⃣ 不确定自己改进的步骤、结果是否正确⁉️ 订阅专栏即可进群享受模型训练、模型改进、论文写作、投稿选刊,从入门到论文的各种答疑内容,非常适合新手。4️⃣ 团队内发表数篇SCI论

Limiiiing的博客 2万+

【第一章】基于Simulink的控制器开发教程——目录

摘要:本文系统介绍了基于Simulink的控制器开发方法,涵盖PID、状态反馈、模型预测(MPC)、模糊控制、自适应控制等8类主流控制器。针对每种控制器,详细阐述了其基本原理、适用场景,并通过Simulink建模与仿真测试进行实践验证。文章采用"理论+实践"的结构,从算法设计到硬件实现全流程展开,为汽车、航空航天、工业控制等领域的控制器开发提供完整解决方案,最后通过应用对比与学习总结帮助读者掌握不同控制器的核心特性和应用场景。(149字)

熟悉MATLAB/fpga/RK3588/LABVIEW/protus/单片机/dsp/Multisim 387

android 水平滑动的控件

HorizontalScrollview android 水平滑动的控件

u011979273的专栏 2519

使用Simulink进行基于IIR滤波器的设计与稳定性分析仿真

IIR滤波器的稳定性与其系统函数的极点位置密切相关。如果所有极点都位于Z平面的单位圆内,则该滤波器是稳定的;否则,滤波器将是不稳定的。在设计IIR滤波器时,确保其稳定性对于避免输出信号发散至关重要。明确你的系统需求,比如输入信号类型(如正弦波)、采样率、IIR滤波器的设计参数(如滤波器类型、阶数、截止频率等)。假设我们需要设计一个低通IIR滤波器,用来去除高于500Hz的所有频率成分,保留低于500Hz的信号成分。采样率为8kHz。

xiaoheshang_123的博客 150

android控件左右滑动,上下滑动监听

主要是有时候一些控件,你需要对控件的滑动情况做判断,恰好遇到这个,写个日志记录一下,你们看到的人,就直接用这个代码吧 1.运行效果:手机运行,滑动对照着日志测试了很多遍,发现很准确,没有出错的情况 04-18 18:03:42.631 31286-31286/com.example.longshine.zname E/TAG: wang向右 04-18 18:03:43.981 31286-...

cf8833的博客 2948

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Android无限滑动控件实现

无限滑动控件 无限滑动控件的预期效果是添加有限个View实现无限滑动的效果。 我的实现是通过重写dispatchDraw,对canvas画布进行偏移达到无限滑动的效果。 效果如图: github地址:https://github.com/BigPig-LittleTail/cyclePager 实现原理 一个View时 蓝色为绘制出的内容 灰色的为布局位置 黑色矩形框...

BigPig_LittleTail的博客 1500

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

上一篇: Android利用DrawerLayout实现侧滑菜单
下一篇: 华为2016研发工程师编程题---删数
android_cmos
博客等级 码龄12年 177粉丝 73原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值