国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

滑動退出Activity的兩種方法

2019-11-09 14:43:16
字體:
來源:轉載
供稿:網友

最近遇到需求,需要滑動退出Activity,參考了大蝦們的方案后整理出了兩種主流的方法:

使用OnTouchEvent,處理觸摸事件實現滑動退出使用ViewDragHelper拖動實現滑動退出

兩種方法各有利弊,遇到界面上的滑動或滾動事件產生沖突的需要自己處理,下面就來詳細的介紹兩種實現方法。

0.前提

兩種方法不管使用哪一種都需要設置透明主題及Activity中根布局的background,以實現滑動時,上一個Activity可見。

Activity根布局背景: android:background="?android:colorBackground"Activity主題: <style name="Translucent" parent="A1.使用OnTouchEvent,處理觸摸事件實現滑動退出

先來看看具體實現:

/** * @author Steven Duan * @version 1.0 */public class SlideLayout extends FrameLayout {
PRivate static final String T = SlideLayout.class.getName(); private Activity mActivity; private Scroller mScroller; private int mShadowWidth; private Drawable mLeftShadow; private int mLastMoveX; private int mScreenWidth; private int mMinX; public SlideLayout(Activity activity) { this(activity, null); } public SlideLayout(Activity activity, AttributeSet attrs) { this(activity, attrs, 0); } public SlideLayout(Activity activity, AttributeSet attrs, int defStyleAttr) { super(activity, attrs, defStyleAttr); Log.d(T, "F初始化 "); this.mActivity = activity; mScroller = new Scroller(activity); //滑動時漸變的陰影 //noinspection deprecation mLeftShadow = getResources().getDrawable(R.drawable.left_shadow); //陰影的寬度 mShadowWidth = ((int) getResources().getDisplayMetrics().density) * 16; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mLastMoveX = (int) event.getX(); mScreenWidth = getWidth(); mMinX = mScreenWidth / 10; break; case MotionEvent.ACTION_MOVE: int eventX = (int) event.getX(); Log.d(T, "eventX: " + eventX); int dx = mLastMoveX - eventX; if (getScrollX() + dx >= 0) { scrollTo(0, 0); } else if (eventX > mMinX) { //手指處于屏幕邊緣時不處理滑動 scrollBy(dx, 0); } mLastMoveX = eventX; break; case MotionEvent.ACTION_UP: if (-getScrollX() < mScreenWidth / 2) { slideBack(); } else { slideFinish(); } break; } return true; } private void slideFinish() { mScroller.startScroll(getScrollX(), 0, -getScrollX() - mScreenWidth, 0, 200); invalidate(); } private void slideBack() { mScroller.startScroll(getScrollX(), 0, -getScrollX(), 0, 200); invalidate(); } @Override public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), 0); postInvalidate(); } else if (-getScrollX() == mScreenWidth) { mActivity.finish(); } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); //繪制邊緣陰影 canvas.save(); //設置陰影的大小范圍 mLeftShadow.setBounds(0, 0, mShadowWidth, getHeight()); //平移畫布 canvas.translate(-mShadowWidth, 0); //繪制 mLeftShadow.draw(canvas); canvas.restore(); } public void bind() { Log.d(T, "bind: F"); ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView(); View child = decorView.getChildAt(0); decorView.removeView(child); addView(child); decorView.addView(this); Log.d(T, "bind成功"); }}

定義好了容器,那么在Activity中如何使用呢?只需要在Activity的onCreate方法做如下調用即可:

@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); new SlideLayout(this).bind(); }

代碼比較簡單,一看便知。只是這種方法在Activity中有滑動或滾動事件會產生沖突,這就涉及事件分發機制,需要自己看情況處理。

2.使用ViewDragHelper拖動實現滑動退出

廢話不多說直接上代碼:

/** * @author Steven Duan * @version 1.0 */public class SlideLayout extends FrameLayout { private View mDragView; private Activity mActivity; private ViewDragHelper mViewDragHelper; private float mSlideWidth; private int mScreenWidth; private int mScreenHeight; private int curSlideX; public SlideLayout(Context context) { super(context); init(context); } private void init(Context context) { mActivity = (Activity) context; mViewDragHelper = ViewDragHelper.create(this, new DragCallback()); //設置可拖動的邊緣 mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); } /** * 把DecorView下的子View移除添加到SlideLayout,再將SlideLayout添加到DecorView */ public void bind() { ViewGroup mDecorView = (ViewGroup) mActivity.getWindow().getDecorView(); mDragView = mDecorView.getChildAt(0); mDecorView.removeView(mDragView); this.addView(mDragView); mDecorView.addView(this); //計算屏幕寬度 DisplayMetrics dm = new DisplayMetrics(); mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm); mScreenWidth = dm.widthPixels; mScreenHeight = dm.heightPixels; //觸發Activity滑出的寬度 mSlideWidth = dm.widthPixels * 0.5f; } @Override public boolean onInterceptHoverEvent(MotionEvent event) { return mViewDragHelper.shouldInterceptTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { mViewDragHelper.processTouchEvent(event); return true; } class DragCallback extends ViewDragHelper.Callback { @Override public boolean tryCaptureView(View child, int pointerId) { return false; } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { int left = releasedChild.getLeft(); if (left <= mSlideWidth) { //返回 mViewDragHelper.settleCapturedViewAt(0, 0); } else { //滑出 mViewDragHelper.settleCapturedViewAt(mScreenWidth, 0); } //需要重繪 invalidate(); } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { curSlideX = left; invalidate(); if (changedView == mDragView && left >= mScreenWidth) { mActivity.finish(); } } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { //限制左右拖拽的位移 left = left >= 0 ? left : 0; return left; } @Override public int clampViewPositionVertical(View child, int top, int dy) { return 0; } @Override public void onEdgeDragStarted(int edgeFlags, int pointerId) { //觸發邊緣時,主動捕捉mDragView mViewDragHelper.captureChildView(mDragView, pointerId); } } @Override public void computeScroll() { //持續滾動期間,不斷重繪 if (mViewDragHelper.continueSettling(true)) invalidate(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); //進行陰影繪制 canvas.save(); Shader mShader = new LinearGradient(curSlideX - 40, 0, curSlideX, 0, new int[]{Color.parseColor("#00000000"), Color.parseColor("#50000000")}, null, Shader.TileMode.REPEAT); //繪制陰影畫筆 Paint mPaint = new Paint(); mPaint.setStrokeWidth(2); mPaint.setAntiAlias(true); mPaint.setColor(Color.GRAY); mPaint.setShader(mShader); RectF rectF = new RectF(curSlideX - 40, 0, curSlideX, mScreenHeight); canvas.drawRect(rectF, mPaint); canvas.restore(); }}

在Activity的onCreate()中調用:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_forth); //一句話實現綁定 new SlideLayout(this).bind(); }

小結:兩種方法歸根結底都是把DecorView下的子View移除添加到SlideLayout,再將SlideLayout添加到DecorView這種思路,只是移動的方式不同而已。再說第二種方法使用ViewDragHelper只能從邊緣拖拽,這顯得不那么友好。

┗|`O′|┛ 如果你有好的想法思路,歡迎共享討論。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 苍溪县| 大邑县| 连云港市| 阜康市| 江华| 香港| 静乐县| 麻栗坡县| 比如县| 仙居县| 柘城县| 唐山市| 洱源县| 巴林右旗| 平南县| 简阳市| 新晃| 深圳市| 海兴县| 桂阳县| 讷河市| 定安县| 边坝县| 黄陵县| 桐庐县| 策勒县| 化德县| 舟山市| 钟祥市| 广安市| 镇原县| 阿尔山市| 谷城县| 阜南县| 磐石市| 拜城县| 扎鲁特旗| 桑植县| 永清县| 胶南市| 连南|