简单调用弹出框
new Alert.Builder(getContext())
.setOnBackPressedListener(Alert::dismiss)
.setWindowModeWidth(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
.setContentViewResId(R.layout.dialog_selector_calendar)
.createDialog()
.clicked(R.id.dialog_cancel, (view, alert) -> alert.dismiss())
.clicked(R.id.dialog_previous_month, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(-1))
.clicked(R.id.dialog_previous_year, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(-12))
.clicked(R.id.dialog_next_month, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(1))
.clicked(R.id.dialog_next_year, (view, alert) -> alert.findViewById(R.id.calendar_view).onCalendarTransformation(12))
.with(R.id.dialog_title, (TextView view, Alert alert) -> view.setText(alert.findViewById(R.id.calendar_view).getCalendarFormatMonth()))
.with(R.id.calendar_view, (ArnoldCalendarView view, Alert alert) -> {
view.setCalendarBackground(ContextCompat.getColor(getView().getContext(), R.color.popup_background)).setCalendarWeekFontColor(ContextCompat.getColor(getView().getContext(), R.color.calendar_background)).setOnCalendarCurrentDateChangeListener((year, month, day) -> alert.text(R.id.dialog_title, year + "年" + month + "月"));
})
.clicked(R.id.dialog_confirm, (view, alert) -> alert.dismiss())
.show();
弹出框代码
package dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Build;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.app.AlertDialog;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Adapter;
import android.widget.Checkable;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
/**
* @author Arnold
* @date 2019/4/2
* @des
*/
public interface Alert {
/**
* 显示窗口
*/
void show();
/**
* 取消
*/
void cancel();
/**
* 是否显示
*
* @return
*/
boolean isShowing();
/**
* 消失
*/
void dismiss();
/**
* 添加view
*
* @param idResId
* @param layoutResId
* @return
*/
V addView(int idResId, int layoutResId);
/**
* 添加view
*
* @param idResId
* @param subView
* @return
*/
V addView(int idResId, View subView);
/**
* 添加tag
*
* @param idResId
* @param object
* @return
*/
V tag(int idResId, Object object);
/**
* 设置图片资源
*
* @param idResId
* @param res
* @return
*/
V image(int idResId, int res);
/**
* 设置显示方式
*
* @param idResId
* @param visibility
* @return
*/
V visibility(int idResId, int visibility);
/**
* toggle按钮
*
* @param idResId
* @return
*/
V toggle(int idResId);
/**
* 添加透明度
*
* @param idResId
* @param alpha
* @return
*/
V alpha(int idResId, float alpha);
/**
* 设置文字
*
* @param idResId
* @param text
* @return
*/
V text(int idResId, String text);
/**
* 文字对齐方式
*
* @param idResId
* @param gravity
* @return
*/
V textGravity(int idResId, int gravity);
/**
* 设置文字颜色
*
* @param idResId
* @param color
* @return
*/
V textColor(int idResId, int color);
/**
* 添加文字类型
*
* @param idResId
* @param typeface
* @param style
* @return
*/
V typeface(int idResId, Typeface typeface, int style);
/**
* 添加文字类型
*
* @param idResId
* @param typeface
* @return
*/
V typeface(int idResId, Typeface typeface);
/**
* 设置文字大小
*
* @param idResId
* @param unit
* @param size
* @return
*/
V textSize(int idResId, int unit, float size);
/**
* 设置文字大小
* {@link android.util.TypedValue#COMPLEX_UNIT_SP}
*
* @param idResId
* @param size
* @return
*/
V textSize(int idResId, float size);
/**
* 添加下划线
*
* @param idResId
* @return
*/
V textUnderline(int idResId);
/**
* 点击
*
* @param idResId
* @param checked
* @return
*/
V checked(int idResId, boolean checked);
/**
* 选中
*
* @param idResId
* @param selected
* @return
*/
V selected(int idResId, boolean selected);
/**
* 添加按钮事件
*
* @param idResId
* @param listener
* @return
*/
V clicked(int idResId, OnActionClickListener listener);
/**
* 添加按钮改变事件
*
* @param idResId
* @param listener
* @return
*/
V checkedChange(int idResId, CompoundButton.OnCheckedChangeListener listener);
/**
* 添加适配器
*
* @param idResId
* @param adapter
* @return
*/
V adapter(int idResId, android.widget.ListAdapter adapter);
/**
* 添加
*
* @param idResId
* @param action
* @return
*/
V with(int idResId, Action extends View> action);
/**
* item
*
* @param action
* @return
*/
V with(Action extends View> action);
/**
* 查找视图
*
* @param idResId
* @param
* @return
*/
V findViewById(int idResId);
interface OnBackPressedListener {
/**
* 点击返回键
*
* @param alert
*/
void onBackPressed(Alert alert);
}
interface OnDismissListener {
/**
* 消失
*
* @param alert
*/
void onDismiss(Alert alert);
}
interface OnKeyListener {
/**
* 物理键按下监听
*
* @param alert
* @param keyCode
* @param event
* @return
*/
boolean onKey(Alert alert, int keyCode, KeyEvent event);
}
interface OnActionClickListener {
/**
* 确定
*
* @param view
* @param alert
*/
void onApplyClick(View view, Alert alert);
}
interface Action {
/**
* 自定义View
*
* @param v
* @param alert
*/
void apply(V v, Alert alert);
}
/**
* @author Arnold
* @date 2019/4/2
* @des
*/
class Dialog implements Alert, DialogInterface.OnKeyListener, DialogInterface.OnDismissListener {
private AlertDialog dialog;
private Builder builder;
private SparseArrayCompat viewSparseArrayCompat;
/**
* @param
* @return
*/
private V findItemView() {
return (V) builder.mContentView;
}
/**
* 查找视图
*
* @param idResId
* @param
* @return
*/
@Override
public V findViewById(int idResId) {
View view = this.viewSparseArrayCompat.get(idResId);
if (view == null) {
view = this.builder.mContentView.findViewById(idResId);
this.viewSparseArrayCompat.put(idResId, view);
}
return (V) view;
}
/**
* 获取 实现Checkable的View
*
* @param idResId
* @param
* @return
*/
private V findCheckableViewById(int idResId) {
return this.findViewById(idResId);
}
protected Dialog(Builder builder) {
this.viewSparseArrayCompat = new SparseArrayCompat<>();
this.builder = builder;
this.dialog = new AlertDialog
.Builder(builder.context)
.setView(builder.mContentView)
.setCancelable(builder.cancelable)
.create();
this.dialog.setCanceledOnTouchOutside(builder.outsideTouchable);
this.dialog.setOnKeyListener(this);
this.dialog.setOnDismissListener(this);
}
@Override
public void show() {
dialog.show();
//获得dialog的window窗口
android.view.Window window = this.dialog.getWindow();
//设置dialog在屏幕底部
window.setGravity(builder.gravity);
//设置dialog弹出时的动画效果,从屏幕底部向上弹出
//去掉dialog默认的内填充
window.getDecorView().setPadding(0, 0, 0, 0);
//获得window窗口的属性
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = builder.windowModeWidth;
//设置窗口高度为包裹内容
layoutParams.height = builder.windowModeHeight;
//将设置好的属性set回去
window.setAttributes(layoutParams);
}
@Override
public void cancel() {
if (null != dialog) {
dialog.cancel();
}
}
@Override
public boolean isShowing() {
if (null != dialog) {
return dialog.isShowing();
}
return false;
}
@Override
public void dismiss() {
if (null != dialog) {
dialog.dismiss();
}
}
@Override
public Alert addView(int idResId, int layoutResId) {
this.findViewById(idResId).addView(((LayoutInflater) builder.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(layoutResId, null));
return this;
}
@Override
public Alert addView(int idResId, View subView) {
this.findViewById(idResId).addView(subView);
return this;
}
@Override
public Alert tag(int idResId, Object object) {
this.findViewById(idResId).setTag(object);
return this;
}
@Override
public Alert image(int idResId, int res) {
this.findViewById(idResId).setImageResource(res);
return this;
}
@Override
public Alert visibility(int idResId, int visibility) {
this.findViewById(idResId).setVisibility(visibility);
return this;
}
@Override
public Alert toggle(int idResId) {
this.findCheckableViewById(idResId).toggle();
return this;
}
@Override
public Alert alpha(int idResId, float alpha) {
this.findViewById(idResId).setAlpha(alpha);
return this;
}
@Override
public Alert text(int idResId, String text) {
this.findViewById(idResId).setText(text);
return this;
}
@Override
public Alert textGravity(int idResId, int gravity) {
this.findViewById(idResId).setGravity(gravity);
return this;
}
@Override
public Alert textColor(int idResId, int color) {
this.findViewById(idResId).setTextColor(color);
return this;
}
@Override
public Alert typeface(int idResId, Typeface typeface, int style) {
this.findViewById(idResId).setTypeface(typeface, style);
return this;
}
@Override
public Alert typeface(int idResId, Typeface typeface) {
this.findViewById(idResId).setTypeface(typeface);
return this;
}
@Override
public Alert textSize(int idResId, int unit, float size) {
this.findViewById(idResId).setTextSize(unit, size);
return this;
}
@Override
public Alert textSize(int idResId, float size) {
this.findViewById(idResId).setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
return this;
}
@Override
public Alert textUnderline(int idResId) {
this.findViewById(idResId).getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
return this;
}
@Override
public Alert checked(int idResId, boolean checked) {
this.findCheckableViewById(idResId).setChecked(checked);
return this;
}
@Override
public Alert selected(int idResId, boolean selected) {
this.findViewById(idResId).setSelected(selected);
return this;
}
@Override
public Alert clicked(int idResId, Alert.OnActionClickListener listener) {
this.findViewById(idResId).setOnClickListener(v -> listener.onApplyClick(v, this));
return this;
}
@Override
public Alert checkedChange(int idResId, CompoundButton.OnCheckedChangeListener listener) {
this.findViewById(idResId).setOnCheckedChangeListener(listener);
return this;
}
@Override
public Alert adapter(int idResId, ListAdapter adapter) {
this.findViewById(idResId).setAdapter(adapter);
return this;
}
@Override
public V with(int idResId, Alert.Action extends View> action) {
action.apply(this.findViewById(idResId), this);
return (V) this;
}
@Override
public V with(Alert.Action extends View> action) {
action.apply(findItemView(), this);
return (V) this;
}
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && null != builder.onBackPressedListener) {
builder.onBackPressedListener.onBackPressed(this);
}
if (null != builder.onKeyListener) {
return builder.onKeyListener.onKey(this, keyCode, event);
}
return false;
}
@Override
public void onDismiss(DialogInterface dialog) {
if (null != builder.onDismissListener) {
builder.onDismissListener.onDismiss(this);
}
}
}
class Builder {
private static final float WINDOW_MODE_RATIO = 0.8F;
private int gravity = Gravity.BOTTOM;
private int layoutResId = -1;
private Context context;
private View mContentView;
private boolean cancelable = true;
private boolean outsideTouchable = true;
private Alert.OnBackPressedListener onBackPressedListener;
private Alert.OnDismissListener onDismissListener;
private Alert.OnKeyListener onKeyListener;
public Builder setOnBackPressedListener(Alert.OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
return this;
}
public Builder setOnKeyListener(Alert.OnKeyListener onKeyListener) {
this.onKeyListener = onKeyListener;
return this;
}
public Builder setOnDismissListener(Alert.OnDismissListener onDismissListener) {
this.onDismissListener = onDismissListener;
return this;
}
public Builder setWindowModeWidth(int windowModeWidth, int windowModeHeight) {
this.windowModeWidth = windowModeWidth;
this.windowModeHeight = windowModeHeight;
return this;
}
private int windowModeWidth = ViewGroup.LayoutParams.WRAP_CONTENT, windowModeHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
public Builder setGravity(int gravity) {
this.gravity = gravity;
return this;
}
public Builder setContentView(View view) {
this.mContentView = view;
return this;
}
public Builder setContentViewResId(int layoutResId) {
this.layoutResId = layoutResId;
return this;
}
public Builder(Context context) {
this.context = context;
}
public Builder setOutsideTouchable(boolean touchable) {
outsideTouchable = touchable;
return this;
}
/**
* 设置对话框是否可取消。默认值为true。
*
* @param cancelable
*/
public Builder setCancelable(boolean cancelable) {
this.cancelable = cancelable;
return this;
}
/**
* 创建Dialog
*
* @return
*/
public Alert createDialog() {
if (null == mContentView) {
if (layoutResId != -1) {
this.mContentView = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(layoutResId, null);
} else {
this.mContentView = new FrameLayout(context);
this.mContentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
}
if (windowModeWidth != -1) {
int displayWidth;
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
displayWidth = display.getMode().getPhysicalWidth();
} else {
displayWidth = display.getWidth();
}
this.windowModeWidth = (int) (displayWidth * WINDOW_MODE_RATIO);
}
return new Dialog(this);
}
}
}