android dialog實現底部彈出和手指滑動隱藏效果

直接來看效果圖:
效果圖
第一次隱藏是點擊空白區域自動隱藏,第二次是通過手指滑動控制dialog隱藏。
實現這個效果的代碼量很少,直接來看代碼:

 @Override
    protected void onStart() {
        super.onStart();
        Window window = getWindow();
        window.setWindowAnimations(R.style.bottomShow);
        WindowManager.LayoutParams windowparams = window.getAttributes();
        window.setGravity(Gravity.BOTTOM);
        windowparams.height = DensityUtil.dip2px(context, 300);
        windowparams.width = ScreenUtils.getScreenWidth(context);
        window.setBackgroundDrawableResource(android.R.color.transparent);
        window.setAttributes(windowparams);
    }

在dialog的onstart方法中,我們獲取dialog的window對象,設置內容view顯示在底部,設置view高度爲300dp。寬度爲屏幕寬度,。這裏要使用window的setBackgroundDrawableResource,否則會出現旁邊有間隔的現象。還有設置window的動畫:

<style name="bottomShow" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/pop_show</item>
        <item name="android:windowExitAnimation">@anim/pop_hidden</item>
    </style>
pop_show.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromYDelta="100%p"
        android:duration="500"
        android:toYDelta="0"
        ></translate>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromYDelta="0"
        android:duration="500"
        android:toYDelta="100%p"
        ></translate>
</set>

在style中指定android:windowEnterAnimation和android:windowExitAnimation,進入退出動畫。
這樣就完成了彈出隱藏的動畫。

然後是手指控制dialog滑動隱藏:
爲了滑動不起衝突,使用onTouchEvent方法來監聽滑動事件:

 float startY;
    float moveY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                moveY = ev.getY() - startY;
                view.scrollBy(0, -(int) moveY);
                startY = ev.getY();
                if (view.getScrollY() > 0) {
                    view.scrollTo(0, 0);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (view.getScrollY() < -this.getWindow().getAttributes().height / 4 && moveY > 0) {
                    this.dismiss();

                }
                view.scrollTo(0, 0);
                break;
        }
        return super.onTouchEvent(ev);
    }

在down的時候記錄y,滑動的時候計算出滑動距離通過view。scrollBy方法控制view的滑動,確保view不能玩上滑動溢出,控制view.getScrollY大於0的時候重置。手指擡起的時候判斷滑動方向如果是向下並且超過四分之一,隱藏dialog,然後重置view的位置。
通過改變mScrollY來變化view的位置,實際上view本身並沒有發生移動 移動的view的內容。view的內容和view本身的橫向縱向距離就是mScroolX和mScrollY的值:

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