Lib_Dialog
是对封装DialogFragment
的Dialog
模块,使用链式调用对Dialog
进行设置。
Lib_Dialog
有良好的扩展性,有两个方便使用继承类:一个是CustomDialog
,继承于BaseDialogFragment
,用于实现布局简单的自定义View
的Dialog
;一个是DefinedDialog
,直接继承于DialogFragment
,用于直接使用系统的Dialog
和已定义好的Dialog
(已定义好的Dialog
本可以直接继承DialogFragment
来扩展,DefinedDialog
统一了调用风格。
在封装的基础上重写了选项选择器和时间选择器,选项选择器分别有单项选择器、多项(最多三项)不联动选择器和多项联动选择器。
参考了两个开源项目NiceDialog和Android-PickerView。
CustomDialog
使用示例:
public void showCustom(View view) { CustomDialog.init() .setLayoutId(R.layout.dialog_confirm)//布局 .setConvertListener(new ViewConvertListener() {//设置UI的样式 @Override public void convertView(ViewHolder holder, final BaseDialogFragment dialogFragment) { holder.setText(R.id.title, "提示"); holder.setTextColor(R.id.title, getResources().getColor(R.color.title_red)); holder.setText(R.id.message, "您已支付成功!"); holder.setBackgroundColor(R.id.message, Color.GRAY); holder.setOnClickListener(R.id.cancel, new View.OnClickListener() { @Override public void onClick(View v) { dialogFragment.dismiss(); } }); holder.setOnClickListener(R.id.ok, new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "onClicked Confirm", Toast.LENGTH_SHORT).show(); dialogFragment.dismiss(); } }); } }) // .setStyleId(R.style.LibDialog)//风格 // .setAnimStyleId(R.style.DefaultAnimation)//动画 // .setWidth(WindowManager.LayoutParams.MATCH_PARENT)//宽度,可以是MATCH_PARENT、WRAP_CONTENT和具体数值 // .setHeight(WindowManager.LayoutParams.WRAP_CONTENT)//高度,同上 // .setHMargin(200)//水平方向边距 // .setHMargin(200)//垂直方向边距 .setOutCancelable(false)//点击外部是否隐藏 .setX(100)//相对于原始位置的x坐标偏移 .setY(200)//y坐标偏移 .setGravity(Gravity.START|Gravity.TOP)//显示位置 .setDimAmount(0.4f)//灰度值 .showDialog(getSupportFragmentManager(), "custom"); }
其中,ViewConvertListener
用于设置Dialog
中view的样式,包括字体大小、字体颜色、背景、点击事件。
注意,init()
放在最前面,子类的方法优先在前面调用,如上,setLayoutId()
和setConvertListener()
是CustomDialog
的方法,需要放在前面,其它属性的设置方法是BaseDialogFragment
所有,放在后面。
DefinedDialog
使用示例:
public void showSystem(View view) { DefinedDialog.init() .setInitDialogListener(new InitDialogListener() {//返回已定义的dialog @Override public Dialog create() { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("系统dialog") .setMessage("测试已有的dialog") .setPositiveButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "点击取消", Toast.LENGTH_SHORT).show(); } }) .setNegativeButton("测试", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "test", Toast.LENGTH_SHORT).show(); } }) .setCancelable(false); return builder.create(); } }) .showDialog(getSupportFragmentManager(), "system"); }
DefinedDialog
只有以上代码中的方法,Dialog
的设置全部由定义好的Dialog
自己封装。
注意,DefinedDialog
必须设置InitDialogListener
,用来创建已有的Dialog
,否则,会抛出错误。
WheelView
是一个3D滚动控件,在原有基础上了做了一些改动,完善接口封装,可以单独使用,可通过xml布局文件设置WheelView
的属性,见R.styleable.WheelView
。也可以通过代码设置,见下:
private String mLabel;// 附加单位 private int mTextSize;// 选项的文字大小 private int mOutTextColor = 0xffa8a8a8; private int mCenterTextColor = 0xff2a2a2a; private int mDividerColor = 0xffd5d5d5; boolean mLoop;// item是否循环 private int mGravity = Gravity.CENTER; private float mLineSpaceMultiplier = LINE_SPACE_MULTIPLIER;// 条目间距倍数,限制为1.0~2.0
实现原理见Android-PickerView系列之源码解析篇(二)
单项选择器。
使用示例:
public void showOption(View view) { final ArrayList list = new ArrayList<>(20); for (int i = 0; i < 20; i++) { list.add("数据" + i); } SingleOptionDialog.init(list) .setTitle("单项选择器")//设置标题 .setSelectPosition(5)//设置居中项 .setConvertListener(new ViewConvertListener() {//设置UI样式 @Override public void convertView(ViewHolder holder, BaseDialogFragment dialogFragment) { holder.setTextColor(R.id.tv_confirm, Color.YELLOW); holder.setTextColor(R.id.tv_title, Color.LTGRAY); } }) .setWheelViewSetListener(new OnWheelViewSetListener() {//设置WheelView样式 @Override public void setWheelView(WheelView wheelView) { wheelView.setTextSize(30); wheelView.setDividerColor(Color.RED); wheelView.setCenterTextColor(Color.RED); } }) .setOptionSelectListener(new OnOptionSelectListener() {//设置选中回调 @Override public void onOptionSelect(int option) { Toast.makeText(MainActivity.this, list.get(option), Toast.LENGTH_SHORT).show(); } }) .showDialog(getSupportFragmentManager(), "option"); }
可通过ViewConvertListener
设置包裹WheelView
的外部布局的样式,还有OnWheelViewSetListener
用于设置WheelView
的属性,OnOptionSelectListener
用于设置点击右上角确认按钮时的回调。
多项联动选择器,最多三项,主要用于选择省市县地址。
使用示例:
public void showLinkedOptions(View view) { final ArrayList list1 = new ArrayList<>(20); final ArrayList> list2 = new ArrayList<>(20); final ArrayList>> list3 = new ArrayList<>(20); for (int i = 0; i < 20; i++) { list1.add("一级" + i); list2.add(new ArrayList(20)); list3.add(new ArrayList>(20)); for (int j = 0; j < 20; j++) { list2.get(i).add("二级" + "-" + i + "-" + j); list3.get(i).add(new ArrayList(20)); for (int k = 0; k < 20; k++) { list3.get(i).get(j).add("三级" + "-" + i + "-" + j + "-" + k); } } } LinkedOptionsDialog.init(list1, list2, list3) .setTitle("三级联动") .setWheelViewsSetListener(new OnWheelViewsSetListener() {//设置WheelView样式 @Override public void setWheelViews(WheelView wheelView1, WheelView wheelView2, WheelView wheelView3) { wheelView1.setOutTextColor(Color.RED); } }) .setOptionsSelectListener(new OnOptionsSelectListener() { @Override public void onOptionsSelect(int position1, int position2, int position3) { Toast.makeText(MainActivity.this, list1.get(position1) + "~" + list2.get(position1).get(position2) + "~" + list3.get(position1).get(position2).get(position3), Toast.LENGTH_SHORT).show(); } }) .showDialog(getSupportFragmentManager(), "threeLinked"); }
其中,LinkedOptionsDialog
可通过ViewConvertListener
设置包裹WheelView
的外部UI的样式,通过OnWheelViewsSetListener
设置WheelView
的属性,通过OnOptionsSelectListener
设置点击右上角确认按钮时的回调。
注意,LinkedOptionsDialog
通过泛型控制实体类形参,对于数字或String
,使用init(List,List,List)
做初始化;对于其他实体类,需要实现IPickerViewEntity
接口,用于在获取绘制在WheelView
中的内容,还需要实现Serializable
接口,因为保存信息的时候需要序列化(说明,ArrayList
不支持Parcelable
序列化,为了简单统一,选项选择器中的实体类都使用Serializable
),初始化使用init()
方法,然后调用setOptionsList(ArrayList, ArrayList, ArrayList)
方法设置实体类数据列表。
多项非联动选择器,最多三项。
使用示例:
public void showUnLinkedOptions(View view) { final ArrayList list1 = new ArrayList<>(20); final ArrayList list2 = new ArrayList<>(20); final ArrayList list3 = new ArrayList<>(20); for (int i = 0; i < 20; i++) { list1.add("一级数据" + i); list2.add("二级数据" + i); list3.add("三级数据" + i); } UnLinkedOptionsDialog.init(list1, list2, list3) .setTitle("三级非联动") .setSelectPositions(2, 3, 4) .setOptionsSelectListener(new OnOptionsSelectListener() { @Override public void onOptionsSelect(int position1, int position2, int position3) { Toast.makeText(MainActivity.this, list1.get(position1) + list2.get(position2) + list3.get(position3), Toast.LENGTH_SHORT).show(); } }) .showDialog(getSupportFragmentManager(), "threeUnLinked"); }
UnLinkedOptionsDialog
使用类似于LinkedOptionsDialog
,更加简单。
时间选择器,支持年月日时分秒,默认只显示年月日。其中年月日可以设置起始和结束时间边界,默认1900~2100;年月日时分秒可以设置选中居中的值,默认当前时间。
使用示例:
public void showTime(View view) { TimeDialog.init()//默认时间为当前时间 .setTitle("时间选择器") .setMvVisibility(true, true, true, true, true, true)//设置显示的WheelView,对应年月日时分秒 .setInitTimeRangeListener(new InitTimeRangeListener() {//设置时间范围,只支持年月日 @Override public Calendar getStartCalendar() { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, 2010); calendar.set(Calendar.MONTH, 0); calendar.set(Calendar.DAY_OF_MONTH, 10); // calendar.set(Calendar.HOUR_OF_DAY, 8); // calendar.set(Calendar.MINUTE, 20); // calendar.set(Calendar.SECOND, 10); return calendar;//2010.1.10 8:20:10 } @Override public Calendar getEndCalendar() { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, 2020); calendar.set(Calendar.MONTH, 9); calendar.set(Calendar.DAY_OF_MONTH, 30); // calendar.set(Calendar.HOUR_OF_DAY, 22); // calendar.set(Calendar.MINUTE, 30); // calendar.set(Calendar.SECOND, 30); return calendar;//2020.10.30 22:30:30 } @Override public Calendar getSelectedCalendar() { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, 2019); calendar.set(Calendar.MONTH, 9); calendar.set(Calendar.DAY_OF_MONTH, 18); calendar.set(Calendar.HOUR_OF_DAY, 12); calendar.set(Calendar.MINUTE, 30); calendar.set(Calendar.SECOND, 25); return calendar;//2019.10.18 12:30:25 } }) // .setSelectedTime(Calendar)//另一个设置居中时间的方法 // .setRangeTime(Calendar, Calendar)//另一个设置时间范围的方法 .setOnTimeSelectListener(new OnTimeSelectListener() {//设置回调 @Override public void onTimeSelect(Date date) { DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Toast.makeText(MainActivity.this, DATE_FORMAT.format(date), Toast.LENGTH_SHORT).show(); } }) .showDialog(getSupportFragmentManager(), "time"); }
TimeDialog
可以设置包裹WheelView
外部的UI,也可以设置WheelView
的属性。
另外,InitTimeRangeListener
用于设置起始时间和结束时间的边界,以及居中选中时间。OnTimeSelectListener
用于回调右上角点击确认事件,返回一个Date
。
- 当
WheelView
中绘制的内容过长时,可能会和Label
重叠,可能会超出WheelView
的宽度; - 目前默认
Lable
固定绘制在居中WheelView
的右侧,如果想让每个WheelView
都带Label
的话,只能把Label
添加到实体类中; WheelView
默认展示11个Item
,不可修改;这样,WheelView
的高度由文字大小和间距决定。文字很大时,UI会有影响。
NiceDialog
Android-PickerView.
有问题请联系邮箱[email protected],欢迎交流,提出修改建议。