`

【转】Android View体系(二)实现View滑动的六种方法

阅读更多

1.View的滑动简介

View的滑动是Android实现自定义控件的基础,同时在开发中我们也难免会遇到View的滑动的处理。其实不管是那种滑动的方式基本思想都是类似的:当触摸事件传到View时,系统记下触摸点的坐标,手指移动时系统记下移动后的触摸的坐标并算出偏移量,并通过偏移量来修改View的坐标。 
实现View滑动有很多种方法,这篇文章主要讲解六种滑动的方法,分别是:layout()、offsetLeftAndRight()与offsetTopAndBottom()、LayoutParams、动画、scollTo与scollBy和Scroller;在下一篇文章我们会详细介绍属性动画。

2.实现View滑动的六种方法

layout()

view进行绘制的时候会调用onLayout()方法来设置显示的位置,因此我们同样也可以通过修改View的left、top、right、bottom这四种属性来控制View的坐标。首先我们要自定义一个View,在onTouchEvent()方法中获取触摸点的坐标:

   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;

...

 

接下来我们在ACTION_MOVE事件中计算偏移量,再调用layout()方法重新放置这个自定义View的位置就好了:

 

 case MotionEvent.ACTION_MOVE:  //计算移动的距离                 
 int offsetX = x - lastX;
 int offsetY = y - lastY;
 //调用layout方法来重新放置它的位置
 layout(getLeft()+offsetX, getTop()+offsetY,
                  getRight()+offsetX , getBottom()+offsetY);
 break;

 

当我们每次移动时都会调用layout()方法来对自己重新布局,从而达到移动View的效果。

自定义View的全部代码(CustomView.java):

 

package com.example.liuwangshu.moonviewslide;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class CustomView extends View {
    private int lastX;
    private int lastY;

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

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

    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;
                //调用layout方法来重新放置它的位置
                layout(getLeft()+offsetX, getTop()+offsetY,
                        getRight()+offsetX , getBottom()+offsetY);
                break;
        }

        return true;
    }
}

 

布局中引用自定义View:

 

<?xml version="1.0" encoding="utf-8"?>
<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">

    <com.example.liuwangshu.moonviewslide.CustomView
        android:id="@+id/customview"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="50dp"
        android:background="@android:color/holo_red_light" />
</LinearLayout>

offsetLeftAndRight()与offsetTopAndBottom()

这两种方法和layout()方法效果方法差不多,使用也差不多,我们将ACTION_MOVE中的代码替换成如下代码:

            case MotionEvent.ACTION_MOVE:
                //计算移动的距离
                int offsetX = x - lastX;
                int offsetY = y - lastY;
                //对left和right进行偏移
                offsetLeftAndRight(offsetX);
                //对top和bottom进行偏移
                offsetTopAndBottom(offsetY);
                break;

LayoutParams(改变布局参数)

LayoutParams主要保存了一个View的布局参数,因此我们可以通过LayoutParams来改变View的布局的参数从而达到了改变View的位置的效果。同样的我们将ACTION_MOVE中的代码替换成如下代码:

 

  LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
                setLayoutParams(layoutParams);

 

因为父控件是LinearLayout,所以我们用了LinearLayout.LayoutParams,如果父控件是RelativeLayout则要使用RelativeLayout.LayoutParams。除了使用布局的LayoutParams外,我们还可以用ViewGroup.MarginLayoutParams来实现:

 

                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
                setLayoutParams(layoutParams);

动画

可以采用View动画来移动,在res目录新建anim文件夹并创建translate.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="300" android:duration="1000"/>
</set>

 

在Java代码中引用:

 

  mCustomView.setAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));

 

当然使用属性动画移动那就更简单了,我们让CustomView在1000毫秒内沿着X轴像右平移300像素:

 

ObjectAnimator.ofFloat(mCustomView,"translationX",0,300).setDuration(1000).start();
  • 1

scollTo与scollBy

scollTo(x,y)表示移动到一个具体的坐标点,而scollBy(dx,dy)则表示移动的增量为dx、dy。其中scollBy最终也是要调用scollTo的。scollTo、scollBy移动的是View的内容,如果在ViewGroup中使用则是移动他所有的子View。我们将ACTION_MOVE中的代码替换成如下代码:

 ((View)getParent()).scrollBy(-offsetX,-offsetY);

 

这里要实现CustomView随着我们手指移动的效果的话,我们就需要将偏移量设置为负值。

Scroller

我们用scollTo/scollBy方法来进行滑动时,这个过程是瞬间完成的,所以用户体验不大好。这里我们可以使用Scroller来实现有过度效果的滑动,这个过程不是瞬间完成的,而是在一定的时间间隔完成的。Scroller本身是不能实现View的滑动的,它需要配合View的computeScroll()方法才能弹性滑动的效果。 
在这里我们实现CustomView平滑的向右移动。

  • 首先我们要初始化Scroller:
  public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }
  • 接下来重写computeScroll()方法,系统会在绘制View的时候在draw()方法中调用该方法,这个方法中我们调用父类的scrollTo()方法并通过Scroller来不断获取当前的滚动值,每滑动一小段距离我们就调用invalidate()方法不断的进行重绘,重绘就会调用computeScroll()方法,这样我们就通过不断的移动一个小的距离并连贯起来就实现了平滑移动的效果:
    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mScroller.computeScrollOffset()){
            ((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
        }
        //通过不断的重绘不断的调用computeScroll方法
        invalidate();
    }
  • 调用Scroller.startScroll()方法。我们在CustomView中写一个smoothScrollTo()方法,调用Scroller.startScroll()方法,在2000毫秒内沿X轴平移delta像素:
  public void smoothScrollTo(int destX,int destY){
        int scrollX=getScrollX();
        int delta=destX-scrollX;
        //1000秒内滑向destX
        mScroller.startScroll(scrollX,0,delta,0,2000);
        invalidate();
    }
  • 最后我们在ViewSlideActivity.java中调用CustomView的smoothScrollTo()方法:
          //使用Scroll来进行平滑移动
          mCustomView.smoothScrollTo(-400,0);

这里我们是设定CustomView沿着X轴向右平移400像素。

分享到:
评论

相关推荐

    android中实现左右滑动View

    综上所述,实现Android中的左右滑动View涉及到了布局管理、触摸事件处理、动画效果等多个方面,通过合理的设计和编码,可以创造出既美观又易用的滑动界面。同时,理解项目文件结构有助于更好地维护和管理Android应用...

    View滑动的三种实现方法

    本文将详细介绍三种实现View滑动的方法:ScrollBy/ScrollTo、动画(Animation)以及修改LayoutParams。 1. **ScrollBy/ScrollTo方法** `ScrollBy()` 和 `ScrollTo()` 是 Android 中 View 类提供的两个方法,用于...

    android 十字架效果实现(水平和垂直滑动)

    "android 十字架效果实现(水平和垂直滑动)"是一个这样的实例,它涉及到Android自定义View的绘制以及手势识别技术。这个效果允许用户通过水平或垂直滑动来操作一个呈现十字架形状的元素,为用户界面增添动态交互性...

    Android listview滑动删除以及view滑动的实现

    在TestView中,你可能已经实现了对View滑动的基本逻辑。进行滑动测试时,可以模拟不同方向和速度的滑动,检查View的行为是否符合预期。同时,也可以利用Android的JUnit或Espresso测试框架,编写自动化测试用例来验证...

    Android-自定义蚂蜂窝app滑动tab实现波浪线滑动View

    本文将深入探讨如何实现“Android-自定义蚂蜂窝app滑动tab实现波浪线滑动View”的功能,这属于Android开发中的“其它控件”类别。 首先,我们需要理解“蚂蜂窝app滑动tab”的概念。滑动tab通常指的是...

    android 纵向滑动页面(上下滑动效果)

    在Android开发中,创建一个能够实现纵向滑动,即上下滑动效果的页面是一项常见的任务。这样的效果常常用于实现如滚动列表、轮播图或阅读器等应用功能。本教程将详细讲解如何在Android中实现这样的功能,并结合提供的...

    Android自定义View——滑动变色指示器

    在类中,我们需要重写几个关键方法来实现滑动变色指示器的功能: 1. `onDraw(Canvas canvas)`: 这是自定义View的核心,我们在其中绘制指示器的图形。通常,我们会使用`canvas.drawColor()`来填充背景颜色,然后使用...

    Android-Android实现了可以滑动左侧边缘退出Activity的功能

    在Android应用开发中,滑动边缘退出Activity是一种常见的交互设计,它可以提供更加直观和便捷的用户界面体验。本文将深入探讨如何在Android中实现这一功能,主要涉及Android自定义手势识别、视图层级管理和Activity...

    安卓Android 排班自定义view 支持左右上下滑动 支持点击事件,支持更改每个框的内容

    标题提到的"安卓Android 排班自定义view 支持左右上下滑动 支持点击事件,支持更改每个框的内容",这是一个专为排班场景设计的自定义View组件,它具有高度的可定制性和交互性。 首先,这个自定义View能够实现左右...

    Android:自定义View实现随滑动由箭头变对勾的指示按钮

    本篇文章将深入探讨如何实现一个名为"MagicButton"的自定义View,该按钮在用户滑动时能从箭头形态平滑过渡到对勾形态,为用户提供一种直观的反馈机制。 首先,我们需要创建一个新的Java类,继承自`View`或`Button`...

    Android实现图片左右滑动效果

    在Android开发中,实现图片左右滑动效果是常见的需求,比如在查看相册或轮播图时。这个功能可以通过多种方式实现,其中最常用的是使用ViewPager组件。ViewPager允许用户通过左右滑动手势在多个页面之间切换,非常...

    Android-CardStackView-实现类似Tinder的Android滑动式卡片视图

    在Android应用开发中,创建吸引用户的交互体验是至关重要的,而`CardStackView`就是一种实现这种体验的有效工具。这个库允许开发者构建类似Tinder应用的卡片滑动界面,用户可以左右滑动卡片来浏览或操作内容。在这个...

    Android-使用recyclerView实现画廊滑动效果

    item.xml)、适配器类(如GalleryAdapter.java)以及主活动类(如MainActivity.java),通过学习和分析这些文件,你可以更好地理解和掌握如何在Android应用中实现画廊式的RecyclerView滑动效果。记得在实际操作时,...

    Android实现导航菜单左右滑动效果

    本文将详细讲解如何在Android平台上实现一个左右滑动的导航菜单,这种效果通常被用于展示多个主选项,用户可以通过平滑的手势在各个页面之间切换。 首先,实现这个功能的关键是使用`android.support.v4.view....

    Android 实现横向滑动的GridView

    本篇文章将详细讲解如何在Android中实现一个横向滑动的GridView。 首先,了解GridView的基本概念。GridView继承自AbsListView,它会将数据集中的每个项显示为一个单元格,并且可以自动调整列的数量以适应屏幕宽度。...

    Android viewpager实现竖向滑动demo

    在Android开发中,ViewPager是一个非常常用的组件,它主要用于展示多个Fragment或者View,并且可以左右滑动切换页面。然而,标准的ViewPager默认支持的是水平滑动,即从左到右或从右到左切换页面。在某些场景下,...

    【原创】Android自定义View实现图片显示并能缩放、拖拽、切换

    在Android开发中,自定义View是...理解并掌握自定义View的原理和实现方法,是成为一名出色的Android开发者不可或缺的一部分。通过不断实践和学习,你将能够创建出更加复杂、功能强大的自定义组件,提升应用的用户体验。

    Android实现View拖动 可拖动窗口 View 示例ViewDragHelper

    这将启动一个平滑的动画,将View滑动到指定位置。 通过以上步骤,你就可以实现一个基本的可拖动View。在`DragTest`项目中,你可以找到一个具体的示例,演示了如何创建一个可以拖动的窗口或视图。通过阅读和理解代码...

    android横向滑动选择的View

    综上所述,创建一个自定义的横向滑动选择View涉及到了Android UI体系的基础知识,包括View的继承与重写、触摸事件的处理、测量与布局的逻辑,以及平滑滚动的实现。通过理解并应用这些概念,开发者可以构建出具有独特...

    Android Scroller实现View弹性滑动Demo

    `Scroller`主要用于处理View的弹性滑动效果,比如在ScrollView、ViewPager或者自定义View中实现平滑滚动和回弹效果。这个Demo就是演示如何使用`Scroller`来实现View的弹性滑动。 首先,理解`Scroller`的工作原理是...

Global site tag (gtag.js) - Google Analytics