直接來看效果圖:
第一次隱藏是點擊空白區域自動隱藏,第二次是通過手指滑動控制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的值: