两步搞定Activity的向右滑动返回的功能

本文转载自两步搞定Activity的向右滑动返回的功能,原作者的代码在完全被ListView填充的Activity右滑会在关闭Activity的同时触发ListView Item的点击事件,我对此做了微调,解决了这一问题。

实现该功能需同时满足几个条件,并要考虑用户的操作意图,既要保证足够的灵敏度,不要出现向右滑动好多次还没返回上一页的情况,也不要出现本来是想上下滑动(斜着上下滑动)而非向右滑动返回,也被判断为向右滑动返回而结束了当前界面,那么我们需要满足:

  1. 用户需向右滑动一段距离,且X轴距离>某一设定的值;

  2. 因为向右滑动时,不可能时严格的水平方向而不向Y轴偏移,所以向Y轴的偏移量不能超过某一设定的值,否则认为用户意图不是滑动返回而是上下滑动;

  3. 在测试过程中,如果用户意图是上下滑动时,那么手指在y轴移动速度(我们按每秒移动的像素值,可通过VelocityTracker类计算)非 常大,通常在几千到过万,而在正常的水平滑动时,y轴的移动速度通常只有100左右,因此,我们需要判断的是,如果y轴上手指滑动速度超过某一设定值(本人将该值设置为了1000),则认为用户意图是上下滑动而非向右滑动返回;
    在这里插入图片描述

好了,接下来我们便可自定义一个SlideBackActivity继承Activity,并在SlideBackActivity中重写事件分发dispatchTouchEvent,并记录手指按下,移动的距离及手指滑动速度,从而判断用户的意图,(微调后的)完整代码:

import android.app.Activity;
import android.view.MotionEvent;
import android.view.VelocityTracker;

/**
 * 支持滑动返回
 * 继承该Activity则支持滑动返回
 */
public class SlideBackActivity extends Activity {

    //手指上下滑动时的最小速度
    private static final int YSPEED_MIN = 1000;

    //手指向右滑动时的最小距离
    private static final int XDISTANCE_MIN = 50;

    //手指向上滑或下滑时的最小距离
    private static final int YDISTANCE_MIN = 100;

    //记录手指按下时的横坐标。
    private float xDown;

    //记录手指按下时的纵坐标。
    private float yDown;

    //记录手指移动时的横坐标。
    private float xMove;

    //记录手指移动时的纵坐标。
    private float yMove;

    //用于计算手指滑动的速度。
    private VelocityTracker mVelocityTracker;

    private int distanceX;
    private int distanceY;
    private int ySpeed;

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        createVelocityTracker(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                xDown = event.getRawX();
                yDown = event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                xMove = event.getRawX();
                yMove= event.getRawY();
                //滑动的距离
                distanceX = (int) (xMove - xDown);
                distanceY= (int) (yMove - yDown);
                //获取顺时速度
                ySpeed = getScrollVelocity();
                break;
            case MotionEvent.ACTION_UP:
                recycleVelocityTracker();
                //关闭Activity需满足以下条件:
                //1.x轴滑动的距离>XDISTANCE_MIN
                //2.y轴滑动的距离在YDISTANCE_MIN范围内
                //3.y轴上(即上下滑动的速度)<XSPEED_MIN,如果大于,则认为用户意图是在上下滑动而非左滑结束Activity
                if(distanceX > XDISTANCE_MIN &&(distanceY<YDISTANCE_MIN&&distanceY>-YDISTANCE_MIN)&& ySpeed < YSPEED_MIN) {
                    finish();
                    return false;
                }
                //当手指抬起时,不要将滑动产生的点击事件冒泡,否则会触发ListView的OnClickListener
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    /**
     * 创建VelocityTracker对象,并将触摸界面的滑动事件加入到VelocityTracker当中。
     *
     * @param event 触摸滑动事件
     *
     */
    private void createVelocityTracker(MotionEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }

    /**
     * 回收VelocityTracker对象。
     */
    private void recycleVelocityTracker() {
        mVelocityTracker.recycle();
        mVelocityTracker = null;
    }

    /**
     *
     * @return 滑动速度,以每秒钟移动了多少像素值为单位。
     */
    private int getScrollVelocity() {
        mVelocityTracker.computeCurrentVelocity(1000);
        int velocity = (int) mVelocityTracker.getYVelocity();
        return Math.abs(velocity);
    }
}

接下来的两步可以很容易的将这个功能加入你的APP:

第一步:创建一个class类名为SlideBackActivity,并将以上代码复制粘贴进去。

第二部:将你APP需要向右滑动返回的页面所在activity继承改为SlideBackActivity,即可实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中,如果一个 Activity 要向另一个 Activity 返回数据,可以使用 startActivityForResult() 方法。该方法会启动另一个 Activity 并等待其返回结果。当另一个 Activity 结束时,会调用 onActivityResult() 方法,通过该方法可以获取另一个 Activity 返回的数据。 以下是一个简单的示例: 在第一个 Activity 中: ``` public class MainActivity extends AppCompatActivity { private static final int REQUEST_CODE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivityForResult(intent, REQUEST_CODE); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) { String result = data.getStringExtra("result"); Toast.makeText(this, result, Toast.LENGTH_SHORT).show(); } } } ``` 在第二个 Activity 中: ``` public class SecondActivity extends AppCompatActivity { private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); editText = findViewById(R.id.edit_text); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String result = editText.getText().toString(); Intent intent = new Intent(); intent.putExtra("result", result); setResult(RESULT_OK, intent); finish(); } }); } } ``` 在第二个 Activity 中,当用户点击按钮时,会把编辑框中的文本作为结果返回给第一个 Activity。在 onActivityResult() 方法中,可以获取到返回的结果并进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值