赞
踩
翻看今日头条app时发现右滑Activity退出,近日领导又提到这个功能,本以为是activity自带的特效(改下某项设置后能达到效果),百度后发现很多bug,尤其是结合listview导致滑动事件冲突。
设计思路:
滑动DecorView后发现并不能看到下部Activity,我们需要设置其背景透明。
先上效果
BaseActivity代码:
package smsread.cn.zkr.com.smsread;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
public class BaseActivity extends AppCompatActivity {
View decorView;
int screenWidth;//屏宽
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
decorView=getWindow().getDecorView();
DisplayMetrics metrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth=metrics.widthPixels;
}
float startX,startY,endX,endY,distanceX,distanceY;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
startX=event.getX();
startY=event.getY();
break;
case MotionEvent.ACTION_MOVE:
endX=event.getX();
endY=event.getY();
distanceX=endX-startX;
distanceY=Math.abs(endY-startY);
//1.判断手势右滑 2.横向滑动的距离要大于竖向滑动的距离
if(endX-startX>0&&distanceY<distanceX){
decorView.setX(distanceX);
}
break;
case MotionEvent.ACTION_UP:
endX=event.getX();
distanceX=endX-startX;
endY=event.getY();
distanceY=Math.abs(endY-startY);
//1.判断手势右滑 2.横向滑动的距离要大于竖向滑动的距离 3.横向滑动距离大于屏幕三分之一才能finish
if(endX-startX>0&&distanceY<distanceX&&distanceX>screenWidth/3){
moveOn(distanceX);
}
//1.判断手势右滑 2.横向滑动的距离要大于竖向滑动的距离 但是横向滑动距离不够则返回原位置
else if(endX-startX>0&&distanceY<distanceX){
backOrigin(distanceX);
}else{
decorView.setX(0);
}
break;
}
return super.dispatchTouchEvent(event);
}
/**
* 返回原点
* @param distanceX 横向滑动距离
*/
private void backOrigin(float distanceX){
ObjectAnimator.ofFloat(decorView,"X",distanceX,0).setDuration(300).start();
}
/**
* 划出屏幕
* @param distanceX 横向滑动距离
*/
private void moveOn(float distanceX){
ValueAnimator valueAnimator=ValueAnimator.ofFloat(distanceX,screenWidth);
valueAnimator.setDuration(300);
valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
decorView.setX((Float) animation.getAnimatedValue());
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
finish();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}
背景设置透明需要在res/style文件中添加主题样式,将主题样式设置为背景透明,其parent为app的theme,然后在manifest.xml中设置每个activity的theme。注意:不能直接在app的theme下直接设置背景透明,有兴趣的可以试试效果是什么样。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#ffe516</item>
<!--<item name="colorPrimaryDark">#ffe516</item>-->
<item name="colorAccent">#ffe516</item>
</style>
<style name="MyTheme" parent="AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
</style>
关于listview与BaseActivity出现的滑动冲突问题,可以看看android事件分发机制:http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。