[Android] 仿IOS實現自定義Dialog,底部彈窗和中間彈窗工具
用過Android的預設對話方塊的都懂,不管是哪個版本的對話方塊,都醜到爆!就算是Google推崇的Material Design風格的彈窗一樣不好看,基本每款APP都不會去使用預設的對話方塊樣式,他們都有自己的風格,怎樣去改變預設的對話方塊樣式呢?只能自定義了,將系統對話方塊改為自己喜歡或者是APP特有風格的樣式。本文將介紹如何去實現自定義Dialog,仿IOS,並新增動畫效果,並提供豐富的方法呼叫,讓開發者可以在已有樣式的基礎上進行進一步的細節改變。算是一個工具類了,直接copy就可以直接用了。
一、舉例
這是Android 4.2版本的彈窗:
這是Android 7.0版本的彈窗:
我是沒有覺得很好看。大概這就是程式設計師的審美吧。
下面再看一下IOS的對話方塊,話說找這個對話方塊太難了。我找了好久好久,都找不到有什麼地方能彈窗,不找的時候一直有。還好不負所望,找了倆。中間彈窗對話方塊:
IOS底部彈窗:
是不是感覺還不錯!Android的系統對話方塊雖然樣式很醜,但畢竟是開源系統,它可以輕鬆實現對話方塊樣式的自定義,而且Android的對話方塊的樣式基本一個APP就一個樣,種類繁多,樣式豐富。
二、實現效果
經過自定義後,現在的Dialog已經能實現各種豐富的樣式了。
可以看到自定義的Dialog已經實現了IOS效果的彈窗。並且裡面的按鈕、文字、標題都可以在使用時進行各種詳細的定義,如改變文字顏色、文字大小、文字粗體、背景色,還可以傳入自己定義的動畫效果去替換原有的動畫效果,如果不覺得突兀,還可以取消動畫效果
三、特點
其實特點就是仿照IOS的特點。
1、圓角。經過自定義的彈窗,其圓角效果已經和IOS的很接近了,而且圓角很大,當然如果你不喜歡,可以在XML檔案中進行修改,目前的圓角是15。
2、Dialog控制元件之間的間隔很大。這應該也算是IOS風格的一個特色了,它的文字、留白都非常大,如果說多數Android的彈窗效果都是小巧玲瓏的話,這種風格可以說是豪邁奔放了。
3、動畫效果。這個動畫效果是完全仿IOS的,底部彈窗效果不是很像,只是加了一個平移效果。中間彈窗的話還能算是精仿,包括縮放和透明度的變化。
四、全部程式碼
說實話,全部程式碼並不長,只是註釋太多,佔用了絕大部分的空間。
1、MyDialog核心類
package com.my.dialogdemo;
import android.app.Dialog;
import android.content.Context;
import android.support.v7.app.ActionBar;
import android.text.TextPaint;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static android.content.ContentValues.TAG;
public class MyDialog {
private Context mContext; //上下文
private View mDialogLayout; //彈窗佈局
private boolean mCancelable = true; //返回鍵、窗體外區域是否可點選取消,預設可以
private View.OnClickListener positiveButton; //positive區域監聽器
private View.OnClickListener negativeButton; //negative區域監聽器
private AdapterView.OnItemClickListener mItemClickListener; //item的點選事件
private Dialog dialog; //構建的彈窗
private int mCustomAnim; //自定義動畫
private boolean mIsShowTitle; //是否顯示標題,預設不顯示
private boolean mIsShowNegativeButton; //是否顯示negative區域按鈕,預設不顯示
private boolean mIsShowPositiveButton; //是否顯示positive區域按鈕,預設不顯示
private boolean mIsShowListView; //是否在內容區顯示ListView,預設不顯示
private boolean mIsHaveCustomAnim; //是否含有自定義的動畫效果
private boolean mIsShowBottomTitle; //是否顯示底部彈窗標題,預設不顯示
private boolean mIsShowBottomNegativeButton; //是否顯示底部彈窗的negative區域按鈕,預設不顯示
private boolean mIsBottomDialog; //是否是底部彈窗,預設中間彈窗
private MyAdapter mAdapter; //Adapter,設配自定義的資料
private List<StringItemBean> mDataList; //資料來源,顯示的文字
public static final String BOTTOM = "BOTTOM"; //底部彈窗標誌
/**
* 中間彈窗,建構函式
*
* @param context 上下文
*/
public MyDialog(Context context) {
this.mContext = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDialogLayout = inflater.inflate(R.layout.my_custom_dialog_layout, null);
}
/**
* 中間彈窗,建構函式,需要傳入自定義動畫的ID,若傳入0,則代表無動畫
*
* @param context 上下文
* @param customAnim 自定義的動畫效果ID
*/
public MyDialog(Context context, int customAnim) {
this(context);
mCustomAnim = customAnim;
mIsHaveCustomAnim = true;
}
/**
* 底部彈窗,建構函式,需要傳入String型別引數,BOTTOM,才會顯示底部Dialog
*
* @param context 上下文
* @param gravity 位置,String型別,必須是"BOTTOM"才會顯示底部Dialog
*/
public MyDialog(Context context, String gravity) {
this.mContext = context;
if (gravity.equals(BOTTOM)) {
mIsBottomDialog = true;
}
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDialogLayout = inflater.inflate(R.layout.my_custom_bottom_dialog_layout, null);
}
/**
* 都不彈窗,建構函式,需要傳入String型別引數,BOTTOM,才會顯示底部Dialog;自定義動畫效果
*
* @param context 上下文
* @param customAnim 自定義的動畫效果
* @param gravity 位置,String型別,必須是"BOTTOM"才會顯示底部Dialog
*/
public MyDialog(Context context, int customAnim, String gravity) {
this.mContext = context;
if (gravity.equals(BOTTOM)) {
mIsBottomDialog = true;
}
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDialogLayout = inflater.inflate(R.layout.my_custom_bottom_dialog_layout, null);
mCustomAnim = customAnim;
mIsHaveCustomAnim = true;
}
/**
* 能否返回鍵取消和點選彈窗外部區域取消
* 中間、底部彈窗共用
*
* @param boolean1 true 代表可以取消,false 不可取消
* @return this
*/
public MyDialog setCancelable(Boolean boolean1) {
this.mCancelable = boolean1;
return this;
}
/**
* 中間彈窗,設定標題 int型 不常用,適配更多型別可過載多個該方法,引數型別不同即可
*
* @param title int型引數
* @return this
*/
public MyDialog setTitle(int title) {
mIsShowTitle = true;
((TextView) mDialogLayout.findViewById(R.id.title)).setText(title);
return this;
}
/**
* 中間彈窗,設定標題 String型 最常用
*
* @param title String型引數
* @return this
*/
public MyDialog setTitle(String title) {
mIsShowTitle = true;
((TextView) mDialogLayout.findViewById(R.id.title)).setText(title);
return this;
}
/**
* 中間彈窗,設定標題文字大小
*
* @param size 大小值,int型
* @return this
*/
public MyDialog setTitleSize(int size) {
((TextView) mDialogLayout.findViewById(R.id.title)).setTextSize(size);
return this;
}
/**
* 中間彈窗,設定標題文字顏色
*
* @param color 顏色
* @return this
*/
public MyDialog setTitleColor(int color) {
((TextView) mDialogLayout.findViewById(R.id.title)).setTextColor(mContext.getResources().getColor(color));
return this;
}
/**
* 中間彈窗,設定標題字型為粗體
*
* @return this
*/
public MyDialog setTitleStyleBold(){
TextView tv = (TextView)mDialogLayout.findViewById(R.id.title);
TextPaint tp = tv.getPaint();
tp.setFakeBoldText(true);
return this;
}
/**
* 中間彈窗,設定標題區域的背景顏色 不常用
*
* @param color 顏色
* @return this
*/
public MyDialog setTitleBackgroundColor(int color) {
mDialogLayout.findViewById(R.id.title_background).setBackgroundColor(mContext.getResources().getColor(color));
return this;
}
/**
* 中間彈窗,設定內容,int型,不常用,適配更多型別可過載多個該方法,引數型別不同即可
*
* @param message int型引數
* @return this
*/
public MyDialog setMessage(int message) {
((TextView) mDialogLayout.findViewById(R.id.message)).setText(message);
return this;
}
/**
* 中間彈窗,設定內容,String型,最常用
*
* @param message String型資訊
* @return this
*/
public MyDialog setMessage(String message) {
((TextView) mDialogLayout.findViewById(R.id.message)).setText(message);
return this;
}
/**
* 中間彈窗,設定內容的文字顏色
*
* @param color 文字顏色
* @return this
*/
public MyDialog setMessageColor(int color){
((TextView) mDialogLayout.findViewById(R.id.message)).setTextColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 中間彈窗,設定內容區域的背景色
*
* @param color 背景色
* @return this
*/
public MyDialog setMessageBackground(int color){
mDialogLayout.findViewById(R.id.content).setBackgroundColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 中間彈窗,設定negative區域的文字和點選事件,一般為"取消"
* 同AlertDialog.Builder的設定名稱相同
*
* @param negativeText 按鈕文字
* @param listener 監聽器
* @return this
*/
public MyDialog setNegativeButton(String negativeText, View.OnClickListener listener) {
mIsShowNegativeButton = true;
((TextView) mDialogLayout.findViewById(R.id.negative)).setText(negativeText);
this.negativeButton = listener;
return this;
}
/**
* 中間彈窗,設定negative區域顯示文字的顏色,如藍色的"取消"文字
* 多數APP如網購APP,在某個商品瀏覽頁面,不希望使用者退出又必須要給出退出提示時,多將negative設定為顯眼的顏色
* 而positive設定為暗色。所以該方法還是使用比較常見的
*
* @param color 顏色
* @return this
*/
public MyDialog setNegativeButtonColor(int color) {
((TextView) mDialogLayout.findViewById(R.id.negative)).setTextColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 中間彈窗,設定negative文字的大小
*
* @param size 文字大小
* @return this
*/
public MyDialog setNegativeButtonTextSize(int size){
((TextView) mDialogLayout.findViewById(R.id.negative)).setTextSize(size);
return this;
}
/**
* 中間彈窗,設定negative文字字型為粗體
*
* @return this
*/
public MyDialog setNegativeButtonStyleBold(){
TextView tv = (TextView) mDialogLayout.findViewById(R.id.negative);
TextPaint tp = tv.getPaint();
tp.setFakeBoldText(true);
return this;
}
/**
* 中間彈窗,設定positive區域的文字和點選事件,一般為"確定"
* 同AlertDialog.Builder的設定名稱相同
*
* @param positiveText 按鈕文字
* @param listener 監聽器
* @return this
*/
public MyDialog setPositiveButton(String positiveText, View.OnClickListener listener) {
mIsShowPositiveButton = true;
((TextView) mDialogLayout.findViewById(R.id.positive)).setText(positiveText);
this.positiveButton = listener;
return this;
}
/**
* 中間彈窗,設定positive區域顯示文字的顏色,如藍色的"確定"文字
*
* @param color 顏色
* @return this
*/
public MyDialog setPositiveButtonColor(int color) {
((TextView) mDialogLayout.findViewById(R.id.positive)).setTextColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 中間彈窗,設定positive區域顯示文字的大小
*
* @param size 文字大小
* @return this
*/
public MyDialog setPositiveButtonSize(int size){
((TextView) mDialogLayout.findViewById(R.id.positive)).setTextSize(size);
return this;
}
/**
* 中間彈窗,設定positive文字字型為粗體
*
* @return this
*/
public MyDialog setPositiveButtonStyleBold(){
TextView tv = (TextView) mDialogLayout.findViewById(R.id.positive);
TextPaint tp = tv.getPaint();
tp.setFakeBoldText(true);
return this;
}
/**
* 中間彈窗,重新設定內容的顯示控制元件
* 預設的Dialog只有一個顯示的TextView,替換顯示控制元件可以實現顯示更豐富的內容,如圖片 + 文字。
*
* @param v 要顯示的控制元件
* @return this
*/
public MyDialog setView(View v) {
((FrameLayout) mDialogLayout.findViewById(R.id.sv)).removeAllViews();
//進行判斷,否則第二次彈出Dialog時會報異常
//異常:java.lang.IllegalStateException: The specified child already has a parent.
// You must call removeView() on the child's parent first.
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null) {
parent.removeAllViews();
}
((FrameLayout) mDialogLayout.findViewById(R.id.sv)).addView(v);
return this;
}
/**
* 設定顯示內容為ListView,傳入要顯示的陣列和監聽事件
* 顯示預設顏色
* 中間彈窗和底部彈窗共用
*
* @param data 資料來源,陣列,String型別
* @param listener item的監聽事件,短按型別
* @return this
*/
public MyDialog setListView(String[] data, AdapterView.OnItemClickListener listener) {
setListView(Arrays.asList(data), listener);
return this;
}
/**
* 設定顯示內容為ListView,傳入要顯示的list和監聽事件
* 顯示預設顏色
* 中間彈窗和底部彈窗共用
*
* @param list 資料來源,list,String型別
* @param listener item的監聽事件,短按型別
* @return this
*/
public MyDialog setListView(List<String> list, AdapterView.OnItemClickListener listener) {
mItemClickListener = listener;
mIsShowListView = true;
mDataList = new ArrayList<>();
for (String str : list) {
mDataList.add(new StringItemBean(str));
}
mAdapter = new MyAdapter(mContext, R.layout.string_item_layout, mDataList);
return this;
}
/**
* 設定顯示內容為ListView,可以設定item的顏色,且可以分別設定
* 資料來源型別:陣列,陣列
* 中間彈窗和底部彈窗共用
*
* @param data 資料來源,陣列,String型別
* @param colors 顏色資料來源,陣列,Integer型別
* @param listener item的監聽事件,短按型別
* @return this
*/
public MyDialog setListView(String[] data, Integer[] colors, AdapterView.OnItemClickListener listener) {
setListView(Arrays.asList(data), Arrays.asList(colors), listener);
return this;
}
/**
* 設定顯示內容為ListView,可以設定item的顏色,且可以分別設定
* 資料來源型別:List,陣列
* 中間彈窗和底部彈窗共用
*
* @param list 資料來源,List,String型別
* @param colors 顏色資料來源,陣列,Integer型別
* @param listener item的監聽事件,短按型別
* @return this
*/
public MyDialog setListView(List<String> list, Integer[] colors, AdapterView.OnItemClickListener listener) {
setListView(list, Arrays.asList(colors), listener);
return this;
}
/**
* 設定顯示內容為ListView,可以設定item的顏色,且可以分別設定
* 資料來源型別:陣列,List
* 中間彈窗和底部彈窗共用
*
* @param data 資料來源,陣列,String型別
* @param colors 顏色資料來源,List,Integer型別
* @param listener item的監聽事件,短按型別
* @return this
*/
public MyDialog setListView(String[] data, List<Integer> colors, AdapterView.OnItemClickListener listener) {
setListView(Arrays.asList(data), colors, listener);
return this;
}
/**
* 設定顯示內容為ListView,可以設定item的顏色,且可以分別設定
* 資料來源型別:List,List,
* 不管傳入的資料來源和顏色資料來源的型別是陣列還是List,最後都要使用這個方法進行設定
* 中間彈窗和底部彈窗共用
*
* @param list 資料來源,List,String型別
* @param colors 顏色資料來源,List,Integer型別
* @param listener item的監聽事件
* @return this
*/
public MyDialog setListView(List<String> list, List<Integer> colors, AdapterView.OnItemClickListener listener) {
mIsShowListView = true;
mItemClickListener = listener;
mDataList = new ArrayList<>();
for (String str : list) {
mDataList.add(new StringItemBean(str));
}
mAdapter = new MyAdapter(mContext, R.layout.string_item_layout, mDataList, colors);
return this;
}
/**
* 底部彈窗,重新設定內容的顯示控制元件
*
* @param v 要顯示的控制元件
* @return this
*/
public MyDialog setBottomView(View v) {
((LinearLayout) mDialogLayout.findViewById(R.id.list_content)).removeAllViews();
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null) {
parent.removeAllViews();
}
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
if (getMsgListViewHeight((ListView) v) > height / 5 * 3){
//如果List的高度大於螢幕高度的4/5
LinearLayout.LayoutParams LayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,height / 5 * 3);
mDialogLayout.findViewById(R.id.list_content).setLayoutParams(LayoutParams);
}
((LinearLayout) mDialogLayout.findViewById(R.id.list_content)).addView(v);
return this;
}
/**
* 底部彈窗,設定標題
*
* @param title 整型標題
* @return this
*/
public MyDialog setBottomTitle(int title) {
mIsShowBottomTitle = true;
((TextView) mDialogLayout.findViewById(R.id.bottom_title)).setText(title);
return this;
}
/**
* 底部彈窗,設定標題
*
* @param title String型標題
* @return this
*/
public MyDialog setBottomTitle(String title) {
mIsShowBottomTitle = true;
((TextView) mDialogLayout.findViewById(R.id.bottom_title)).setText(title);
return this;
}
/**
* 底部彈窗,設定標題文字的顏色
*
* @param color 文字顏色
* @return this
*/
public MyDialog setBottomTitleColor(int color) {
((TextView) mDialogLayout.findViewById(R.id.bottom_title)).setTextColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 設定底部彈窗標題文字的文字大小
*
* @param size 文字大小
* @return this
*/
public MyDialog setBottomTitleSize(int size){
((TextView) mDialogLayout.findViewById(R.id.bottom_title)).setTextSize(size);
return this;
}
/**
* 底部彈窗,設定標題區域的背景色
*
* @param color 背景色
* @return this
*/
public MyDialog setBottomTitleBackground(int color) {
mIsShowBottomTitle = true;
mDialogLayout.findViewById(R.id.bottom_title_content).setBackgroundColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 底部彈窗,設定Negative的文字和點選事件,點選事件可為null
*
* @param negativeText 文字,如"取消"
* @param listener negative區域的監聽事件
* @return this
*/
public MyDialog setBottomNegativeButton(String negativeText, View.OnClickListener listener) {
mIsShowBottomNegativeButton = true;
((TextView) mDialogLayout.findViewById(R.id.bottom_negative)).setText(negativeText);
this.negativeButton = listener;
return this;
}
/**
* 底部彈窗,設定negative文字的顏色
*
* @param color 文字顏色
* @return this
*/
public MyDialog setBottomNegativeButtonColor(int color) {
((TextView) mDialogLayout.findViewById(R.id.bottom_negative)).setTextColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 底部彈窗,設定negative文字的字型大小
*
* @param size 文字大小
* @return this
*/
public MyDialog setBottomNegativeButtonSize(int size){
((TextView) mDialogLayout.findViewById(R.id.bottom_negative)).setTextSize(size);
return this;
}
/**
* 設定底部彈窗negative文字的字型為粗體
*
* @return this
*/
public MyDialog setBottomNegativeButtomStyleBold(){
TextView tv = (TextView) mDialogLayout.findViewById(R.id.bottom_negative);
TextPaint tp = tv.getPaint();
tp.setFakeBoldText(true);
return this;
}
/**
* 設定底部彈窗negative區域的背景色
*
* @param color 背景色
* @return this
*/
public MyDialog setBottomNegativeButtonBackground(int color) {
mDialogLayout.findViewById(R.id.bottom_negative_content).setBackgroundColor(
mContext.getResources().getColor(color));
return this;
}
/**
* 獲取List的總高度
* @param mMessageCenterLv ListView
* @return this
*/
private int getMsgListViewHeight(ListView mMessageCenterLv) {
//ListView總高度
int totalHeight = 0;
ListAdapter listAdapter = mMessageCenterLv.getAdapter();
if (listAdapter == null) {
return totalHeight;
}
int height = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, mMessageCenterLv);
int desiredWidth = View.MeasureSpec.makeMeasureSpec(mMessageCenterLv.getWidth(), View.MeasureSpec.AT_MOST);
listItem.measure(desiredWidth, 0);
height += (listItem.getMeasuredHeight());
Log.d(TAG, "每項item的高度:"+listItem.getMeasuredHeight());
}
totalHeight = height + (mMessageCenterLv.getDividerHeight() * (listAdapter.getCount() - 1));
return totalHeight;
}
/**
* 構建窗體,所有鏈式呼叫都在這裡進行集中整理
*
* @return 構建完畢的窗體
*/
public Dialog builder() {
dialog = new Dialog(mContext, R.style.MyDialogTheme);
dialog.setCancelable(mCancelable);
dialog.addContentView(mDialogLayout, new ActionBar.LayoutParams(
ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT));
//如果是中間彈窗
if (!mIsBottomDialog) {
//如果沒有設定Title
if (!mIsShowTitle) {
mDialogLayout.findViewById(R.id.title_background).setVisibility(View.GONE);
}
//如果設定顯示了ListView
if (mIsShowListView) {
ListView listView = new ListView(mContext);
LinearLayout.LayoutParams listLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
listView.setLayoutParams(listLayoutParams);
listView.setAdapter(mAdapter);
int list_height = getMsgListViewHeight(listView); //獲取ListView的高度
Log.v(TAG, "List的總高度為:"+list_height);
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
int height = wm.getDefaultDisplay().getHeight();
Log.d(TAG, "螢幕高度:" + height);
if (list_height > height*3/5) {
list_height = height*3/5;
}
LinearLayout.LayoutParams LayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, list_height);
((ScrollView) mDialogLayout.findViewById(R.id.sv)).setLayoutParams(LayoutParams);
setView(listView);
if (mItemClickListener != null) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mItemClickListener.onItemClick(parent, view, position, id);
dialog.dismiss();
}
});
} else {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dialog.dismiss();
}
});
}
}
//如果設定了negative區域的按鈕
if (mIsShowNegativeButton) {
if (negativeButton != null) {
mDialogLayout.findViewById(R.id.negative).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
negativeButton.onClick(v);
dialog.dismiss();
}
});
} else {
mDialogLayout.findViewById(R.id.negative).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
} else {
mDialogLayout.findViewById(R.id.negative).setVisibility(View.GONE);
mDialogLayout.findViewById(R.id.line3).setVisibility(View.GONE);
}
//如果設定了positive區域的按鈕
if (mIsShowPositiveButton) {
if (positiveButton != null) {
mDialogLayout.findViewById(R.id.positive).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
positiveButton.onClick(v);
dialog.dismiss();
}
});
} else {
mDialogLayout.findViewById(R.id.positive).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
} else {
mDialogLayout.findViewById(R.id.positive).setVisibility(View.GONE);
mDialogLayout.findViewById(R.id.line3).setVisibility(View.GONE);
}
mDialogLayout.findViewById(R.id.negative).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (negativeButton != null) {
negativeButton.onClick(v);
}
dialog.dismiss();
}
});
//如果有自定義的動畫效果傳入,就顯示傳入的動畫效果,否則顯示預設效果,另外:傳入0,無動畫
if (mIsHaveCustomAnim) {
if (mCustomAnim != 0) { //設定顯示dialog的顯示動畫
dialog.getWindow().setWindowAnimations(mCustomAnim);
}
} else { //設定預設dialog的顯示動畫
dialog.getWindow().setWindowAnimations(R.style.DialogInAndOutAnim);
}
} else { //是底部彈窗
//如果沒有設定底部彈窗標題
if (!mIsShowBottomTitle) {
mDialogLayout.findViewById(R.id.bottom_title_content).setVisibility(View.GONE);
}
//如果設定了顯示ListView
if (mIsShowListView) {
ListView listView = new ListView(mContext);
LinearLayout.LayoutParams listLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
listView.setLayoutParams(listLayoutParams);
listView.setAdapter(mAdapter);
setBottomView(listView);
if (mItemClickListener != null) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mItemClickListener.onItemClick(parent, view, position, id);
dialog.dismiss();
}
});
} else {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dialog.dismiss();
}
});
}
}
//如果設定了顯示底部Negative按鈕
if (mIsShowBottomNegativeButton) {
if (negativeButton != null) {
mDialogLayout.findViewById(R.id.bottom_negative_content).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
negativeButton.onClick(v);
dialog.dismiss();
}
});
} else {
mDialogLayout.findViewById(R.id.bottom_negative_content).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
} else {
mDialogLayout.findViewById(R.id.bottom_negative_content).setVisibility(View.GONE);
}
//如果有自定義的動畫效果傳入,就顯示傳入的動畫效果,否則顯示預設效果,另外:傳入0,無動畫
if (mIsHaveCustomAnim) {
if (mCustomAnim != 0) { //設定顯示底部dialog的顯示動畫
dialog.getWindow().setWindowAnimations(mCustomAnim);
}
} else { //設定預設底部dialog的顯示動畫
dialog.getWindow().setWindowAnimations(R.style.BottomDialogInAndOutAnim);
}
Window dialogWindow = dialog.getWindow();
dialogWindow.setGravity(Gravity.BOTTOM);
}
return dialog;
}
}
2、所有Layout檔案程式碼
(1)、中間彈窗設計:my_custom_dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/my_dialog_bg"
android:orientation="vertical">
<LinearLayout
android:id="@+id/title_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="50dp"
android:paddingEnd="15dp"
android:paddingStart="15dp"
android:paddingTop="10dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:text="標題"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
<ScrollView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:fadingEdge="none"
android:overScrollMode="never">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:minHeight="80dp"
android:orientation="horizontal">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="內容"
android:textColor="@color/black"
android:textSize="16sp" />
</LinearLayout>
</ScrollView>
<View
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/line" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:gravity="center"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:text="取消"
android:textColor="@color/gray"
android:textSize="18sp"
android:textStyle="normal" />
<View
android:id="@+id/line3"
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="@color/line" />
<TextView
android:id="@+id/positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:gravity="center"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:text="確認"
android:textColor="@color/blue"
android:textSize="18sp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
(2)、底部彈窗設計:my_custom_bottom_dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/my_dialog_bg"
android:orientation="vertical">
<LinearLayout
android:id="@+id/bottom_title_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/bottom_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:layout_gravity="center"
android:text="標題" />
<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/line"/>
</LinearLayout>
<LinearLayout
android:id="@+id/list_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/bottom_negative_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/my_dialog_bg"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:padding="15dp"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/bottom_negative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:textSize="18sp"
android:textColor="@color/blue" />
</LinearLayout>
</LinearLayout>
(3)、彈窗List的item設計:string_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:gravity="center">
<!-- item顯示文字,預設大小18,字型顏色藍色 -->
<TextView
android:id="@+id/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@color/blue" />
</RelativeLayout>
(4)、測試使用的替換佈局:edit_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/edittext_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp"
android:orientation="horizontal">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:background="@drawable/my_edit_bg"
android:hint="請輸入資訊"/>
</LinearLayout>
3、所有drawable檔案程式碼
(1)、彈窗形狀設計:my_dialog_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<!-- 圓角 -->
<corners
android:radius="12dp"/>
</shape>
(2)、編輯框形狀設計:my_edit_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<corners android:radius="2dp" />
<stroke
android:width="0.5dp"
android:color="#888888"
/>
</shape>
4、所有動畫效果檔案程式碼
(1)、中間彈窗進入動畫:dialog_in_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration = "300"
android:fromXScale="1.2"
android:toXScale="1.0"
android:fromYScale="1.2"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"/>
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
(2)、中間彈窗消失動畫:dialog_out_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="300"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.2"
android:toYScale="1.2" />
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
(3)、底部彈窗進入動畫:bottom_dialog_in.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromYDelta="100%"
android:toYDelta="0" />
(4)、底部彈窗消失動畫:bottom_dialog_out.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromYDelta="0"
android:toYDelta="100%" />
5、使用到的color程式碼
res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<!-- 灰色 -->
<color name="gray">#333333</color>
<!-- 分割線顏色 -->
<color name="line">#20888888</color>
<!-- 藍色 0099ff-->
<color name="blue">#1e90ff</color>
<!-- 黑色 -->
<color name="black">#000000</color>
<!-- 紅色 -->
<color name="red">#EE0000</color>
<!-- 橘黃 -->
<color name="yellow">#EE7600</color>
<!-- 綠色 -->
<color name="green">#458B00</color>
</resources>
6、彈窗樣式style程式碼
res/values/styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!-- 自定義對話方塊樣式,底部彈窗和中間彈窗共用 -->
<style name="MyDialogTheme" parent="@android:style/Theme.Dialog">
<!-- 邊框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮現在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 無標題 -->
<item name="android:windowNoTitle">true</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
</style>
<!-- 自定義的Dialog進出動畫 中間彈窗 -->
<style name="DialogInAndOutAnim">
<item name="android:windowEnterAnimation">@anim/dialog_in_anim</item>
<item name="android:windowExitAnimation">@anim/dialog_out_anim</item>
</style>
<!-- 自定義Dialog進出動畫 底部彈窗 -->
<style name="BottomDialogInAndOutAnim">
<item name="android:windowEnterAnimation">@anim/bottom_dialog_in</item>
<item name="android:windowExitAnimation">@anim/bottom_dialog_out</item>
</style>
</resources>
7、其他程式碼
(1)、彈窗中List使用的Adapter:MyAdapter.java
package com.my.dialogdemo;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
public class MyAdapter extends ArrayAdapter<StringItemBean> {
private int mResourceId; //資源ID,佈局檔案
private List<Integer> mColorsList; //顏色list
private boolean mIsHaveColor; //是否傳入了顏色
private Context mContext; //上下文
public MyAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<StringItemBean> objects) {
super(context, resource, objects);
mResourceId = resource;
mContext = context;
}
public MyAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<StringItemBean> objects,List<Integer> colors) {
super(context, resource, objects);
mResourceId = resource;
mColorsList = colors;
mContext = context;
mIsHaveColor = true;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//獲取當前item的例項
StringItemBean stringItemBean = getItem(position);
View view;
ViewHolder viewHolder;
if (convertView == null) { //快取為空
//載入佈局
view = LayoutInflater.from(getContext()).inflate(mResourceId, parent, false);
//只有在快取為空的情況下,才會建立ViewHolder例項
viewHolder = new ViewHolder();
//關聯控制元件
viewHolder.item = (TextView) view.findViewById(R.id.item);
//將ViewHolder儲存到view中
view.setTag(viewHolder);
} else { //快取不為空
view = convertView;
//重新獲取ViewHolder
viewHolder = (ViewHolder) view.getTag();
}
//設定顯示內容
if (mIsHaveColor){
viewHolder.item.setText(stringItemBean.getItemStr());
viewHolder.item.setTextColor(mContext.getResources().getColor(mColorsList.get(position)));
}else{
viewHolder.item.setText(stringItemBean.getItemStr());
}
return view;
}
//內部類ViewHolder
private class ViewHolder {
TextView item;
}
}
(2)、彈窗中List的item的實體類:StringItemBean.java
package com.my.dialogdemo;
public class StringItemBean {
/**
* ListView的Item內容
*/
private String itemStr;
public StringItemBean(String str){
this.itemStr = str;
}
public String getItemStr() {
return itemStr;
}
public void setItemStr(String itemStr) {
this.itemStr = itemStr;
}
}
8、專案結構圖
五、具體使用
(1)、主介面佈局檔案:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="中間彈出,有標題,雙按鈕"/>
<Button
android:id="@+id/button_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="中間彈出,無標題,單按鈕"/>
<Button
android:id="@+id/button_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="中間彈出,有標題,藍色List"/>
<Button
android:id="@+id/button_4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="中間彈出,無標題,彩色List"/>
<Button
android:id="@+id/button_5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="中間彈出,有標題,內容替換為EditText"/>
<Button
android:id="@+id/button_6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="底部彈出,有標題,藍色List"/>
<Button
android:id="@+id/button_7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="底部彈出,無標題,彩色List"/>
</LinearLayout>
(2)、主介面呼叫Dialog程式碼:
package com.my.dialogdemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText mEditText; //編輯框
//資料來源,陣列和List
private String[] mDataArray = {"我是 item 1", "我是 item 2", "我是 item 3", "我是 item 4"};
private List<String> mDataList = Arrays.asList(mDataArray);
//顏色值陣列和List
private Integer[] mColorArray = {R.color.blue,R.color.red,R.color.yellow,R.color.green};
private List<Integer> mColorsList = Arrays.asList(mColorArray);
LinearLayout mEditLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第 1 個按鈕
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(this);
//第 2 個按鈕
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(this);
//第 3 個按鈕
Button button3 = (Button) findViewById(R.id.button_3);
button3.setOnClickListener(this);
//第 4 個按鈕
Button button4 = (Button) findViewById(R.id.button_4);
button4.setOnClickListener(this);
//第 5 個按鈕
Button button5 = (Button) findViewById(R.id.button_5);
button5.setOnClickListener(this);
//第 6 個按鈕
Button button6 = (Button) findViewById(R.id.button_6);
button6.setOnClickListener(this);
//第 7 個按鈕
Button button7 = (Button) findViewById(R.id.button_7);
button7.setOnClickListener(this);
//引入EditText的佈局檔案,找到EditText控制元件
LayoutInflater editInflater = LayoutInflater.from(this);
mEditLayout = (LinearLayout) editInflater.inflate(R.layout.edit_layout, null);
mEditText = (EditText) mEditLayout.findViewById(R.id.editText);
}
/**
* 點選事件
*
* @param v 按鈕
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
//中間彈出,有標題,雙按鈕
case R.id.button_1: {
new MyDialog(MainActivity.this)
.setTitle("標題")
.setMessage("中間彈出,有標題,雙按鈕")
.setNegativeButton("取消", new View.OnClickListener() {
//點選事件可以設定為null
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了取消",
Toast.LENGTH_SHORT).show();
}
})
.setPositiveButton("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了確定",
Toast.LENGTH_SHORT).show();
}
})
.setCancelable(false)
.builder()
.show();
break;
}
//中間彈出,無標題,單按鈕
case R.id.button_2: {
new MyDialog(MainActivity.this)
.setCancelable(false)
.setMessage("中間彈出,無標題,單按鈕")
.setPositiveButton("確 定", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了確定",
Toast.LENGTH_SHORT).show();
}
})
.builder()
.show();
break;
}
//中間彈出,有標題,藍色List
case R.id.button_3: {
new MyDialog(MainActivity.this)
.setTitle("標題,藍色ListView")
.setCancelable(false)
.setListView(mDataList, new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "點選了 " + position, Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取 消", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了取消",
Toast.LENGTH_SHORT).show();
}
})
.setNegativeButtonColor(R.color.blue)
.builder()
.show();
break;
}
//中間彈出,無標題,彩色List
case R.id.button_4: {
new MyDialog(MainActivity.this)
.setCancelable(false)
.setListView(mDataList, mColorArray, new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "點選了 " + position, Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("取 消", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了取消",
Toast.LENGTH_SHORT).show();
}
})
.setNegativeButtonColor(R.color.blue)
.builder()
.show();
break;
}
//中間彈出,有標題,內容替換為EditText
case R.id.button_5: {
new MyDialog(MainActivity.this)
.setTitle("標題,內容替換為EditText")
.setCancelable(false)
.setView(mEditLayout)
.setNegativeButton("取消", null)
.setPositiveButton("確定", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, mEditText.getText().toString(),
Toast.LENGTH_SHORT).show();
}
})
.builder()
.show();
break;
}
//底部彈出,有標題,藍色List
case R.id.button_6: {
new MyDialog(MainActivity.this,"BOTTOM")
.setBottomTitle("有標題,底部彈窗,藍色List")
.setCancelable(false)
.setListView(mDataList, new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "點選了 " + position, Toast.LENGTH_SHORT).show();
}
})
.setBottomNegativeButton("取 消", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了取消", Toast.LENGTH_SHORT).show();
}
})
.builder()
.show();
break;
}
//底部彈出,無標題,彩色List
case R.id.button_7: {
new MyDialog(MainActivity.this,"BOTTOM")
.setCancelable(false)
.setListView(mDataArray, mColorsList, new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "點選了 "+ position, Toast.LENGTH_SHORT).show();
}
})
.setBottomNegativeButton("取 消", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "點選了取消", Toast.LENGTH_SHORT).show();
}
})
.builder()
.show();
break;
}
}
}
}
貼出了全部程式碼,看著確實是有點多。。實際使用真的不多,按照自定義Dialog的步驟,這些程式碼都是必要的。
1、定義彈窗樣式style
2、定義彈窗佈局layout
3、設定動畫效果anim
4、具體實現核心類
使用是非常簡單的,按照anroid中AlertDialog的方式進行鏈式呼叫。使用時上去就new就對了。想使用什麼就設定什麼,如果你不需要標題Title,關於它的呼叫隻字不提即可。如果你不想使用按鈕,不寫按鈕的邏輯就完事了。各種方法的使用在註釋中說明的非常清楚,set就完了。如果你還有其他的需求,在Dialog核心類中進行新增就OK了。
六、注意事項
(1)、注意使用中間彈窗和底部彈窗的構造方法
使用彈窗時,若不傳入引數"BOTTOM",則是中間彈窗,若傳入,就是底部彈窗。
(2)、Cancelable預設為true,也就是說,你不進行設定,點選窗體以外的區域,就會讓彈窗消失。只有傳入false,他才會起作用。和AlertDialog的使用相同
七、總結
如果你嫌上面的程式碼太多,太囉嗦,直接copy去用。如果看懂了上面的程式碼(其實很簡單),在進行適當的優化,他就是你自己的了。其實,這也是我第一次使用自定義的Dialog,開始想自定義的時候翻網上的一些文章,看別人是怎麼實現的,看了好久都沒啥思路,感覺好麻煩啊。不過真正動手寫就沒有問題了。遇到什麼問題,慢慢也就解決了。實踐比空想要實際的多。
八、專案原始碼下載
原始碼下載地址,不需要積分: 點選下載原始碼
九、BUG修復
出現了一個BUG,該bug導致:
1、中間彈窗,當內容為文字時,內容長度過長,則內容無法滑動,並且不會顯示底部按鈕;當內容為List時,List長度過長時,則不會顯示底部按鈕。
2、底部彈窗,當List過長時,則無法顯示底部按鈕。