100行代码实现Activity右滑退出
来源:互联网 发布:python致命缺点 编辑:程序博客网 时间:2024/05/21 00:45
很多Android App上已经增加了Activity右滑退出的效果,这个功能通常可以叫做SwipeBackActivity。这个效果最早来源于iOS,这样的操作优化确实提升了用户体验。在github上大概看了一下,实现很多也比较复杂。本文将介绍一种简单的方法来实现这个功能,只需在页面中调用两行代码就可以轻松搞定,对页面基本没有侵入性。
先来看一下最终的效果图
正式介绍代码之前,先来说明讲基本原理。我们知道在Android的PhoneWindow中包含一个DecorView,它是整个Activity的根View,实际上就是一个FrameLayout。DecorView中又会一个子View(一个资源id名字为content的FrameLayout),我们称之为contentView,它是我们页面布局的parent布局,即我们通过setContentView()方法设置的布局就是直接添加到这个id为content的FrameLayout上。如果将我们自己定义的View称作userView,那么DecorView、contentView和userView这三个View之间就是依次包含的关系。
有了上面的这些概念,就可以很容易的实现我们的功能。我们只需要将DecorView、contentView背景设置成透明,然后将userView根据用户的手势向右进行移动,当userView全部移动出屏幕之后将Activity销毁,就形成了Activity右滑退出的假象。
下面来看一下具体的代码实现。
private int mScreenWidth; private int mTouchSlop; private boolean isMoving = false; private float mInitX; private float mInitY; private ViewGroup decorView;//窗口根布局 private ViewGroup contentView;//content布局 private ViewGroup userView;//用户添加的布局 private ArgbEvaluator evaluator; private ValueAnimator mAnimator; private VelocityTracker mVelTracker; public SwipeBackController(final Activity activity) { mScreenWidth = activity.getResources().getDisplayMetrics().widthPixels; mTouchSlop = ViewConfiguration.get(activity).getScaledTouchSlop(); evaluator = new ArgbEvaluator(); decorView = (ViewGroup) activity.getWindow().getDecorView(); decorView.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00ffffff"))); contentView = (ViewGroup) activity.findViewById(android.R.id.content); userView = (ViewGroup) contentView.getChildAt(0); mAnimator = new ValueAnimator(); mAnimator.setDuration(ANIMATION_DURATION); mAnimator.setInterpolator(new DecelerateInterpolator()); mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int x = (Integer) valueAnimator.getAnimatedValue(); if (x >= mScreenWidth) { activity.finish(); } handleView(x); handleBackgroundColor(x); } }); } public void handleView(int x) { userView.setTranslationX(x); } /** * 控制背景颜色和透明度 * @param x */ private void handleBackgroundColor(float x) { int colorValue = (int) evaluator.evaluate(x / mScreenWidth, Color.parseColor("#dd000000"), Color.parseColor("#00000000")); contentView.setBackgroundColor(colorValue); Log.d(TAG, "x is " + x); }
首先获得了屏幕宽度,获得TouchSlop增加滑动判断的准确性,否则任何微小的滑动都会被误认为是用户的滑动行为。ArgbEvaluator用来对变化的颜色求值。然后分别获得DecorView、contentView和userView,并将DecorView的背景色设置为透明。
重点来看一下DecorView、contentView和userView的获取方法。
DecorView:通过getWindow()的getDecorView()方法获得。
contentView:之前提到contentView在系统中的资源id为content,可以直接通过findViewById(android.R.id.content)来获得这个View。userView:userView是直接添加到contentView上的,通过contentView.getChildAt(0)得到的就是userView。
然后定义用于userView的属性动画,在属性动画的监听方法中,设置contentView的背景色不断变化,并且设置userView的偏移量。当属性动画的值大于屏幕宽度时,将Activity销毁。
public boolean processEvent(MotionEvent event) { getVelocityTracker(event); if (mAnimator.isRunning()) { return true; } int pointId = -1; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mInitX = event.getRawX(); mInitY = event.getRawY(); pointId = event.getPointerId(0); break; case MotionEvent.ACTION_MOVE: if (!isMoving) { float dx = Math.abs(event.getRawX() - mInitX); float dy = Math.abs(event.getRawY() - mInitY); if (dx > mTouchSlop && dx > dy && mInitX < DEFAULT_TOUCH_THRESHOLD) { isMoving = true; } } if (isMoving) { handleView((int) event.getRawX()); handleBackgroundColor(event.getRawX()); } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: int distance = (int) (event.getRawX() - mInitX); mVelTracker.computeCurrentVelocity(1000); //获取x方向上的速度 float velocityX = mVelTracker.getXVelocity(pointId); Log.d(TAG, "mVelocityX is " + velocityX); if (isMoving && Math.abs(userView.getTranslationX()) >= 0) { if (distance >= mScreenWidth / 4 || velocityX > 1000f) { mAnimator.setIntValues((int) event.getRawX(), mScreenWidth); } else { mAnimator.setIntValues((int) event.getRawX(), 0); } mAnimator.start(); isMoving = false; } mInitX = 0; mInitY = 0; recycleVelocityTracker(); break; } return true; }在onTouchEvent中根据当前移动的距离,调用handleView和handleBackgroundColor方法分别来设置userView的位置和contentView的背景色。当ACTION_UP的时候,会根据当时用户手势滑动的速度和当前已经划过的距离去判断,是否继续滑动销毁Activity还是恢复页面的初始状态。然后根据判断结果去执行动画。
public class SecondActivity extends Activity {private SwipeBackController swipeBackController; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_second); swipeBackController = new SwipeBackController(this); } @Override public boolean onTouchEvent(MotionEvent ev) { if (swipeBackController.processEvent(ev)) { return true; } else { return super.onTouchEvent(ev); } }}
最后在需要实现右滑退出的Activity页面,创建一个SwipBackController的对象,然后在OnTouchEvent中将MotionEvent传给它的processEvent()方法就可以了。我们并没有给Activity设置什么属性,也不需要继承什么类,就可以轻松实现这个功能。
完整代码下载
- 100行代码实现Activity右滑退出
- Slidr框架,一行代码实现右滑退出Activity
- 实现app全局activity右滑退出
- Android 右滑实现退出Activity
- android activity右滑退出
- 自定义SwipeBackLayout控件实现右滑退出activity功能
- Activity右滑退出控件SlidingLayout
- android Activity右滑返回,退出当前activity
- android Activity右滑返回,退出当前activity
- android Activity右滑返回,退出当前activity
- SwipeBack实现Activity右滑退出(仿IOS效果)(学习:纯净日报第一弹)
- 实现屏幕右划退出当前Activity(带动画效果)
- Android 快速实现右滑退出效果
- Git上面的右滑退出当前Activity
- android项目添加activity右滑退出.返回的效果
- android 仿ios右滑退出当前activity
- 【Android】Activity右滑返回的实现
- Activity右滑返回效果实现
- VNC Viewer远程登录服务器时 点了logout
- linux下Oracle显示中文乱码
- Google大数据三篇著名论文中文版
- Windows Server 2008R2 设置SMTP邮件转发服务
- Linux服务器大量向外发包问题排查
- 100行代码实现Activity右滑退出
- nagios网络流量监控(附pnp模板)
- Windows Server 2008R2关闭/打开默认windows共享
- Kotlin实战一:项目配置和语言转换
- 离线安装Cloudera Manager5.3.4与CDH5.3.4
- 专注做事
- 现实JAVAEE开发中最常用到的技术和工具
- 【bzoj1726】【Usaco2006 Nov】【Roadblocks第二短路】【spfa】
- hadoop反编译安装包自带的例子