弹出框

  • 背景
  • 提示与询问弹出框
    • 实现
    • 使用
  • 列表选择框
    • 实现
    • 使用
  • 顶部条件筛选框
    • 实现
      • 自定义ViewGroup
    • 使用
  • 总结

背景

鉴于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();}@Overridepublic 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() {@Overridepublic 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;}@Overrideprotected 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*/@Overrideprotected 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的marginlp.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*/@Overrideprotected 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和rightMarginlineWidth += childWidth + lp.leftMargin + lp.rightMargin;//计算一行的高度取lineHeight和子view的实际高度最大值lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);//保存子viewlineViews.add(child);}//保存每行的高度、宽度、子viewmLineHeight.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++) {//一行的子viewlineViews = mAllViews.get(i);//这一行需要的高度lineHeight = mLineHeight.get(i);//这一行需要的宽度int currentLineWidth = mLineWidth.get(i);//每次换行重新计算left值,getPaddingLeft获取viewgroup的PaddingLeftswitch (this.mGravity) {case LEFT:left = getPaddingLeft();break;case CENTER:left = getPaddingLeft();break;case RIGHT:left = width - currentLineWidth + getPaddingLeft();break;}//遍历每行子viewfor (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自身的leftMarginint lc = left + lp.leftMargin;//计算子view 的top值=当前top+子view 的topMarginint tc = top + lp.topMargin;int rc = lc + child.getMeasuredWidth();int bc = tc + child.getMeasuredHeight();//摆放子viewchild.layout(lc, tc, rc, bc);//下一个子view 的left=当前left+当前子view的宽度+当前子view的leftMargin与rightMarginleft += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;}//计算下一行的top=当前top+一行高度top += lineHeight;}}

最后重写下generateLayoutParams方法,返回布局参数类LayoutParams

    @Overridepublic LayoutParams generateLayoutParams(AttributeSet attrs) {return new MarginLayoutParams(getContext(), attrs);}@Overrideprotected LayoutParams generateDefaultLayoutParams() {return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);}@Overrideprotected 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);//设置viewthis.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() {@Overridepublic 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() {@Overridepublic void onClick(View view) {onConfirmClickListener.onConfirmClick();dismiss();}});nullView.setOnClickListener(new View.OnClickListener() {@Overridepublic 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() {@Overridepublic void onClick(View view) {mPopWindow = new MangoPopWindow(MainActivity.this, dictList);mPopWindow.showAsDropDown(ivBack);mPopWindow.setOnConfirmClickListener(new MangoPopWindow.OnConfirmClickListener() {@Overridepublic 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

Android仿IOS封装通用的弹出框Dialog和底部弹出列表选择框 仿美团顶部条件筛选框 附自定义ViewGroup相关推荐

  1. android 条件筛选吸顶,自定义吸顶LayoutManager

    吸顶效果 RecyclerView已经成为在Android Native开发过程中的明星组件,出镜率超高,只要需要列表展示的内容,我们第一想到的就是使用RecyclerView.RecyclerVie ...

  2. android 7 ios 安全性,在安全性方面,安卓真的是垃圾!尽量都选择用iOS手机吧

    说一下自己在安卓手机遇到的情况吧! 1. 我自己的体验:每次我在京东搜索过某商品,打开虎扑后推送的广告绝对是京东的那些商品广告,比如,我之前在京东搜索过"小米显示器.机械键盘.笔记本等&qu ...

  3. android 底部弹窗失效,Android实现从底部弹出Dialog(和PopWindow实现的效果同样)

    布局文件:dialog_custom_layout.xmlandroid android:orientation="vertical" android:layout_width=& ...

  4. Android自定义底部弹出窗-dialog(2种实现分析+源码)

    Android自定义底部弹出窗-dialog(2种实现分析+源码) 上线项目功能抽取,在项目开发中,我们会在许多地方会用到底部自定义弹窗,比如设置:个人账户退出,切换,照片的拍照或者相册的调出,或者一 ...

  5. android高仿ios控制中心,高仿ios控制中心安卓版

    高仿ios控制中心安卓版是一款非常好用的安卓仿苹果手机控制中心的软件,能够让使用安卓手机的朋友们随时体验苹果手机的系统,操作简单方便,软件也是非常稳定的,大家可放心的下载使用,感兴趣的用户们就前来下载 ...

  6. Android实践-自定义dialog从屏幕底部弹出并且充满屏幕宽度

    转载出处http://blog.csdn.net/nugongahou110 通常我们使用dialog的时候会遇到一些问题,比如我想用自己定义的布局来替代系统那个黑乎乎的布局时我要怎么做?我想要指定d ...

  7. android高仿输入法,仿ios输入法

    详情 仿ios输入法是一款十分有趣的手机输入法app,可以做到在安卓的手机上使用以假乱真的ios手机输入法,操作简单方便,习惯使用苹果手机后来换安卓手机或者是想用这个输入法恶搞其他人的朋友们,可以下载 ...

  8. 使用BottomSheetDialogFragment实现购买出商品,底部弹出商品属性的效果

    BottomSheetDialogFragment继承于BottomSheetDialog,一个Dialog形式的framgnet,可实现拖动打开及关闭,通过查看源码,发现在其内部是创建了一个Bott ...

  9. android模仿ios滚动,模仿iOS版微信的滑动View效果

    前言 最近经常交替使用Android和iOS手机.对于两个系统,从我们常用的列表来看,Android一般的列表菜单是通过长按出来的,而iOS是通过滑动出现的.比如我们常用的微信,对于Android版本 ...

最新文章

  1. Linux学习(linux就该这么学习)8.1
  2. HashMap数据类型使用注意-不能使用基本数据类型
  3. 跟我一起学perl系统管理脚本 第3课
  4. OpenCASCADE绘制测试线束:OCAF 命令之标准演示命令
  5. wxWidgets:wxDCClipper类用法
  6. Spring Security和多个过滤器链
  7. ASP非模板生成静态页
  8. 如何获得线程对象,获得Thread对象,得到线程对象,根据线程名获得线程对象,多线程取得线程对象...
  9. SQLHelp sql数据库的DAL
  10. 基于Modbus/TCP的西门子1200PLC和STM32通信
  11. AE 动效工作流技巧 —— 减少 Bodymovin 导出的 JSON 大小并提升性能(三)
  12. 异步FIFO中格雷码和二进制数据的转换
  13. html中图片为什么反了,HTML5 canvas如何实现图片反色
  14. 手机打字测速软件简版
  15. 维基百科:人人都能改写的网络百科全书
  16. 亚马逊要求化妆品提交HRIPT / RIPT测试报告和COA证书详情解析
  17. 招商银行、伊利股份套利模型(1)
  18. C语言 生成集合的幂集
  19. 华为路由器负载均衡_华为路由器双出口负载均衡+备份(示例代码)
  20. 套接字创建、连接和关闭函数

热门文章

  1. 详解如何使用git sqush合并多次未提交commit
  2. Symbol的具体用法
  3. CSS图片的下边有间隙解决方法
  4. 新浪微博mid base62进制转10进制
  5. 周岁计算方法(当天加一岁 与 过了当日加一岁)
  6. WWDC 2015 后最新的苹果开发者协议(翻译版)
  7. [译] 如何阅读苹果开发文档
  8. @Deprecated 注解
  9. 台式计算机鼠标没有怎么移动,鼠标无法移动是怎么回事
  10. 苹果6sp怎么录屏_涨知识了!原来苹果手机还自带录屏功能,不用有些浪费了