在Android開發中咱們經常須要使用Dialog來處理一些彈窗操做。雖然Android系統自己爲咱們封裝了一個自帶的彈窗Dialog,可是因爲Android操做系統的不一樣,致使了每一個手機彈窗頁面的不一樣,以致於咱們很難用系統的去統同樣式。而且UI會以爲系統的彈窗過於醜陋,但願本身來作一個因而咱們便須要本身來處理一個Dialog彈窗。今天叫你們利用Builder構造者模式本身來封裝一個彈窗Dialog。android
首先肯定一下,彈窗咱們須要哪些功能?git
分析完了需求以後咱們即可以根據需求來擼代碼了。github
首先咱們寫一個CommonDialog類讓他繼承Dialog。 此時咱們必須複寫onCreat(),在onCreat()我麼進行一些設置操做。這裏咱們設置setContentView()加載佈局樣式,設置setCancelable()是否點擊彈窗之外使得彈窗消失。bash
public class CommonDialog extends Dialog {
private Context context;
private View view;
private boolean cancelTouchout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(view);
setCancelable(cancelTouchout);
}
}
複製代碼
其實這時候咱們就開始要編寫Builder構造者模式的代碼了。ide
構造者模式,顧名思義,就是根據咱們的須要往代碼上添加需求。例如,咱們須要設置title標題的內容,此時咱們就添加上這個功能,若是須要設置message內容的功能咱們也設置上這個功能。若是不須要則不添加這段代碼。佈局
先根據不一樣樣式加載不一樣的佈局。此時咱們利用LayoutInflater來處理。佈局樣式由參數傳遞進來。學習
public Builder view(int resView) {
view = LayoutInflater.from(context).inflate(resView, null);
return this;
}
複製代碼
其次,再根據是否能夠點擊彈窗外部使得彈窗消失。ui
public Builder cancelTouchout(boolean val) {
cancelTouchout = val;
return this;
}
複製代碼
傳入的val若爲true表明能夠消失,若是傳入的爲false則表明不能消失。this
緊接着咱們再來看看若是根據title和message來設置不一樣的內容。 這裏咱們的參數設置爲兩個,一個是須要設置內容的id,一個是設置內容的文字title/message。咱們先經過findViewById去查找到這個View中的控件,以後再根據文字內容將文字設置到控件上去。spa
//設置標題title
public Builder setTitle(int viewRes,String title){
TextView txtTitle = (TextView) view.findViewById(viewRes);
txtTitle.setText(title);
return this;
}
//設置內容message
public Builder setMessage(int viewRes,String message){
TextView txtMessage = (TextView)view.findViewById(viewRes);
txtMessage.setText(message);
return this;
}
複製代碼
而後咱們就該去設置點擊事件了。 點擊事件咱們能夠借鑑設置title和message的狀況來處理,經過傳入一個點擊控件的id來查找id,以後經過View.OnClickListener來回調這個點擊事件處理點擊邏輯便可。
public Builder addViewOnclick(int viewRes,View.OnClickListener listener){
view.findViewById(viewRes).setOnClickListener(listener);
return this;
}
複製代碼
最後咱們只須要把最後寫一個build返回一個CommonDialog便可。可是若是此時咱們調用使用這個CommonDialog時你會發現咱們無論如何設置加載的View,發現大小其實都是不變的。這是怎麼回事?其實這是由於咱們的背景色一塊兒被設置進入了View佈局中。若是此時咱們把咱們加載的View背景設置爲黑色(#000000),就會神奇的發現,在View旁邊還有一些白色的存在。正是由於這些白色,致使了咱們不管如何設置彈窗寬度都顯示的是原來的大小。若是你要設置爲圓角,那更是不太可能。
那該如何處理這種狀況?其實很簡單,咱們僅僅須要設置一下將彈窗風格的style設置一個透明的背景便可處理好這種狀況。
咱們在value-style中設置一個style風格樣式,將背景設置爲透明便可。
<!--Dialog將白色背景變透明-->
<style name="Dialog" parent="android:style/Theme.Dialog">
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
</style>
複製代碼
此時咱們再在CommonDialog中設置一個style樣式,根據傳入的樣式來處理風格。
public Builder style(int resStyle) {
this.resStyle = resStyle;
return this;
}
複製代碼
最後咱們再寫兩個CommonDialog的構造方法,根據是否有傳入style來調用不一樣父類。完成操做。
private CommonDialog(Builder builder) {
super(builder.context);
context = builder.context;
cancelTouchout = builder.cancelTouchout;
view = builder.view;
}
private CommonDialog(Builder builder, int resStyle) {
super(builder.context, resStyle);
context = builder.context;
cancelTouchout = builder.cancelTouchout;
view = builder.view;
}
複製代碼
到此咱們的整個代碼就所有操做完畢。
使用起來也很是簡單,咱們只須要建立一個CommonDialog.Builder根據不一樣的業務需求來添加不一樣操做便可。
CommonDialog build;
//dialog彈窗
private void dialog(){
build = new CommonDialog.Builder(this)
.view(R.layout.dialog)//設置彈窗的樣式layout
.style(R.style.Dialog) //設置主題,這裏能夠將背景設爲透明,這樣只顯示你須要顯示的dialog部分
.cancelTouchout(true) //設置點擊dialog以外是否彈窗消失,true爲消失,false爲不消失
.setTitle(R.id.txt_title, "這是一個彈窗標題")//根據id來設置標題的顯示文字
.setMessage(R.id.txt_message, "這是一個彈窗消息內容")//根據id來設置消息內容的顯示文字
.addViewOnclick(R.id.txt_sure, new View.OnClickListener() {//處理確認點擊事件
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點擊了肯定按鈕", Toast.LENGTH_SHORT).show();
build.dismiss();
}
})
.addViewOnclick(R.id.txt_cancel, new View.OnClickListener() {//處理取消的點擊事件
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點擊了取消按鈕", Toast.LENGTH_SHORT).show();
build.dismiss();
}
}).build();
build.show();
}
複製代碼
代碼已經上傳至github,只需將CommonDialog這個類複製到本身項目中再複製style中的Dialog便可使用,方便快捷。歡迎start。github傳送門
有興趣能夠關注個人小專欄,學習更多職場產品思考知識:小專欄