1,首先需要自定义一个支持跟随手势滑动的布局SildingFinishLayout:
2,在activity里面使用,需要在清单文件进行如下配置:
android:name=".activity.LockScreenActivity"
android:excludeFromRecents="true"
android:exported="false"
android:launchMode="singleInstance"
android:noHistory="true"
android:screenOrientation="portrait"
android:taskAffinity="com.package.name.lockscreen"
android:theme="@style/LockScreenBase"/>
/////////自定义的SildingFinishLayout:
public classSildingFinishLayout2extendsRelativeLayoutimplements
View.OnTouchListener {
/**
* SildingFinishLayout布局的父布局
*/
privateViewGroupmParentView;
/**
* 处理滑动逻辑的View
*/
privateViewtouchView;
/**
* 滑动的最小距离
*/
private intmTouchSlop;
/**
* 按下点的X坐标
*/
private intdownX;
/**
* 按下点的Y坐标
*/
private intdownY;
/**
* 临时存储X坐标
*/
private inttempX;
/**
* 临时存储Y坐标
*/
private inttempY;
/**
* 滑动类
*/
privateScrollermScroller;
/**
* SildingFinishLayout的宽度
*/
private intviewWidth;
/**
* SildingFinishLayout的高度
*/
private intviewHeight;
/**
* 记录是否正在滑动
*/
private booleanisSilding;
privateOnSildingFinishListeneronSildingFinishListener;
private booleanisFinish;
publicSildingFinishLayout2(Context context,AttributeSet attrs) {
this(context,attrs,0);
}
publicSildingFinishLayout2(Context context,AttributeSet attrs, intdefStyle) {
super(context,attrs,defStyle);
mTouchSlop= ViewConfiguration.get(context).getScaledTouchSlop();
mScroller=newScroller(context);
}
@Override
protected voidonLayout(booleanchanged, intl, intt, intr, intb) {
super.onLayout(changed,l,t,r,b);
if(changed) {
// 获取SildingFinishLayout所在布局的父布局
mParentView= (ViewGroup)this.getParent();
viewWidth=this.getWidth();
viewHeight=this.getHeight();
}
}
/**
* 设置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity
*
*@paramonSildingFinishListener
*/
public voidsetOnSildingFinishListener(
OnSildingFinishListener onSildingFinishListener) {
this.onSildingFinishListener= onSildingFinishListener;
}
/**
* 设置Touch的View
*
*@paramtouchView
*/
public voidsetTouchView(View touchView) {
this.touchView= touchView;
touchView.setOnTouchListener(this);
}
publicViewgetTouchView() {
returntouchView;
}
/**
* 滚动出界面
*/
private voidscrollRight() {
final intdelta = (viewHeight+mParentView.getScrollY());
mScroller.startScroll(0,mParentView.getScrollY(),0,delta +1,
Math.abs(delta));
postInvalidate();
}
/**
* 滚动到起始位置
*/
private voidscrollOrigin() {
intdelta =mParentView.getScrollY();
mScroller.startScroll(0,mParentView.getScrollY(),0,-delta,
Math.abs(delta));
postInvalidate();
}
/**
* touch的View是否是AbsListView, 例如ListView, GridView等其子类
*
*@return
*/
private booleanisTouchOnAbsListView() {
returntouchViewinstanceofAbsListView ?true:false;
}
/**
* touch的view是否是ScrollView或者其子类
*
*@return
*/
private booleanisTouchOnScrollView() {
returntouchViewinstanceofScrollView ?true:false;
}
@Override
public booleanonTouch(View v,MotionEvent event) {
switch(event.getAction()) {
caseMotionEvent.ACTION_DOWN:
downX=tempX= (int) event.getRawX();
downY=tempY= (int) event.getRawY();
break;
caseMotionEvent.ACTION_MOVE:
intmoveX = (int) event.getRawX();
intmoveY = (int) event.getRawY();
intdeltaX =tempX- moveX;
intdeltaY =tempY- moveY;
tempX= moveX;
tempY= moveY;
/* if (Math.abs(moveX - downX) > mTouchSlop
&& Math.abs((int) event.getRawY() - downY) < mTouchSlop) {
isSilding = true;*/
if(Math.abs(moveY -downY)
&& Math.abs((int) event.getRawX() -downX)
isSilding=true;
// 若touchView是AbsListView,
// 则当手指滑动,取消item的点击事件,不然我们滑动也伴随着item点击事件的发生
if(isTouchOnAbsListView()) {
MotionEvent cancelEvent = MotionEvent.obtain(event);
cancelEvent
.setAction(MotionEvent.ACTION_CANCEL
| (event.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
v.onTouchEvent(cancelEvent);
}
}
if(moveY -downY<=0&&isSilding) {
mParentView.scrollBy(0,deltaY);
// 屏蔽在滑动过程中ListView ScrollView等自己的滑动事件
if(isTouchOnScrollView() || isTouchOnAbsListView()) {
return true;
}
}
break;
caseMotionEvent.ACTION_UP:
isSilding=false;
if(mParentView.getScrollY() >=viewHeight/4) {
isFinish=true;
scrollRight();
}else{
scrollOrigin();
isFinish=false;
}
break;
}
if(isTouchOnScrollView() || isTouchOnAbsListView()) {
returnv.onTouchEvent(event);
}
// 其他的情况直接返回true
return true;
}
@Override
public voidcomputeScroll() {
// 调用startScroll的时候scroller.computeScrollOffset()返回true,
if(mScroller.computeScrollOffset()) {
mParentView.scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
// if (mScroller.isFinished()) {
if(onSildingFinishListener!=null&&isFinish) {
onSildingFinishListener.onSildingFinish();
}
// }
}
}
public interfaceOnSildingFinishListener {
public voidonSildingFinish();
}
}
////////Activity里的使用:
public class LockScreenActivity extends AppCompatActivity {
@Override
protected voidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_lock_screen);
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
SildingFinishLayout2 mSildingFinishLayout = (SildingFinishLayout2) findViewById(R.id.sildingFinishLayout);
mSildingFinishLayout.setOnSildingFinishListener(newSildingFinishLayout2.OnSildingFinishListener() {
@Override
public voidonSildingFinish() {
finish();
}
});
mSildingFinishLayout.setTouchView(findViewById(R.id.rl));//这个布局必须是包含在SildingFinishLayout下的最外层布局
}
@Override
public voidonBackPressed() {
}