背景
鉴于Android提供的默认弹出框很一般,IOS的弹出框样式还不错,同时使用弹出框dialog的需求还是蛮高的,于是就想仿照ios弹出框封装一个通用的dialog,解决操作询问,提示信息,列表选择等需求;同时在搜索数据的时候,需要选择条件,也是使用弹出框解决,类似于美团的顶部筛选框,今天就来封装下
提示与询问弹出框
为了解决确认、取消这种询问性的需求,还有提示性的需求,我们使用Dialog来仿一个ios式的弹出框,样式简洁大方,效果如图:
实现
主要还是自定义一个类继承Dialog,实现比较简单,如下
package com.mango.dialog;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.view.Gravity;
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.mango.dialog.listener.OnOptionListener;
import com.mango.dialog.utils.DisplayUtil;
/**
* @ClassName mango
* @Description TODO(操作询问框 提示框)
* @author cxy
* @Date 2019/6/27 15:19
*/
public class OptionAskDialog extends Dialog implements View.OnClickListener {
private String TAG = "OptionAskDialog";
private Context mContext;
private TextView tv_title;
private TextView tv_content;
private Button btn_sure;
private Button btn_cancle;
private LinearLayout ll_title;
private View line;
private OnOptionListener livingSure;
private String typeResult;
private OptionAskDialog(Context context) {
super(context);
mContext = context;
View view = View.inflate(context, R.layout.dialog_ask,null);
setContentView(view);
findViewId(view);
initWindow();
}
private OptionAskDialog(Context context, int themeResId) {
super(context, themeResId);
mContext = context;
View view = View.inflate(context, R.layout.dialog_ask,null);
setContentView(view);
findViewId(view);
initWindow();
initClick();
}
private void initClick() {
btn_sure.setOnClickListener(this);
btn_cancle.setOnClickListener(this);
}
private void findViewId(View view) {
tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_content = (TextView) view.findViewById(R.id.tv_content);
btn_sure = (Button) view.findViewById(R.id.btn_sure);
btn_cancle = (Button) view.findViewById(R.id.btn_cancle);
ll_title = (LinearLayout) view.findViewById(R.id.ll_title);
line = view.findViewById(R.id.line);
}
private void initView(String title_dialog,String content_dialog,String btn_left,String btn_right) {
if (!TextUtils.isEmpty(title_dialog)) {
tv_title.setText(title_dialog);
}
if (!TextUtils.isEmpty(content_dialog)) {
tv_content.setText(content_dialog);
}
if (!TextUtils.isEmpty(btn_left)) {
btn_sure.setText(btn_left);
}
if (!TextUtils.isEmpty(btn_right)) {
btn_cancle.setText(btn_right);
}
}
/**
* 设置dialog的背景、宽度、位置
*/
private void initWindow() {
Window dialogWindow = getWindow();
dialogWindow.setBackgroundDrawable(new ColorDrawable(0));
dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.width = (int) (DisplayUtil.getScreenWidth(mContext) * 0.8);
lp.gravity = Gravity.CENTER;
dialogWindow.setAttributes(lp);
}
/**
* 是否隐藏标题
* @param isShow
*/
private void setTitleVisible(boolean isShow) {
if (isShow) {
ll_title.setVisibility(View.VISIBLE);
line.setVisibility(View.VISIBLE);
btn_cancle.setVisibility(View.VISIBLE);
btn_sure.setText(R.string.ok);
btn_sure.setBackgroundResource(R.drawable.selector_askdialog_ok);
} else {
ll_title.setVisibility(View.GONE);
line.setVisibility(View.GONE);
btn_cancle.setVisibility(View.GONE);
btn_sure.setText(R.string.i_know);
btn_sure.setBackgroundResource(R.drawable.selector_askdialog_fullok);
}
}
private void initListener(OnOptionListener livingSure, String typeResult){
this.livingSure = livingSure;
this.typeResult = typeResult;
}
/**
* 点击确定按钮
*/
public void clickSure(){
if (livingSure != null) {
livingSure.onOptionSure(typeResult);
}
dismiss();
}
/**
* 点击取消按钮
*/
public void clickCancle(){
if (livingSure != null) {
livingSure.onOptionCancle(typeResult);
}
dismiss();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_cancle) {
clickCancle();
} else {
clickSure();
}
}
public static class Bulid{
private Context mContext;
private String title_dialog;
private String content_dialog;
private String btn_left;
private String btn_right;
private String typeResult;
private OnOptionListener optionListener;
private int themeResId;
private boolean isShowTitle = true;
public Bulid(Context context, int themeResId) {
mContext = context;
this.themeResId = themeResId;
}
public Bulid setShowTitle(boolean showTitle) {
isShowTitle = showTitle;
return this;
}
public Bulid setTitle_dialog(int title_dialog) {
this.title_dialog = mContext.getResources().getString(title_dialog);
return this;
}
public Bulid setTitle_dialog(String title_dialog) {
this.title_dialog = title_dialog;
return this;
}
public Bulid setContent_dialog(int content_dialog) {
this.content_dialog = mContext.getResources().getString(content_dialog);
return this;
}
public Bulid setContent_dialog(String content_dialog) {
this.content_dialog = content_dialog;
return this;
}
public Bulid setBtn_left(int btn_left) {
this.btn_left = mContext.getResources().getString(btn_left);
return this;
}
public Bulid setBtn_right(int btn_right) {
this.btn_right = mContext.getResources().getString(btn_right);
return this;
}
public Bulid setOptionListener(OnOptionListener optionListener, String typeResult) {
this.optionListener = optionListener;
this.typeResult = typeResult;
return this;
}
public OptionAskDialog create(){
OptionAskDialog ackDialog;
if (themeResId == 0) {
ackDialog = new OptionAskDialog(mContext);
} else {
ackDialog = new OptionAskDialog(mContext,themeResId);
}
ackDialog.initView(title_dialog,content_dialog,btn_left,btn_right);
ackDialog.setTitleVisible(isShowTitle);
ackDialog.initListener(optionListener,typeResult);
return ackDialog;
}
}
}
使用
public void showTitle(View v) {
new OptionAskDialog
.Bulid(this,R.style.Dialog)
.setOptionListener(this,"1")
.setTitle_dialog(R.string.dialog_title)
.setContent_dialog(R.string.dialog_content)
.create()
.show();
}
public void showNoTitle(View v){
new OptionAskDialog
.Bulid(this,R.style.Dialog)
.setShowTitle(false)
.setOptionListener(this,"2")
.setTitle_dialog(R.string.dialog_title)
.setContent_dialog(R.string.dialog_content_sure)
.create()
.show();
}
列表选择框
有时候你需要向用户提供一些选项,让用户从列表中选择,如果还是像上面这种就比较丑了;可以设计成从底部弹出,如图:
实现
第一步:定义Dialog
public class OptionSheetDialog implements AdapterView.OnItemClickListener {
private WeakReference<Context> mContext;
private Dialog dialog;
private RelativeLayout rl_content;
private TextView txt_title;
private TextView txt_cancel;
private ListView mListview;
private BaseAdapter adapter;
private float scale;
private OnItemClickListener onItemClickListener;
public OptionSheetDialog(Context context) {
this.mContext = new WeakReference<>(context);
scale = DisplayUtil.getDensity(mContext.get());
}
public OptionSheetDialog builder() {
// 获取Dialog布局
View view = LayoutInflater.from(mContext.get()).inflate(R.layout.dialog_sheet, null);
// 获取自定义Dialog布局中的控件
rl_content = (RelativeLayout) view.findViewById(R.id.rl_content);
mListview = (ListView) view.findViewById(R.id.lv);
mListview.setOnItemClickListener(this);
txt_title = (TextView) view.findViewById(R.id.txt_title);
txt_cancel = (TextView) view.findViewById(R.id.txt_cancel);
txt_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
// 定义Dialog布局和参数
dialog = new Dialog(mContext.get(), R.style.ActionSheetDialogStyle);
dialog.setContentView(view);
//设置显示坐标、位置、宽度
Window dialogWindow = dialog.getWindow();
dialogWindow.setGravity(Gravity.BOTTOM);
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.x = 0;
lp.y = 0;
lp.width = DisplayUtil.getScreenWidth(mContext.get()) - (int)(16*scale + 0.5f);
dialogWindow.setAttributes(lp);
return this;
}
}
第二步:既然有LitView,那肯定需要adapter
public OptionSheetDialog setAdapter(BaseAdapter adapter) {
this.adapter = adapter;
return this;
}
第三步:现在需要考虑这个弹出框的高度问题了,既然是ListView,那它的item数量可能只有一个,两个…100个,所以肯定不能有多少个item,dialog就有多高,需要进行动态设置
/**
* 根据item数量动态设置listview的高度
* item数量在5个以下,高度由item个数决定
* item数量在5个及以上,高度固定是5个item高度总和
*/
private void setSheetItems() {
int height = (int) (LISTVIEW_ITEM_HEIGHT * scale + 0.5f);
int totalHeight;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mListview.getLayoutParams();
if (adapter.getCount() >= MAX_ITEM_HEIGHT) {
params.height = height * MAX_ITEM_HEIGHT;
totalHeight = height * MAX_ITEM_HEIGHT;
mListview.setLayoutParams(params);
} else {
params.height = height * adapter.getCount();
totalHeight = height * adapter.getCount();
mListview.setLayoutParams(params);
}
ViewGroup.LayoutParams vl = rl_content.getLayoutParams();
vl.height = (int) (DIALOG_TITLE_HEIGHT * scale + 0.5f) + totalHeight + (int) (DIALOG_CANCLE_HEIGHT * scale + 0.5f);
rl_content.setLayoutParams(vl);
mListview.setAdapter(adapter);
}
第四步:就是显示弹出框了,不过在show之前,调用下setSheetItems方法
public void show() {
setSheetItems();
dialog.show();
}
使用
private List<SheetItem> itemList = new ArrayList<>();
private List<SheetItem> moreItemList = new ArrayList<>();
private SheetAdapter sheetAdapter;
itemList.add(new SheetItem("清空消息列表",R.color.sheet_red));
moreItemList.add(new SheetItem("发送给好友",R.color.sheet_blue));
moreItemList.add(new SheetItem("转载到空间相册",R.color.sheet_blue));
moreItemList.add(new SheetItem("上传到群相册",R.color.sheet_blue));
moreItemList.add(new SheetItem("保存到手机",R.color.sheet_blue));
moreItemList.add(new SheetItem("发送到朋友圈",R.color.sheet_blue));
moreItemList.add(new SheetItem("查看聊天图片",R.color.sheet_blue));
sheetAdapter = new SheetAdapter(this);
public void showSheet(View v){
sheetAdapter.setItemList(itemList);
new OptionSheetDialog(MainActivity.this)
.builder()
.setTitle("清空消息列表后,聊天记录依然保留,确定要清空消息列表?")
.setCancelable(true)
.setCanceledOnTouchOutside(true)
.setAdapter(sheetAdapter)
.setOnItemClickListener(this)
.show();
}
public void showMoreSheet(View v){
sheetAdapter.setItemList(moreItemList);
new OptionSheetDialog(MainActivity.this)
.builder()
.setTitle("请选择操作")
.setCancelable(true)
.setCanceledOnTouchOutside(true)
.setAdapter(sheetAdapter)
.setOnItemClickListener(this)
.show();
}
顶部条件筛选框
这种弹出框比较适合选择条件搜索的需求,而且是分类别的条件,比如你在美团上搜外卖,按条件搜商家;在淘宝京东上按条件搜商品等;如图:
具体实现前分析下实现思路:
首先可以确定使用PopupWindow来作为弹出框的载体,易于显示位置的确定
弹出框内容分为两部分:第一部分是条件展示,可以使用ListView来显示条件列表;第二部分是按钮操作,处于弹出框底部,用两个Button或者Textview就行了
其中第二部分很简单,主要是第一部分,条件是分类别的,然后类别下又分很多子选项,所以把类别和子选项一起作为Item;其中子选项可以是一个自定义ViewGroup,显示众多子选项
其实第一部分也可以是一个ScrollView,然后开发者可以往里动态添加自己编写的各式各样的Item,这样扩展性更强,更灵活;我这里是从通用性和简易型角度考虑选择了上面使用ListView的方案
实现
先封装 搜索条件对象,这个对象主要包括类型及包括的条件
/**
* @Description TODO(搜索条件对象)
* @author cxy
* @Date 2019/6/28 11:51
*/
public class FilterTypeBean {
/**
* 筛选条件所属的类型
*/
private String typeName;
/**
* 包含的条件
*/
private List<Condition> children;
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public List<Condition> getChildren() {
return children;
}
public void setChildren(List<Condition> children) {
this.children = children;
}
public static class Condition {
//条件名称
private String value;
//是否选中
private boolean isSelected = false;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
}
接下来需要重新定义下ListView,因为它的高度决定了弹出框的高度,我给它指定高度
/**
* @Description TODO()
* @author cxy
* @Date 2019/6/28 10:52
*/
public class FixedHeightListView extends ListView {
private Context mContext;
public FixedHeightListView(Context context) {
this(context, null);
}
public FixedHeightListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FixedHeightListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mContext = context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
/**
* 设置ListView高度不能超过屏幕高度一半
* 因为下面有按钮,所以使用屏幕一半高度减去100
*/
heightMeasureSpec = MeasureSpec.makeMeasureSpec(DisplayUtil.getScreenHeight(mContext) / 2 - 100, MeasureSpec.AT_MOST);
} catch (Exception e) {
e.printStackTrace();
}
//重新计算控件高、宽
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
自定义ViewGroup
到这一步就需要自定义ViewGroup了,摆放搜索条件;自定义ViewGroup主要有两件事:第一就是重写onMeasure方法测量子控件的宽高和自己的宽高,第二就是重写onLayout方法摆放子控件的位置
先重写onMeasure方法,这里需要考虑viewGroup的宽度,同时高度需要考虑使用多少行来展示子view
/**
* 测量子view大小 和自己大小
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//从约束规范中获取尺寸
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
//获取测量规格
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//viewgroup的宽度
int width = 0;
//viewgroup的高度
int height = 0;
//一行子view的宽度之和
int lineWidth = 0;
//一行子view的高
int lineHeight = 0;
//获取子view数量
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
//如果子View设置了GONE属性,就跳过
if (child.getVisibility() == View.GONE) {
//计算viewgroup宽高
if (i == count - 1) {
width = Math.max(lineWidth, width);
height += lineHeight;
}
continue;
}
//计算这个子view的大小
measureChild(child, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
//设置子view的margin
lp.leftMargin = 10;
lp.rightMargin = 10;
lp.topMargin = 10;
lp.bottomMargin = 10;
//计算子view的宽高
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
/**
* 1.如果算出来的子view宽度和 > ViewGroup能使用的宽度值,那就说明需要重启一行显示了,就需要重新计算ViewGroup的宽高及每行的宽高
* 那就取width和lineWidth最大值并赋值给width,即一行的宽度或者说ViewGroup的宽度
* 新的一行的宽度lineWidth就重置为子view宽度childWidth,下一行第一个子view
* ViewGroup的高度height等于与每行高度lineHeight之和
* 同时新的一行的高度lineHeight重置为子view的高度
*
* 2.如果算出来的子view宽度和 <= ViewGroup能使用的宽度值,说明这些子view可以摆在同一行
* 那么一行宽度lineWidth等于子view宽度之和
* 一行lineHeight取子view高度和上一行高度lineHeight最大值
*/
if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight()) {
width = Math.max(width, lineWidth);
lineWidth = childWidth;
height += lineHeight;
lineHeight = childHeight;
} else {
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight);
}
/**
* 当最后一个子view计算完了
* viewGroup的宽度取lineWidth和width最大值
* viewGroup的高度取前面N行高度+最后一行高度
*/
if (i == count - 1) {
width = Math.max(lineWidth, width);
height += lineHeight;
}
}
/**
* 保存测量后的宽高
* 如果指定了ViewGroup的宽高,那就用指定的宽高
* 否则使用测量出来的宽高值
*/
setMeasuredDimension(
modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width + getPaddingLeft() + getPaddingRight(),
modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height + getPaddingTop() + getPaddingBottom()
);
}
然后重写onLayout方法,摆放每一个子view,具体要算出每个子view的上下左右四个值,换行时要重新计算left值和top值
/**
* 摆放子view的位置
* @param changed
* @param l
* @param t
* @param r
* @param b
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllViews.clear();
mLineHeight.clear();
mLineWidth.clear();
lineViews.clear();
//viewgroup宽度
int width = getWidth();
//一行宽度
int lineWidth = 0;
//一行高度
int lineHeight = 0;
//子view数量
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
/**
* 如果已经计算的一行宽度+当前子view的宽度+leftMargin+rightMargin 大于 一行实际能显示的宽度
* 这就需要折行显示了
* 那就保存已经算出来的一行高度、宽度、这一行所包含的view
* 然后重置下一行宽度为0,高度为当前子view的高度加topMargin,bottomMargin,并实例化保存新一行子view的list
*/
if (lineWidth + childWidth + lp.leftMargin + lp.rightMargin > width - getPaddingLeft() - getPaddingRight()) {
mLineHeight.add(lineHeight);
mLineWidth.add(lineWidth);
mAllViews.add(lineViews);
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
lineViews = new ArrayList<>();
}
//计算一行的宽度=前面计算的一行宽度+当前子view的宽度及leftMargin和rightMargin
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
//计算一行的高度取lineHeight和子view的实际高度最大值
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
//保存子view
lineViews.add(child);
}
//保存每行的高度、宽度、子view
mLineHeight.add(lineHeight);
mLineWidth.add(lineWidth);
mAllViews.add(lineViews);
int left = getPaddingLeft();
int top = getPaddingTop();
//viewgroup的行数
int lineNum = mAllViews.size();
for (int i = 0; i < lineNum; i++) {
//一行的子view
lineViews = mAllViews.get(i);
//这一行需要的高度
lineHeight = mLineHeight.get(i);
//这一行需要的宽度
int currentLineWidth = mLineWidth.get(i);
//每次换行重新计算left值,getPaddingLeft获取viewgroup的PaddingLeft
switch (this.mGravity) {
case LEFT:
left = getPaddingLeft();
break;
case CENTER:
left = getPaddingLeft();
break;
case RIGHT:
left = width - currentLineWidth + getPaddingLeft();
break;
}
//遍历每行子view
for (int j = 0; j < lineViews.size(); j++) {
View child = lineViews.get(j);
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
//计算子view 的left值=当前left+子view自身的leftMargin
int lc = left + lp.leftMargin;
//计算子view 的top值=当前top+子view 的topMargin
int tc = top + lp.topMargin;
int rc = lc + child.getMeasuredWidth();
int bc = tc + child.getMeasuredHeight();
//摆放子view
child.layout(lc, tc, rc, bc);
//下一个子view 的left=当前left+当前子view的宽度+当前子view的leftMargin与rightMargin
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
//计算下一行的top=当前top+一行高度
top += lineHeight;
}
}
最后重写下generateLayoutParams方法,返回布局参数类LayoutParams
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@Override
protected LayoutParams generateLayoutParams(LayoutParams p) {
return new MarginLayoutParams(p);
}
最后就是实现PopupWindow
public class MangoPopWindow extends PopupWindow {
private final Activity context;
private final List<FilterTypeBean> dictList;
private FixedHeightListView mListView;
private TextView tvReset, tvConfirm;
private View nullView;
private PopAdapter adapter;
private OnConfirmClickListener onConfirmClickListener;
public MangoPopWindow(Activity context, List<FilterTypeBean> dictList ) {
this.context = context;
this.dictList=dictList;
initPop();
}
private void initPop() {
View popView = View.inflate(context, R.layout.listview_popwindow, null);
//设置view
this.setContentView(popView);
//设置宽高(也可设置为LinearLayout.LayoutParams.MATCH_PARENT或者LinearLayout.LayoutParams.MATCH_PARENT)
this.setWidth(-1);
this.setHeight(-2);
//设置PopupWindow的焦点
this.setFocusable(true);
//设置窗口以外的地方点击可关闭
this.setOutsideTouchable(true);
//设置背景透明
this.setBackgroundDrawable(new ColorDrawable(0x33000000));
mListView = (FixedHeightListView) popView.findViewById(R.id.listview);
tvReset = (TextView) popView.findViewById(R.id.tv_reset);
tvConfirm = (TextView) popView.findViewById(R.id.tv_confirm);
nullView = popView.findViewById(R.id.view_null);
adapter = new PopAdapter(context, dictList);
mListView.setAdapter(adapter);
tvReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (int x = 0; x < dictList.size(); x++) {
List<FilterTypeBean.Condition> childrenBeen = dictList.get(x).getChildren();
for (int y=0;y<childrenBeen.size();y++){
if (childrenBeen.get(y).isSelected()) {
childrenBeen.get(y).setSelected(false);
}
}
}
adapter.notifyDataSetChanged();
}
});
tvConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onConfirmClickListener.onConfirmClick();
dismiss();
}
});
nullView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
}
public void setOnConfirmClickListener(OnConfirmClickListener onConfirmClickListener){
this.onConfirmClickListener=onConfirmClickListener;
}
public interface OnConfirmClickListener{
void onConfirmClick();
}
}
使用
private void initView() {
ivBack = (ImageView) findViewById(R.id.iv_back);
tvFilter = (TextView) findViewById(R.id.tv_flow);
tvFilter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mPopWindow = new MangoPopWindow(MainActivity.this, dictList);
mPopWindow.showAsDropDown(ivBack);
mPopWindow.setOnConfirmClickListener(new MangoPopWindow.OnConfirmClickListener() {
@Override
public void onConfirmClick() {
StringBuilder sb = new StringBuilder();
for (FilterTypeBean fb : dictList) {
List<FilterTypeBean.Condition> cdList = fb.getChildren();
for (int x = 0; x < cdList.size(); x++) {
FilterTypeBean.Condition children = cdList.get(x);
if (children.isSelected()) {
sb.append(fb.getTypeName() + ":" + children.getValue() + ";");
}
}
}
if (!TextUtils.isEmpty(sb.toString())) {
Toast.makeText(MainActivity.this, sb.toString(), Toast.LENGTH_LONG).show();
}
}
});
}
});
}
private void initParam() {
String[] send = {"美团专送", "到店自取","骑手配送"};
String[] feature = {"免配送费", "0元起送", "品牌商家", "点评高分", "跨天预定", "最新商家", "可开发票"};
String[] activity = {"优惠商家", "首单立减", "满减优惠", "进店领券", "折扣商品", "第二份半价", "提前下单优惠", "满返代金券"};
FilterTypeBean fb1 = new FilterTypeBean();
fb1.setTypeName("配送");
List<FilterTypeBean.Condition> childrenList = new ArrayList<>();
for (int x = 0; x < send.length; x++) {
FilterTypeBean.Condition cd = new FilterTypeBean.Condition();
cd.setValue(send[x]);
childrenList.add(cd);
}
fb1.setChildren(childrenList);
FilterTypeBean fb2 = new FilterTypeBean();
fb2.setTypeName("商家特色");
List<FilterTypeBean.Condition> childrenList2 = new ArrayList<>();
for (int x = 0; x < feature.length; x++) {
FilterTypeBean.Condition cd = new FilterTypeBean.Condition();
cd.setValue(feature[x]);
childrenList2.add(cd);
}
fb2.setChildren(childrenList2);
FilterTypeBean fb3 = new FilterTypeBean();
fb3.setTypeName("优惠活动");
List<FilterTypeBean.Condition> childrenList3 = new ArrayList<>();
for (int x = 0; x < activity.length; x++) {
FilterTypeBean.Condition cd = new FilterTypeBean.Condition();
cd.setValue(activity[x]);
childrenList3.add(cd);
}
fb3.setChildren(childrenList3);
filterList.add(fb1);
filterList.add(fb2);
filterList.add(fb3);
}
总结
这下不用烦恼在需要弹出框的时候到底该弹个什么样的dialog了,这三种弹出框应该能适应大部分的弹出框需求了
代码托管于MangoDialog