private static final String LOG_TAG = "SlideActivity"; /** android.R.id.content 这个View */ private View mContentView = null; /** 一个activity的主View */ private View mDecoreView = null; //记录滑动的开始的位置 private int mDownPos = -1; //记录滑动手指的id private int mPointerId = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //这里,请注意,需要把windowbackground设置为透明,并且android:windowIsTranslucent置为true. //这样,你才会在滑动的时候,看到下面Activity的界面。请参看AndroidManifest.xml这个Activity的style. //而且,在开发的过程中,发现windowbackgournd设置为@null的,滑动会花屏,这个原因还没有找到。 this.setContentView(R.layout.slide_activity); getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); Log.i(LOG_TAG, "onCreate"); } @Override protected void onStart() { super.onStart(); Log.i(LOG_TAG, "onStart"); } @Override protected void onRestart() { super.onRestart(); Log.i(LOG_TAG, "onRestart"); } @Override protected void onResume() { super.onResume(); //拿到decoreView mDecoreView = this.getWindow().getDecorView(); //拿到contentView mContentView = mDecoreView.findViewById(android.R.id.content); //监听contentView上面的Touch事件 mContentView.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { Log.i(LOG_TAG, "result:" + event.getActionMasked()); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { //分配记录滑动的初始位置,和PointerId。 mDownPos = (int) event.getRawY(); mPointerId = event.getPointerId(event.getActionIndex()); Log.e(LOG_TAG, "mDownPos:" + event.getY()); break; } case MotionEvent.ACTION_MOVE: { //滑动contentView 到 手指当前位置到初始位置的位移。 int currentPos = (int) event.getRawY(); v.scrollTo(0, mDownPos - currentPos); v.invalidate(); // use margin // FrameLayout.LayoutParams flp = // (FrameLayout.LayoutParams)mContentView.getLayoutParams(); // flp.bottomMargin = flp.bottomMargin - distance; // flp.topMargin = flp.topMargin + distance; // flp.height = mHeight - (mDownPos - currentPos); // mContentView.offsetTopAndBottom(-distance); // mContentView.setLayoutParams(flp); // mDecoreView.invalidate(); // move windows? // WindowManager.LayoutParams wlp = mWindow.getAttributes(); // wlp.y = currentPos - mDownPos; // mWindow.setAttributes(wlp); // // WindowManager.LayoutParams wlp = // (WindowManager.LayoutParams)mDecoreView.getLayoutParams(); // Log.i(LOG_TAG, "posX:"+ wlp.x + " posY:"+wlp.y); // wlp.y = currentPos - mDownPos; // //wlp.height = mHeight; // Log.i(LOG_TAG, "posY change to "+wlp.y); // //wlp.height = 360; // this.getWindowManager().updateViewLayout(mDecoreView, // wlp); break; } case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: default: { int pointerId = event.getPointerId(event.getActionIndex()); //如果是触发Action_Down的手指出现UP或Cancel事件。计算总位移并决定是不是需要关闭这个Activity if(-1 != pointerId && mPointerId == pointerId) { int currentPosY = (int)event.getY(event.findPointerIndex(mPointerId)); int distance = mDownPos - currentPosY; int height = v.getHeight(); if(distance <= -height/2) { //滑动超过半屏,结束Activity。 v.scrollTo(0, -height); v.invalidate(); SlideActivity.this.finish(); } else if (distance > -height/2 && distance < height/2) { //滑动位置没超过半个屏幕,恢复初始位置 v.scrollTo(0, 0); v.invalidate(); } else { //滑动超过半屏,结束Activity。 v.scrollTo(0, height); v.invalidate(); SlideActivity.this.finish(); } //清除变量 mPointerId = -1; } } } return true; } }); Log.i(LOG_TAG, "onResume"); } @Override protected void onPause() { super.onPause(); Log.i(LOG_TAG, "onPause"); } @Override protected void onStop() { super.onStop(); Log.i(LOG_TAG, "onStop"); } @Override protected void onDestroy() { super.onDestroy(); Log.i(LOG_TAG, "onDestroy"); } }