• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android中View实现弹性滑动的方法——Android开发艺术探索笔记

Android中View实现弹性滑动的方法——Android开发艺术探索笔记

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android recyclerview,android scrollview,android surfaceview,android photoview,android wheelview等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android中View实现弹性滑动的方法——Android开发艺术探索笔记


介绍

弹性滑动也就是渐进式滑动,实现弹性滑动的方法有很多,但是他们都有一个共同的思想:将一次大的滑动分成若干次小的滑动并在一段时间内完成。本文主要介绍三种弹性滑动方式,Scroller、动画和Handler。

本文中的“滑动”是指View内容的滑动而非View本身位置的改变。

示例

点击屏幕任意地方,手指与屏幕接触时,触发ACTION_DOWN屏幕中的文字会向上滑动400px,手指离开屏幕时触发ACTION_UP文字下滑400px。

示例

基础知识补充

View的宽高和坐标关系:width = right - left,height = top - bottom。 View在平移过程中,top和left表示的是原始左上角的位置信息,其值不会改变,发生改变的是x、y、translationX、translationY这四个参数。 x是View左上角的坐标,translation是view移动后相对于父容器的偏移量,所以有x = left + translationX。y的原理相同。 getX/getY返回的是相对于当前View左上角的x和y坐标,而getRawX/getRawY返回的是相对于手机屏幕左上角的x和y坐标。

使用Scroller

private void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int detlaX = destX - scrollX;
        int scrollY = getScrollY();
        int detlaY = destY - scrollY;
        Log.d(TAG, "smoothScrollTo:scrollY, detlaY= " + scrollY+" " + detlaY);
        mScroller.startScroll(scrollX, scrollY, detlaX, detlaY, 1000);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
    }

上面是使用Scroller实现弹性滑动的一个典型方法。

实现原理为:Scroller本身无法让View弹性滑动,它需要和View的computeScroll方法配合使用才能共同完成这个功能。在startScroll()方法下调用了invalidate(),这使得View重绘,View重绘的时候会在draw方法中调用computeScroll(),在此方法中调用scrollTo滑向指定位置。之后再通过postInvalidate()进行二次重绘,如此重复直到滑动结束。

下面是computeScrollOffset()这个函数的源码。从中可以看出判断滑动是否结束是以timePassed为标准的。

/**
     * Call this when you want to know the new location.  If it returns true,
     * the animation is not yet finished.
     */ 
    public boolean computeScrollOffset() {
        if (mFinished) {
            return false;
        }

        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);

        if (timePassed < mDuration) {
            switch (mMode) {
            case SCROLL_MODE:
                final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
                mCurrX = mStartX + Math.round(x * mDeltaX);
                mCurrY = mStartY + Math.round(x * mDeltaY);
                break;
            case FLING_MODE:
            ...
            ...
                break;
            }
        }
        else {
            mCurrX = mFinalX;
            mCurrY = mFinalY;
            mFinished = true;
        }
        return true;
    }

使用动画

    private static final int FRAME_COUNT = 30;
    final int startX = 0;
    final int deltaX = 100;
    ValueAnimator animator = ValueAnimator.ofInt(0,1).setDuration(1000);
    animator.addUpdateListener(new AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animator) {
            float fraction = animator.getAnimatedFraction();
            mButton1.scrollTo(startX + (int) (deltaX * fraction), 0);
        }
    });
    animator.start();

上述代码中,动画本质上没有作用于任何对象上,只是在1000ms内完成了整个动画过程。这个方法scrollTo(startX + (int) (deltaX * fraction), 0)使得动画每次更新时view都滑动一点。

使用Handler

    private static final int MESSAGE_SCROLL_TO = 1;
    private static final int DELAYED_TIME = 33;

 private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_SCROLL_TO: {
                mCount++;
                if (mCount <= FRAME_COUNT) {
                    float fraction = mCount / (float) FRAME_COUNT;
                    int scrollX = (int) (fraction * 100);
                    mButton1.scrollTo(scrollX, 0);
                    mHandler.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO, DELAYED_TIME);
                }
                break;
            }

            default:
                break;
            }
        };
    };

在Handler的handleMessage中调用View的scrollTo方法滑动一些距离,紧接着再向Handler发送一个Delay的消息再次滑动。关键方法mHandler.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO, DELAYED_TIME)。

示例动画效果的源码

示例中的动画效果是在一个TextView进行的,滑动的是TextView中的文字。源码如下。


/**
 * Created by Spark on 2/22/2016 21:12.
 */

public class ElasticText extends TextView {
    private static final String TAG = "ElasticText";
    private Scroller mScroller;
    private VelocityTracker mVelocityTracker;

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

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

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

    private void init() {
        mScroller = new Scroller(getContext());
        mVelocityTracker = VelocityTracker.obtain();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                Log.d(TAG, "onTouchEvent: ActionDown");
                mScroller.startScroll(getScrollX(), getScrollY(), 0, 400, 600);
                invalidate();
                break;
            }
            case MotionEvent.ACTION_MOVE: {

                break;
            }
            case MotionEvent.ACTION_UP: {
                Log.d(TAG, "onTouchEvent: ACTION_UP");
                mScroller.startScroll(getScrollX(), getScrollY(), 0, -400, 600);
                invalidate();
                break;
            }
            default:
                break;
        }

        return true;
    }

    private void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int detlaX = destX - scrollX;
        int scrollY = getScrollY();
        int detlaY = destY - scrollY;
        mScroller.startScroll(scrollX, scrollY, detlaX, detlaY, 1000);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
        }
    }
}

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 在Kotlin编写RecyclerView适配器(KAD 16),kotlinrecyclerview
  • 深入理解 Android 之 View 的绘制流程,androidview
  • RecyclerView在软键盘弹出时自动调整内容技巧,recyclerview技巧
  • RecyclerView的五大开源项目-解决办法
  • Android View分区域点击实现方案——1.根据坐标范围
  • 【读书笔记】【Android 开发艺术探索】第3章 View 的事件体系
  • Android View体系(六)从源码解析Activity的构成
  • RecyclerView再封装,RecyclerView封装
  • Android中View的滑动冲突——Android开发艺术探索笔记
  • Android View体系(二)实现View滑动的六种方法

相关文章

  • 2017-05-26redis使用内存调整及优化
  • 2017-05-26android工程师这么面试就能拿高薪,android高薪
  • 2017-05-26APP级别处理未捕获异常,APP级别处理捕获
  • 2017-05-26Android合并两个APP的具体做法(掌握)
  • 2017-05-26Android开发10:传感器器及地图相关应用,android传感器
  • 2017-05-26安卓第十二天笔记-广播,安卓第十二天广播
  • 2017-05-26Kotlin与Android SDK 集成(KAD 05),kotlinandroid
  • 2017-05-26ORB_SLAM2在Android上的移植过程
  • 2017-05-26LocationManager使用细节,locationmanager
  • 2017-05-26android中实现在矩形框中输入文字,可以显示剩余字数的功能,android字数

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 【Android性能工具】腾讯开源工具APT,androidapt
    • 硅谷新闻11--极光推送的集成,硅谷新闻11--极光
    • 硅谷社交3--登录页面,硅谷社交3--
    • redis使用内存调整及优化
    • ListView中响应item的点击事件并且刷新界面,listviewitem
    • zabbix监控tomcat出现"Connection refused to host: 127.0.0.1"的故障解决
    • ListView嵌套出现的问题,listview嵌套出现
    • Service的启动与停止、绑定与解绑,service停止绑定
    • HBase Thrift2 CPU过高问题分析
    • Android-ViewPager的使用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有