亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android怎么實現橡皮筋回彈和平移縮放效果

發布時間:2022-04-19 10:34:10 來源:億速云 閱讀:146 作者:iii 欄目:開發技術

這篇文章主要介紹“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;

/**
 * Created by ChenZehao
 * on 2019/8/4
 */
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;

/**
 * Created by ChenZehao
 * on 2019/8/4
 */
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;

/**
 * Created by ChenZehao
 * on 2019/8/4
 */
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;

/**
 * Created by ChenZehao
 * on 2019/8/4
 */
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怎么實現橡皮筋回彈和平移縮放效果”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

奈曼旗| 东光县| 城固县| 饶河县| 德保县| 屯昌县| 伊宁市| 仁寿县| 贵港市| 东城区| 赤水市| 鹤岗市| 昭觉县| 黔西| 奉新县| 松江区| 沐川县| 闸北区| 同德县| 肇东市| 会昌县| 长垣县| 泸水县| 太保市| 江源县| 乐安县| 平舆县| 全南县| 阳高县| 同心县| 东乡族自治县| 乌拉特前旗| 马公市| 深泽县| 定日县| 林芝县| 芜湖县| 广昌县| 新源县| 石棉县| 怀仁县|