Android 自定義AlertDialog
阿新 • • 發佈:2018-11-12
這幾天看了一些關於Android UI的文件,看到這個控制元件的時候感覺,怎麼會有這麼醜,這麼難用的元件,不就是一個Alert嗎?好在這個元件給我們提供了一個可以將這個元件蓋頭換面的Api,便是setView,那就以重寫這個元件為核心對AlertDialog進行重寫吧,這裡我們實驗一種最常用的使用場景,先把實現效果貼圖吧
仿照IPhone做的效果,喬幫主的產品確實簡潔美觀
首先我們先來定義一下介面中的幾個引數
// 控制元件
private TextView tv_alertdialog_message_title, tv_alertdialog_message_message;
private Button btnPositive, btnNegative;
// 傳遞引數
private String title, message;
private String positiveText = "確定", negativeText = "取消";
說白了就是四個元件,接下來是繫結的事件了
// 定義確定、取消事件
public interface AlertDialogMessageListener {
void positiveClick();
void negativeClick();
}
// 定義一個介面物件,供呼叫者例項化
private AlertDialogMessageListener alertListener;
public AlertDialogMessageListener getAlertListener() {
return alertListener;
}
接下來我們繪製一下我們自定義的介面
public void setAlertView() {
// 佈局
View view = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.alertdialog_message, null);
// 標題
tv_alertdialog_message_title = view.findViewById (R.id.tv_alertdialog_message_title);
tv_alertdialog_message_title.setText(title);
// 資訊
tv_alertdialog_message_message = view.findViewById(R.id.tv_alertdialog_message_message);
tv_alertdialog_message_message.setText(message);
// Positive 按鈕
btnPositive = view.findViewById(R.id.bt_alertdialog_message_positive);
btnPositive.setText(positiveText);
btnPositive.setOnClickListener(this);
// Negative 按鈕
btnNegative = view.findViewById(R.id.bt_alertdialog_message_negative);
btnNegative.setText(negativeText);
btnNegative.setOnClickListener(this);
// 透明背景
Window window = getWindow();
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setView(view);
}
細心的同學發現,我在最後直接呼叫了setView()
核心程式碼已經完成接一下我們繼續優化,正如我們大家知道的那樣,除了setView(),我們還需要按照順序,依次執行 setCancelable()、setView()(必須在create之前執行)、create()、最後才能show(),那我們何不借助方法重寫將他們全部整合起來,這樣我們在呼叫的時候就簡潔很多了,如下
@Override
protected void onCreate(Bundle savedInstanceState) {
// 配置自定義View(必須在onCreate之前,否則載入失敗)
setAlertView();
super.onCreate(savedInstanceState);
}
@Override
public void show() {
// 在Show方法中直接呼叫
setCancelable(false);
create();
super.show();
// 設定 AlertDialog的 寬高和位置
Window dialogWindow = getWindow();
WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
layoutParams.width = (int) (new Metrics(getContext()).screenWidth() * 0.75);
// 當Window的Attributes改變時系統會呼叫此函式,可以直接呼叫以應用上面對視窗引數的更改,也可以用setAttributes
dialogWindow.setAttributes(layoutParams);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_alertdialog_message_positive:
if (alertListener != null) {
getAlertListener().positiveClick();
}
dismiss();
break;
case R.id.bt_alertdialog_message_negative:
if (alertListener != null) {
getAlertListener().negativeClick();
}
dismiss();
break;
default:
break;
}
}
這樣封裝之後我們是這樣用的
// alertDialogMessage = new AlertDialogMessage(this, "這是Component 元件", "名字為:AlertDialogMessage");
alertDialogMessage = new AlertDialogMessage(this, "這是Component 元件", "名字為:AlertDialogMessage", "走了哦", "留下吧");
alertDialogMessage.setAlertListener(this);
alertDialogMessage.show();
是不是很簡潔
對了,把遇到的問題給大家同步一下,遇到的話有個參考
1、設定圓角之後,四個角是白色填充色,解決方案如下:
// 透明背景
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
2、無法改變彈出框的寬高,解決方案如下:
// 設定 AlertDialog的 寬高和位置
Window dialogWindow = getWindow();
WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
layoutParams.width = (int) (new Metrics(getContext()).screenWidth() * 0.75);
// 當Window的Attributes改變時系統會呼叫此函式,可以直接呼叫以應用上面對視窗引數的更改,也可以用setAttributes
dialogWindow.setAttributes(layoutParams);
避免大家對有些地方產生誤解,我把這個元件的封裝程式碼全部貼出來吧
package com.mengft.mengft_ui.Compenent;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.mengft.mengft_ui.R;
import com.mengft.mengft_ui.Utils.Metrics;
/**
* Created by mengft on 2018/6/8.
*/
public class AlertDialogMessage extends AlertDialog implements View.OnClickListener {
// 控制元件
private TextView tv_alertdialog_message_title, tv_alertdialog_message_message;
private Button btnPositive, btnNegative;
// 傳遞引數
private String title, message;
private String positiveText = "確定", negativeText = "取消";
// 定義確定、取消事件
public interface AlertDialogMessageListener {
void positiveClick();
void negativeClick();
}
// 定義一個介面物件,供呼叫者例項化
private AlertDialogMessageListener alertListener;
public AlertDialogMessageListener getAlertListener() {
return alertListener;
}
public void setAlertListener(AlertDialogMessageListener alertListener) {
this.alertListener = alertListener;
}
// 傳遞Header引數
public AlertDialogMessage(Context context, String title, String message) {
super(context);
this.title = title;
this.message = message;
}
// 傳遞Header、Button引數
public AlertDialogMessage(Context context, String title, String message, String positiveText, String negativeText) {
super(context);
this.title = title;
this.message = message;
this.positiveText = positiveText;
this.negativeText = negativeText;
}
/**
* 配置自定義 View
*/
public void setAlertView() {
// 佈局
View view = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.alertdialog_message, null);
// 標題
tv_alertdialog_message_title = view.findViewById(R.id.tv_alertdialog_message_title);
tv_alertdialog_message_title.setText(title);
// 資訊
tv_alertdialog_message_message = view.findViewById(R.id.tv_alertdialog_message_message);
tv_alertdialog_message_message.setText(message);
// Positive 按鈕
btnPositive = view.findViewById(R.id.bt_alertdialog_message_positive);
btnPositive.setText(positiveText);
btnPositive.setOnClickListener(this);
// Negative 按鈕
btnNegative = view.findViewById(R.id.bt_alertdialog_message_negative);
btnNegative.setText(negativeText);
btnNegative.setOnClickListener(this);
// 透明背景
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setView(view);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// 配置自定義View(必須在onCreate之前,否則載入失敗)
setAlertView();
super.onCreate(savedInstanceState);
}
@Override
public void show() {
// 在Show方法中直接呼叫
setCancelable(false);
create();
super.show();
// 設定 AlertDialog的 寬高和位置
Window dialogWindow = getWindow();
WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
layoutParams.width = (int) (new Metrics(getContext()).screenWidth() * 0.75);
// 當Window的Attributes改變時系統會呼叫此函式,可以直接呼叫以應用上面對視窗引數的更改,也可以用setAttributes
dialogWindow.setAttributes(layoutParams);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_alertdialog_message_positive:
if (alertListener != null) {
getAlertListener().positiveClick();
}
dismiss();
break;
case R.id.bt_alertdialog_message_negative:
if (alertListener != null) {
getAlertListener().negativeClick();
}
dismiss();
break;
default:
break;
}
}
}