在開發(fā)的過程當(dāng)中,我們經(jīng)常會用到各種各樣的彈框樣式,然而Android自帶的彈框樣式在UI看來是一個特別丑的存在,所以總是給我們設(shè)計各種各樣不同樣式的彈框,這里就不一一闡述了,這里我們只記錄一種公用的彈框樣式,也就是仿iOS的樣式,先上布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/bkg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginStart="30dp"
android:background="@drawable/bg_white_10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/txt_dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:gravity="center"
android:textColor="#000"
android:textSize="17sp"
android:textStyle="bold"
tools:text="標題" />
<TextView
android:id="@+id/txt_dialog_tip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:textColor="#000"
android:textSize="13sp"
tools:text="中文內(nèi)容" />
<RelativeLayout
android:id="@+id/box_custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<EditText
android:id="@+id/txt_input"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:background="@drawable/bg_edit_text"
android:gravity="center_vertical"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:singleLine="true"
android:textColor="#000000"
android:textSize="14sp"
android:visibility="gone"
tools:text="輸入文本" />
<ImageView
android:id="@+id/split_horizontal"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="10dp"
android:background="#2c000000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:id="@+id/btn_selectNegative"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/button_dialog_left"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="取消"
android:textColor="@color/colorMain"
android:textSize="17sp" />
<View
android:id="@+id/split_vertical_1"
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#2c000000" />
<TextView
android:id="@+id/btn_center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/button_dialog_center"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="確定"
android:textColor="@color/colorMain"
android:textSize="17sp" />
<View
android:id="@+id/split_vertical_2"
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#2c000000" />
<TextView
android:id="@+id/btn_selectPositive"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/button_dialog_right"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="確定"
android:textColor="@color/colorMain"
android:textSize="17sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
然后在進行定義之前,我們需要對于彈框的進入和淡出進行一個樣式的設(shè)置
<style name="iOSAnimStyle">
<item name="android:windowEnterAnimation">@anim/enter_dialog_anim</item>
<item name="android:windowExitAnimation">@anim/exit_dialog_anim</item>
</style>
這里順便貼上樣式的效果
enter_dialog_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="300"
android:fromXScale="1.1"
android:fromYScale="1.1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
exit_dialog_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
接下來就是定義Dialog了,直接上干貨
public class NormalDialog extends Dialog implements View.OnClickListener {
private TextView txt_dialog_tip;
private EditText txt_input;
private final String title, tip, negativeName, positiveName, centerName;
private @ColorInt
final int negativeColor, positiveColor, titleColor, centerColor;
private final DialogOnClickListener negativeListener, positiveListener, centerListener;
private final int inputType;//輸入框 的輸入類型
private final boolean autoClose;//點擊確定取消后是否關(guān)閉,默認是
private int DIALOG_TYPE = 0;//dialog類型 0:單個確定按鈕dialog 1:確定取消dialog 2:單個輸入框dialog
public static final int DIALOG_CONFIRM = 0, DIALOG_SELECT = 1, DIALOG_ONE_INPUT = 2;
private final boolean touchOutsideCancel, cancelable;
private NormalDialog(Builder builder) {
super(builder.context);
this.title = builder.title;
this.tip = builder.tip;
this.negativeName = builder.negativeName;
this.positiveName = builder.positiveName;
this.centerName = builder.centerName;
this.negativeListener = builder.negativeListener;
this.positiveListener = builder.positiveListener;
this.centerListener = builder.centerListener;
this.negativeColor = builder.negativeColor;
this.positiveColor = builder.positiveColor;
this.centerColor = builder.centerColor;
this.titleColor = builder.titleColor;
this.inputType = builder.inputType;
this.autoClose = builder.autoClose;
this.DIALOG_TYPE = builder.DIALOG_TYPE;
this.touchOutsideCancel = builder.touchOutsideCancel;
this.cancelable = builder.cancelable;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉title
requestWindowFeature(Window.FEATURE_NO_TITLE);
//設(shè)置背景透明
getWindow().setBackgroundDrawableResource(android.R.color.transparent);
setContentView(R.layout.dialog_normal);
initView();
}
private void initView() {
//title
TextView txt_dialog_title = findViewById(R.id.txt_dialog_title);
if (title != null) {
txt_dialog_title.setText(title);
}
if (titleColor != 0) txt_dialog_title.setTextColor(titleColor);
//tip
txt_dialog_tip = findViewById(R.id.txt_dialog_tip);
if (tip != null) txt_dialog_tip.setText(tip);
//negativeTX
TextView btn_selectNegative = findViewById(R.id.btn_selectNegative);
if (negativeName != null) btn_selectNegative.setText(negativeName);
if (negativeColor != 0) btn_selectNegative.setTextColor(negativeColor);
btn_selectNegative.setOnClickListener(this);
//centerTX
TextView btn_selectCenter = findViewById(R.id.btn_center);
if (centerName != null) btn_selectCenter.setText(centerName);
if (centerColor != 0) btn_selectCenter.setTextColor(centerColor);
btn_selectCenter.setOnClickListener(this);
//positiveTX
TextView btn_selectPositive = findViewById(R.id.btn_selectPositive);
if (positiveName != null) btn_selectPositive.setText(positiveName);
if (positiveColor != 0) btn_selectPositive.setTextColor(positiveColor);
btn_selectPositive.setOnClickListener(this);
//設(shè)置輸入框類型
txt_input = findViewById(R.id.txt_input);
if (inputType != 0) txt_input.setInputType(inputType);
setCanceledOnTouchOutside(touchOutsideCancel);
setCancelable(cancelable);
getWindow().setWindowAnimations(R.style.iOSAnimStyle);
switch (DIALOG_TYPE) {
case DIALOG_CONFIRM://單選確定
findViewById(R.id.split_vertical_1).setVisibility(View.GONE);
findViewById(R.id.split_vertical_2).setVisibility(View.GONE);
btn_selectNegative.setVisibility(View.GONE);
btn_selectCenter.setVisibility(View.GONE);
btn_selectPositive.setBackgroundResource(R.drawable.button_dialog_one);
break;
case DIALOG_SELECT://雙選
findViewById(R.id.split_vertical_1).setVisibility(View.GONE);
btn_selectCenter.setVisibility(View.GONE);
btn_selectPositive.setBackgroundResource(R.drawable.button_dialog_right);
break;
case DIALOG_ONE_INPUT://帶輸入框 ,且左右兩個按鈕
txt_input.setVisibility(View.VISIBLE);
findViewById(R.id.split_vertical_1).setVisibility(View.GONE);
btn_selectCenter.setVisibility(View.GONE);
btn_selectPositive.setBackgroundResource(R.drawable.button_dialog_right);
break;
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_selectNegative) {
//取消
if (negativeListener != null) negativeListener.onClick(this, v);
} else if (v.getId() == R.id.btn_selectPositive) {
//確定
if (positiveListener != null) positiveListener.onClick(this, v);
} else if (v.getId() == R.id.btn_center) {
if (centerListener != null) centerListener.onClick(this, v);
}
if (autoClose) dismiss();
}
public void setTip(String tip) {
txt_dialog_tip.setText(tip);
}
/**
* 獲取輸入框的文本
*
* @return m
*/
public String getInputText() {
return txt_input.getText().toString().trim();
}
public static class Builder {
private Context context;
private String title, tip, negativeName, positiveName, centerName;
private @ColorInt
int negativeColor, positiveColor, titleColor, centerColor;
private DialogOnClickListener negativeListener, positiveListener, centerListener;
private int inputType;
private boolean autoClose = true;
private int DIALOG_TYPE = 0;
private boolean touchOutsideCancel = true, cancelable = true;
public Builder setCanceledOnTouchOutside(boolean canceled) {
touchOutsideCancel = canceled;
return this;
}
public Builder setCancelable(boolean cancelable) {
this.cancelable = cancelable;
return this;
}
/**
* 設(shè)置dialog的類型
*
* @param DIALOG_TYPE DIALOG_CONFIRM=0,DIALOG_SELECT=1,DIALOG_ONEINPUT=2
* @return m
*/
public Builder setDialogType(int DIALOG_TYPE) {
this.DIALOG_TYPE = DIALOG_TYPE;
return this;
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setTitleColor(@ColorInt int color) {
this.titleColor = color;
return this;
}
public Builder setTip(String tip) {
this.tip = tip;
return this;
}
public Builder setNegativeName(String negativeName) {
this.negativeName = negativeName;
return this;
}
public Builder setNegativeColor(@ColorInt int color) {
this.negativeColor = color;
return this;
}
public Builder setNegativeListener(DialogOnClickListener negativeListener) {
this.negativeListener = negativeListener;
return this;
}
public Builder setPositiveName(String positiveName) {
this.positiveName = positiveName;
return this;
}
public Builder setPositiveColor(@ColorInt int color) {
this.positiveColor = color;
return this;
}
public Builder setPositiveListener(DialogOnClickListener positiveListener) {
this.positiveListener = positiveListener;
return this;
}
public Builder setCenterName(String centerName) {
this.centerName = centerName;
return this;
}
public Builder setCenterColor(@ColorInt int color) {
this.centerColor = color;
return this;
}
public Builder setCenterListener(DialogOnClickListener listener) {
this.centerListener = listener;
return this;
}
/**
* 是否自動關(guān)閉(點擊確定和取消后)
*
* @param autoClose 默認是
* @return m
*/
public Builder setAutoClose(boolean autoClose) {
this.autoClose = autoClose;
return this;
}
/**
* 設(shè)置輸入框文本類型
*
* @param type InputType.TYPE_CLASS_TEXT InputType.TYPE_CLASS_NUMBER InputType.TYPE_NUMBER_FLAG_DECIMAL
* InputType.TYPE_TEXT_VARIATION_PASSWORD
* @return m
*/
public Builder setInputType(int type) {
this.inputType = type;
return this;
}
public NormalDialog build(Context context) {
this.context = context;
return new NormalDialog(this);
}
}
}
最后是在我們需要引用的地方進行去引用就大功告成了,也避免了我們在每次需要彈框的時候都要重新定義????乛?乛????
NormalDialog.Builder()
.setDialogType(NormalDialog.DIALOG_SELECT)
.setTitle("hello")
.setTip("確定取消dialog")
.setPositiveListener { _, _ ->
ToastUtils.showMessage(mContext, "確定后可以操作")
}
.build(mContext)
.show()

單個確定按鈕dialog

確定取消dialog

單個輸入框dialog