前言
以前總以為這個底部彈出的視圖是在普通的視圖中添加的氮块,所以沒太在意它的原理柒傻,后來粗略看了一下AlertDialog源碼發(fā)現(xiàn)它是Dialog的子類,將View添加到WindowManager產(chǎn)生的Window對象中顯示在屏幕圖層的最上層叫胖「桂模看了一下網(wǎng)上別人寫的源碼,感覺代碼挺簡單的怔蚌,不過用起來不方便巩步,于是封裝了一下。給大伙看一下效果桦踊。
演示一
演示二
項目地址
https://github.com/Ccapton/BottomDialog
關(guān)鍵源碼解析:
我是用AlertDialog的Builder設(shè)計模式封裝這個BottomDialog的椅野,也方便大家熟悉這個控件。下面是關(guān)鍵的Builder類代碼
public static class Builder{
private LinearLayout bottomLayout; // 根布局
private View contentView; // 內(nèi)容布局
private Dialog dialog; // dialog對象
private boolean hasAnimation = true; // 是否開啟位移動畫的標(biāo)志位
private Context context; // activity或fragment的上下文對象
private int layoutId; // 內(nèi)容布局文件id
public Builder(Context context) {
this.context = context;
// 從指定的布局文件中初始化根布局(不限于LinearLayout)
bottomLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.layout_bottomdialog,null);
}
public Builder setContentView(int layoutId){
this.layoutId = layoutId;
// 設(shè)置內(nèi)容布局籍胯,使其綁定到父布局bottomLayout鳄橘,使其寬高屬性生效
this.contentView = LayoutInflater.from(context).inflate(this.layoutId,bottomLayout);
return Builder.this;
}
public Builder setContentView(View contentView){
this.contentView = contentView;
// 這個方法的弊端是contentView根布局寬高屬性沒有生效
this.bottomLayout.addView(contentView);
return Builder.this;
}
public Builder setHasAnimation(boolean hasAnimation){
this.hasAnimation = hasAnimation;
return Builder.this;
}
public BottomDialog create(){
BottomDialog bottomDialog = new BottomDialog(); // 初始化bottomDialog對象
dialog = new Dialog(context,R.style.BottomDialog); // 初始化dialog對象
contentView.measure(0, 0); // 測量contentView
bottomLayout.measure(0,0); // 測量bottomLayout
// 為Dialog添加View
dialog.setContentView(bottomLayout);
Window dialogWindow = dialog.getWindow(); // 從dialog對象中獲取window對象
// 設(shè)置Gravity,使contentView的初始位置在Window最底部,如果不設(shè)置則默認(rèn)在屏幕的中央芒炼,就達(dá)不到在屏幕底部顯示的效果了
dialogWindow.setGravity(Gravity.BOTTOM);
if(hasAnimation)
dialogWindow.setWindowAnimations(R.style.DialogAnimation);
/*
*設(shè)置Window參數(shù)
*/
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.x = 0;
lp.y = 0;
lp.width = (int) context.getResources().getDisplayMetrics().widthPixels;
lp.height = bottomLayout.getMeasuredHeight();
Log.i("BottomDialog","width = "+lp.width);
Log.i("BottomDialog","height = "+lp.height);
lp.alpha = 9f; // 透明度
dialogWindow.setAttributes(lp);
// 顯示dialog
dialog.show();
bottomDialog.dialog = this.dialog;
bottomDialog.contentView = this.contentView;
return bottomDialog;
}
}
這個封裝控件大致就是這樣瘫怜,有興趣了解的朋友請來我的github看看
https://github.com/Ccapton/BottomDialog
https://github.com/Ccapton