Andorid仿微信側滑退出

                                            Andorid仿微信側滑退出


 使用主題窗體透明,背景透明,側滑時可見前一頁佈局

<!--窗體透明-->
<item name="android:windowIsTranslucent">true</item>
<!--設置的背景-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--背景是否模糊顯示-->
<item name="android:backgroundDimEnabled">true</item>
<!--背景模糊  0.0f完全不暗,1.0f全暗-->
<item name="android:backgroundDimAmount">0.85</item>

父類Activity :

/**
 * <pre>
 * Created by DengDongQi on 2020/5/13
 * 仿微信側滑退出
 * </pre>
 */
@SuppressLint("Registered")
abstract class SideOutActivity : AppCompatActivity() {

    companion object {
        /** DecorView左邊滑出間距佔屏幕寬度PRESENT_TO_FINISH時表示用戶需要退出當前Activity */
        private const val PRESENT_TO_FINISH = 0.3f
        /** 用戶距離左邊MIN_EDGE_DISTANCE內拖動有效 */
        private const val MIN_EDGE_DISTANCE = 100
    }
    /** 屏幕寬度 */
    private var mScreenW = -1f
    /** 用戶計算用戶在屏幕滑動的距離 */
    private var mStartX = 0f
    /** 當前是否允許拖動 */
    private var mIsScrollEnable = false
    /** 當前Activity的DecorView */
    private var mDecorView: View? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //獲得當前窗體對象
        val window = window
        //獲取窗體View 以及屏幕寬度
        mDecorView = window.decorView
        if (mScreenW == -1f) {
            val metrics = DisplayMetrics()
            windowManager.defaultDisplay
                    .getMetrics(metrics)
            mScreenW = metrics.widthPixels.toFloat()
        }
    }

    /**
     * 處理仿微信側滑退出效果
     * */
    fun registerFinishTouchEvent(event: MotionEvent){
        if (event.action == MotionEvent.ACTION_DOWN) {
            mStartX = event.x
            if (mStartX < MIN_EDGE_DISTANCE) {
                // 距離左邊距離足夠小,設置爲可拖動狀態
                mIsScrollEnable = true
            }
        } else if (event.action == MotionEvent.ACTION_MOVE && mIsScrollEnable) {
            // 滾動DecorView內容
            val dX = event.x - mStartX
            mStartX = event.x
            mDecorView!!.scrollBy((-dX).toInt(), 0)
        } else if (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL) {
            // 觸摸操作取消,重置
            mIsScrollEnable = false
            // 根據當前滑動狀態判斷最終是滑到左邊還是滑到右邊(結束Activity)
            val targetX = if (-mDecorView!!.scrollX / mScreenW > PRESENT_TO_FINISH) (-mScreenW).toInt() else 0
            val animator = ValueAnimator.ofInt(mDecorView!!.scrollX, targetX)
            animator.addUpdateListener { animation -> mDecorView!!.scrollTo(animation.animatedValue as Int, 0) }
            animator.addListener(object : Animator.AnimatorListener {
                override fun onAnimationStart(animation: Animator) {}
                override fun onAnimationCancel(animation: Animator) {}
                override fun onAnimationRepeat(animation: Animator) {}
                override fun onAnimationEnd(animation: Animator) {
                    if (targetX.toFloat() == -mScreenW) {
                        finish()
                    }
                }
            })
            animator.start()
        }
    }
}

 需要使用的Activity頁面繼承SideOutActivity類並添加如下代碼 

 佈局文件添加背景

android:background="@android:color/black"

 kotlin 代碼中:

         override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
             registerFinishTouchEvent(ev)
             return super.dispatchTouchEvent(ev)
         } 

效果如下: 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章