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的值:

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