文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android怎么实现橡皮筋回弹和平移缩放效果

2023-06-30 05:41

关注

这篇文章主要介绍“Android怎么实现橡皮筋回弹和平移缩放效果”,在日常操作中,相信很多人在Android怎么实现橡皮筋回弹和平移缩放效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android怎么实现橡皮筋回弹和平移缩放效果”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

代码实现

这里我写把效果分开来写,最后再合并

平移、缩放

mLayout.java

import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.FrameLayout;import android.widget.Scroller;public class mLayout extends FrameLayout{    // 属性变量    private float translationX; // 移动X    private float translationY; // 移动Y    private float scale = 1; // 伸缩比例    // 移动过程中临时变量    private float actionX;    private float actionY;    private float spacing;    private int moveType; // 0=未选择,1=拖动,2=缩放    private float firstX;    private float firstY;    public mLayout(Context context) {        this(context, null);    }    public mLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public mLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        switch (event.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:                moveType = 1;                actionX = event.getRawX();                actionY = event.getRawY();                firstX = actionX;                firstY = actionY;                break;            case MotionEvent.ACTION_POINTER_DOWN:                moveType = 2;                spacing = getSpacing(event);                break;            case MotionEvent.ACTION_MOVE:                if (moveType == 1) {                    translationX = translationX + event.getRawX() - actionX;                    translationY = translationY + event.getRawY() - actionY;                    System.out.println();                    setTranslationX(translationX);                    setTranslationY(translationY);                    actionX = event.getRawX();                    actionY = event.getRawY();                }                else if (moveType == 2) {                    scale = scale * getSpacing(event) / spacing;                    if(scale >= 1){                        setScaleX(scale);                        setScaleY(scale);                    }else{                        scale = 1;                    }                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_POINTER_UP:                moveType = 0;                break;        }        return true;    }    // 触碰两点间距离    private float getSpacing(MotionEvent event) {        //通过三角函数得到两点间的距离        float x = event.getX(0) - event.getX(1);        float y = event.getY(0) - event.getY(1);        return (float) Math.sqrt(x * x + y * y);    }}

橡皮筋回弹

import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.FrameLayout;import android.widget.Scroller;public class mLayout extends FrameLayout{    //系数可自己更改    private static final float DEFAULT_FATOR = 0.4f;        private float mFator = DEFAULT_FATOR;    private Scroller mScroller;        private MotionEvent mLastMotionEvent;    public mLayout(Context context) {        this(context, null);    }    public mLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public mLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mScroller = new Scroller(context);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mLastMotionEvent = MotionEvent.obtain(event);                break;            case MotionEvent.ACTION_MOVE:                int dx = (int) (event.getRawX() - mLastMotionEvent.getRawX());                int dy = (int) (event.getRawY() - mLastMotionEvent.getRawY());                //如果不想对四个方向增加阻尼效果,直接删除即可                //向上平移                if ((Math.abs(dx) < Math.abs(dy)) && dy < 0){                    smoothScrollBy(0, -(int) (dy * mFator));                }                //向下平移                else if (Math.abs(dx) < Math.abs(dy) && dy > 0) {                    smoothScrollBy(0, -(int) (dy * mFator));                }                //向左平移                else if (Math.abs(dx) > Math.abs(dy) && dx < 0){                    smoothScrollBy(-(int) (dx * mFator), 0);                }                //向右平移                else if (Math.abs(dx) > Math.abs(dy) && dx > 0){                    smoothScrollBy(-(int) (dx * mFator), 0);                }                mLastMotionEvent = MotionEvent.obtain(event);                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                smoothScrollTo(0, 0);                break;        }        return true;    }    private void smoothScrollBy(int dx, int dy) {        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);        invalidate();    }    private void smoothScrollTo(int fx, int fy) {        int dx = fx - mScroller.getFinalX();        int dy = fx - mScroller.getFinalY();        smoothScrollBy(dx, dy);    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());            postInvalidate();        }        super.computeScroll();    }}

平移、缩放、阻尼效果合并

import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.FrameLayout;import android.widget.Scroller;public class mLayout extends FrameLayout{    private float scale = 1; // 伸缩比例    // 移动过程中临时变量    private float actionX;    private float actionY;    private float spacing;    private int moveType; // 0=未选择,1=拖动,2=缩放    private float firstX;    private float firstY;    //系数可自己更改    private static final float DEFAULT_FATOR = 0.4f;        private float mFator = DEFAULT_FATOR;    private Scroller mScroller;        private MotionEvent mLastMotionEvent;    public mLayout(Context context) {        this(context, null);    }    public mLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public mLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mScroller = new Scroller(context);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        switch (event.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:                mLastMotionEvent = MotionEvent.obtain(event);                moveType = 1;                actionX = event.getRawX();                actionY = event.getRawY();                firstX = actionX;                firstY = actionY;                break;            case MotionEvent.ACTION_POINTER_DOWN:                moveType = 2;                spacing = getSpacing(event);                break;            case MotionEvent.ACTION_MOVE:                if (moveType == 1) {                    int dx = (int) (event.getRawX() - mLastMotionEvent.getRawX());                    int dy = (int) (event.getRawY() - mLastMotionEvent.getRawY());                    //如果不想对四个方向增加阻尼效果,直接删除即可                    //向上平移                    if ((Math.abs(dx) < Math.abs(dy)) && dy < 0){                        smoothScrollBy(0, -(int) (dy * mFator));                    }                    //向下平移                    else if (Math.abs(dx) < Math.abs(dy) && dy > 0) {                        smoothScrollBy(0, -(int) (dy * mFator));                    }                    //向左平移                    else if (Math.abs(dx) > Math.abs(dy) && dx < 0){                        smoothScrollBy(-(int) (dx * mFator), 0);                    }                    //向右平移                    else if (Math.abs(dx) > Math.abs(dy) && dx > 0){                        smoothScrollBy(-(int) (dx * mFator), 0);                    }                    mLastMotionEvent = MotionEvent.obtain(event);                }                else if (moveType == 2) {                    scale = scale * getSpacing(event) / spacing;                    if(scale >= 1){                        setScaleX(scale);                        setScaleY(scale);                    }else{                        scale = 1;                    }                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_POINTER_UP:            case MotionEvent.ACTION_CANCEL:                moveType = 0;                if(scale == 1)                    smoothScrollTo(0, 0);                break;        }        return true;    }    private void smoothScrollBy(int dx, int dy) {        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);        invalidate();    }    private void smoothScrollTo(int fx, int fy) {        int dx = fx - mScroller.getFinalX();        int dy = fx - mScroller.getFinalY();        smoothScrollBy(dx, dy);    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());            postInvalidate();        }        super.computeScroll();    }    // 触碰两点间距离    private float getSpacing(MotionEvent event) {        //通过三角函数得到两点间的距离        float x = event.getX(0) - event.getX(1);        float y = event.getY(0) - event.getY(1);        return (float) Math.sqrt(x * x + y * y);    }}

使用方法

在xml文件中添加mLayout布局,便可对mLayout里面的控件和布局进行平移、缩放、阻尼效果的操作

功能扩展&mdash;&mdash;在布局中添加button

如果我们在mLayout布局中添加button,那么会出现获取焦点冲突的问题,导致触摸到按钮时无法进行平移等操作,因此我们需要重写button的dispatchTouchEvent函数,因此要创建一个类mButton来继承Button

点击时事件被button获取,因此要将事件通过dispatchTouchEvent回传给父view,再调用父view的onInterceptTouchEvent函数对拦截到的事件进行处理。

代码如下:

mButton.java

import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;public class mButton extends android.support.v7.widget.AppCompatButton {    public mButton(Context context) {        super(context);    }    public mButton(Context context, AttributeSet attrs) {        super(context, attrs);    }    public mButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                getParent().requestDisallowInterceptTouchEvent(false);                break;            case MotionEvent.ACTION_MOVE:                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_POINTER_UP:                break;        }        return super.dispatchTouchEvent(ev);    }}

mLayout.java

import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.FrameLayout;import android.widget.Scroller;public class mLayout extends FrameLayout{    private float scale = 1; // 伸缩比例    // 移动过程中临时变量    private float actionX;    private float actionY;    private float spacing;    private int moveType; // 0=未选择,1=拖动,2=缩放    private float firstX;    private float firstY;    //系数可自己更改    private static final float DEFAULT_FATOR = 0.4f;        private float mFator = DEFAULT_FATOR;    private Scroller mScroller;        private MotionEvent mLastMotionEvent;    public mLayout(Context context) {        this(context, null);    }    public mLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public mLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mScroller = new Scroller(context);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        switch (event.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:                mLastMotionEvent = MotionEvent.obtain(event);                moveType = 1;                actionX = event.getRawX();                actionY = event.getRawY();                firstX = actionX;                firstY = actionY;                break;            case MotionEvent.ACTION_POINTER_DOWN:                moveType = 2;                spacing = getSpacing(event);                break;            case MotionEvent.ACTION_MOVE:                if (moveType == 1) {                    int dx = (int) (event.getRawX() - mLastMotionEvent.getRawX());                    int dy = (int) (event.getRawY() - mLastMotionEvent.getRawY());                    //如果不想对四个方向增加阻尼效果,直接删除即可                    //向上平移                    if ((Math.abs(dx) < Math.abs(dy)) && dy < 0){                        smoothScrollBy(0, -(int) (dy * mFator));                    }                    //向下平移                    else if (Math.abs(dx) < Math.abs(dy) && dy > 0) {                        smoothScrollBy(0, -(int) (dy * mFator));                    }                    //向左平移                    else if (Math.abs(dx) > Math.abs(dy) && dx < 0){                        smoothScrollBy(-(int) (dx * mFator), 0);                    }                    //向右平移                    else if (Math.abs(dx) > Math.abs(dy) && dx > 0){                        smoothScrollBy(-(int) (dx * mFator), 0);                    }                    mLastMotionEvent = MotionEvent.obtain(event);                }                else if (moveType == 2) {                    scale = scale * getSpacing(event) / spacing;                    if(scale >= 1){                        setScaleX(scale);                        setScaleY(scale);                    }else{                        scale = 1;                    }                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_POINTER_UP:            case MotionEvent.ACTION_CANCEL:                moveType = 0;                if(scale == 1)                    smoothScrollTo(0, 0);                break;        }        return true;    }    //拦截子button的事件    @Override    public boolean onInterceptTouchEvent(MotionEvent event) {        switch (event.getAction() & MotionEvent.ACTION_MASK){            case MotionEvent.ACTION_DOWN:                mLastMotionEvent = MotionEvent.obtain(event);                moveType = 1;                actionX = event.getRawX();                actionY = event.getRawY();                firstX = actionX;                firstY = actionY;                break;            case MotionEvent.ACTION_POINTER_DOWN:                moveType = 2;                spacing = getSpacing(event);                break;            case MotionEvent.ACTION_MOVE:                if (moveType == 1) {                    int dx = (int) (event.getRawX() - mLastMotionEvent.getRawX());                    int dy = (int) (event.getRawY() - mLastMotionEvent.getRawY());                    //如果不想对四个方向增加阻尼效果,直接删除即可                    //向上平移                    if ((Math.abs(dx) < Math.abs(dy)) && dy < 0){                        smoothScrollBy(0, -(int) (dy * mFator));                    }                    //向下平移                    else if (Math.abs(dx) < Math.abs(dy) && dy > 0) {                        smoothScrollBy(0, -(int) (dy * mFator));                    }                    //向左平移                    else if (Math.abs(dx) > Math.abs(dy) && dx < 0){                        smoothScrollBy(-(int) (dx * mFator), 0);                    }                    //向右平移                    else if (Math.abs(dx) > Math.abs(dy) && dx > 0){                        smoothScrollBy(-(int) (dx * mFator), 0);                    }                    mLastMotionEvent = MotionEvent.obtain(event);                }                else if (moveType == 2) {                    scale = scale * getSpacing(event) / spacing;                    if(scale >= 1){                        setScaleX(scale);                        setScaleY(scale);                    }else{                        scale = 1;                    }                }                break;            case MotionEvent.ACTION_UP:                moveType = 0;                if(scale == 1)                    smoothScrollTo(0, 0);                if(firstX != event.getRawX() || firstY != event.getRawY())                    return true;                break;            case MotionEvent.ACTION_POINTER_UP:                moveType = 0;                if(scale == 1)                    smoothScrollTo(0, 0);                break;            case MotionEvent.ACTION_CANCEL:                moveType = 0;                if(scale == 1)                    smoothScrollTo(0, 0);                break;        }        return super.onInterceptTouchEvent(event);    }    private void smoothScrollBy(int dx, int dy) {        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);        invalidate();    }    private void smoothScrollTo(int fx, int fy) {        int dx = fx - mScroller.getFinalX();        int dy = fx - mScroller.getFinalY();        smoothScrollBy(dx, dy);    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());            postInvalidate();        }        super.computeScroll();    }    // 触碰两点间距离    private float getSpacing(MotionEvent event) {        //通过三角函数得到两点间的距离        float x = event.getX(0) - event.getX(1);        float y = event.getY(0) - event.getY(1);        return (float) Math.sqrt(x * x + y * y);    }}

到此,关于“Android怎么实现橡皮筋回弹和平移缩放效果”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯