彈窗之三:自定義Dialog
阿新 • • 發佈:2019-01-23
第一步: 給Dialog設定一個風格主題
(基本都是用這個主題)無邊框全透明背景:
res/values/styles:
<!--自定義dialog背景全透明無邊框theme -->
<style name="MyDialog" parent="android:style/Theme.Dialog">
<!--背景顏色及和透明程度-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--是否去除標題 -->
<item name="android:windowNoTitle">true</item>
<!--是否去除邊框-->
<item name="android:windowFrame">@null</item>
<!--是否浮現在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--是否模糊-->
<item name="android:backgroundDimEnabled">false</item>
</style>
第二步:給自定義的Dialog設定自定義的 xml介面
比如:title+message+確定按鈕、取消按鈕
<?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 ="match_parent">
<LinearLayout
android:layout_width="260dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/dialog_bg"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="15dp"
android:gravity="center"
android:text="訊息提示"
android:textColor="#38ADFF"
android:textSize="16sp" />
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="提示訊息" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="15dp"
android:background="#E4E4E4" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<Button
android:id="@+id/no"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:singleLine="true"
android:text="No"
android:textColor="#7D7D7D"
android:textSize="16sp" />
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#E4E4E4" />
<Button
android:id="@+id/yes"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:singleLine="true"
android:text="Yes"
android:textColor="#38ADFF"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
dialog_bg.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff" />
<!-- 圓角 -->
<corners android:radius="6dp" />
</shape>
第三步:繼承Dialog實現自定義的Dialog
public class CustomDialog extends Dialog {
private Button yes;
private Button no;
private TextView titleTv;
private TextView messageTv;
private String titleStr;
private String messageStr;
private String yesStr, noStr;
/* -------------------------------- 介面監聽 ------------------------------------- */
private onNoOnclickListener noOnclickListener;
private onYesOnclickListener yesOnclickListener;
public interface onYesOnclickListener {
void onYesClick();
}
public interface onNoOnclickListener {
void onNoClick();
}
public void setNoOnclickListener(String str, onNoOnclickListener onNoOnclickListener) {
if (str != null) {
noStr = str;
}
this.noOnclickListener = onNoOnclickListener;
}
public void setYesOnclickListener(String str, onYesOnclickListener onYesOnclickListener) {
if (str != null) {
yesStr = str;
}
this.yesOnclickListener = onYesOnclickListener;
}
/* ---------------------------------- 構造方法 ------------------------------------- */
public CustomDialog(Context context) {
super(context, R.style.MyDialog);//風格主題
}
/* ---------------------------------- onCreate------------------------------------- */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_dialog_layout);//自定義佈局
//按空白處不能取消動畫
// setCanceledOnTouchOutside(false);
//初始化介面控制元件
initView();
//初始化介面資料
initData();
//初始化介面控制元件的事件
initEvent();
}
/**
* 初始化介面的確定和取消監聽器
*/
private void initEvent() {
//設定確定按鈕被點選後,向外界提供監聽
yes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (yesOnclickListener != null) {
yesOnclickListener.onYesClick();
}
}
});
//設定取消按鈕被點選後,向外界提供監聽
no.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (noOnclickListener != null) {
noOnclickListener.onNoClick();
}
}
});
}
/**
* 初始化介面控制元件的顯示資料
*/
private void initData() {
//如果使用者自定了title和message
if (titleStr != null) {
titleTv.setText(titleStr);
}
if (messageStr != null) {
messageTv.setText(messageStr);
}
//如果設定按鈕的文字
if (yesStr != null) {
yes.setText(yesStr);
}
if (noStr != null) {
no.setText(noStr);
}
}
/**
* 初始化介面控制元件
*/
private void initView() {
yes = (Button) findViewById(R.id.yes);
no = (Button) findViewById(R.id.no);
titleTv = (TextView) findViewById(R.id.title);
messageTv = (TextView) findViewById(R.id.message);
}
/* ---------------------------------- set方法 傳值------------------------------------- */
//為外界設定一些public 公開的方法,來向自定義的dialog傳遞值
public void setTitle(String title) {
titleStr = title;
}
public void setMessage(String message) {
messageStr = message;
}
}
第四步:activity中呼叫:
final CustomDialog customDialog = new CustomDialog(MainActivityI.this);
customDialog.setTitle("提示");
customDialog.setMessage("確定退出應用?");
customDialog.show();
customDialog.setYesOnclickListener("確定", new CustomDialog.onYesOnclickListener() {
@Override
public void onYesClick() {
Toast.makeText(MainActivityI.this, "點選了--確定--按鈕", Toast.LENGTH_LONG).show();
customDialog.dismiss();
}
});
customDialog.setNoOnclickListener("取消", new CustomDialog.onNoOnclickListener() {
@Override
public void onNoClick() {
Toast.makeText(MainActivityI.this, "點選了--取消--按鈕", Toast.LENGTH_LONG).show();
customDialog.dismiss();
}
});
效果如圖:
1、設定標題和內容可以使用構造方法
2、監聽確定和取消事件可以使用一個介面:
如下
1、dialog佈局:
注意最外層的寬度為match_parent,方便後面修改寬度
<?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="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/dialog_bg"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="15dp"
android:gravity="center"
android:text="訊息提示"
android:textColor="#38ADFF"
android:textSize="16sp" />
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="提示訊息" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="15dp"
android:background="#E4E4E4" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<Button
android:id="@+id/no"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:singleLine="true"
android:text="No"
android:textColor="#7D7D7D"
android:textSize="16sp" />
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#E4E4E4" />
<Button
android:id="@+id/yes"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@null"
android:gravity="center"
android:singleLine="true"
android:text="Yes"
android:textColor="#38ADFF"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
2、定義dialog:
public class MyDialog extends Dialog {
private Context context;
private String message;
private String title;
private String confirmButtonText;
private String cacelButtonText;
/* ----------------------------------介面監聽---------------------------------------- */
private ClickListenerInterface clickListenerInterface;
public interface ClickListenerInterface {
void doConfirm();
void doCancel();
}
public void setClickListener(ClickListenerInterface clickListenerInterface) {
this.clickListenerInterface = clickListenerInterface;
}
/* ----------------------------------構造方法:傳值------------------------------------- */
public MyDialog(Context context, String title, String message, String confirmButtonText, String cacelButtonText) {
super(context, R.style.MyDialog);
this.context = context;
this.title = title;
this.message = message;
this.confirmButtonText = confirmButtonText;
this.cacelButtonText = cacelButtonText;
}
/* ---------------------------------- onCreate ------------------------------------- */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
@SuppressWarnings("ConstantConditions")
@SuppressLint("InflateParams")
public void init() {
setContentView(R.layout.my_dialog);
TextView tvTitle = (TextView) findViewById(R.id.title);
TextView tvMessage = (TextView) findViewById(R.id.message);
TextView tvConfirm = (TextView) findViewById(R.id.yes);
TextView tvCancel = (TextView) findViewById(R.id.no);
tvTitle.setText(title);
tvMessage.setText(message);
tvConfirm.setText(confirmButtonText);
tvCancel.setText(cacelButtonText);
tvConfirm.setOnClickListener(new clickListener());
tvCancel.setOnClickListener(new clickListener());
setCanceledOnTouchOutside(false);//設定視窗外是否可關閉
setOnKeyListener(new DialogInterface.OnKeyListener() {//設定按back鍵不關閉
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
return keyCode == KeyEvent.KEYCODE_BACK;
}
});
Window dialogWindow = getWindow();
if (dialogWindow != null) {
dialogWindow.setGravity(Gravity.BOTTOM | Gravity.CENTER);//設定視窗位置
dialogWindow.setWindowAnimations(R.style.dialogWindowAnim); //設定視窗進出動畫
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
DisplayMetrics d = context.getResources().getDisplayMetrics(); // 獲取螢幕寬、高
if (lp != null) {
lp.width = (int) (d.widthPixels * 0.7); // 設定為螢幕寬度
}
dialogWindow.setAttributes(lp);
}
}
private class clickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.yes:
clickListenerInterface.doConfirm();
break;
case R.id.no:
clickListenerInterface.doCancel();
break;
}
}
}
}
3、activity呼叫:
final MyDialog myDialog = new MyDialog(MainActivityI.this, "提示", "確定要退出嗎?", "退出", "取消");
myDialog.show();
myDialog.setClickListener(new MyDialog.ClickListenerInterface() {
@Override
public void doConfirm() {
Toast.makeText(MainActivityI.this, "點選了--確定--按鈕", Toast.LENGTH_LONG).show();
myDialog.dismiss();
}
@Override
public void doCancel() {
Toast.makeText(MainActivityI.this, "點選了--取消--按鈕", Toast.LENGTH_LONG).show();
myDialog.dismiss();
}
});
4、動畫:
res/values/styles:
<!-- dialog的動畫-->
<style name="dialogWindowAnim" mce_bogus="1" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/animator_dialog_in</item>
<item name="android:windowExitAnimation">@anim/animator_dialog_out</item>
</style>
animator_dialog_in
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromXDelta="100%"
android:toXDelta="0" />
</set>
animator_dialog_out
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromXDelta="0"
android:toXDelta="-100%" />
</set>
效果如圖:
其他:
如果對話方塊需要新增動畫,推薦使用dialogFragment,自定義dialog新增動畫,在按home鍵後會自動執行動畫。監聽back鍵相同。