这是一个基于DialogFragment拓展的dialog,可以完成近乎所有的弹出dialog的东西,看效果:
它的Github地址:https://github.com/Othershe/NiceDialog,根据文档说的添加项目依赖就可直接在自己的项目中使用了。但光能使用不是目的,下面将完全分析一下niceDialog的源码。
首先需要创建一个BaseNiceDialog的类,这个类继承DialogFragment,即
public abstract class BaseNiceDialog extends DialogFragment
之后在这个类中写如下几个方法:
public abstract int intLayoutId(); 这个方法主要是用来设置dialog 的布局文件
public abstract void convertView(ViewHolder holder, BaseNiceDialog dialog);这个方法传递的两个参数一个用来方便UI操作,另一个用来控制dialog的dismiss。ViewHolder是一个工具类,用来辅助View初始化、绑定事件等操作。
ViewHolder的代码如下:
public class ViewHolder {
private SparseArray views;
private View convertView;
private ViewHolder(View view) {
convertView = view;
views = new SparseArray<>();
}
public static ViewHolder create(View view) {
return new ViewHolder(view);
}
public T getView(int viewId) {
View view = views.get(viewId);
if (view == null) {
view = convertView.findViewById(viewId);
views.put(viewId, view);
}
return (T) view;
}
public View getConvertView() {
return convertView;
}
public void setText(int viewId, String text) {
TextView textView = getView(viewId);
textView.setText(text);
}
public void setText(int viewId, int textId) {
TextView textView = getView(viewId);
textView.setText(textId);
}
public void setTextColor(int viewId, int colorId) {
TextView textView = getView(viewId);
textView.setTextColor(colorId);
}
public void setOnClickListener(int viewId, View.OnClickListener clickListener) {
View view = getView(viewId);
view.setOnClickListener(clickListener);
}
public void setBackgroundResource(int viewId, int resId) {
View view = getView(viewId);
view.setBackgroundResource(resId);
}
public void setBackgroundColor(int viewId, int colorId) {
View view = getView(viewId);
view.setBackgroundColor(colorId);
}
}
接下来需要重写两个方法:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.NiceDialog);
layoutId = intLayoutId();
}
这个方法中,第二行setStyle的作用是去掉对话框的标题、背景等。而第三行的代码有一个变量layoutId,则需要我们定义,
protected int layoutId;这个变量是dialog的布局文件。
接着重写另一个方法:
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(layoutId, container, false);
convertView(ViewHolder.create(view), this);
return view;
}
这个方法中就调用了convertView。
方法中定义一些变量:
private int margin;//左右边距
private int width;//宽度
private int height;//高度
private float dimAmount = 0.5f;//灰度深浅
private boolean showBottom;//是否底部显示
private boolean outCancel = true;//是否点击外部取消
再写一些方法,用于给上面的变量赋值:
//距离屏幕左右的margin
public BaseNiceDialog setMargin(int margin) {
this.margin = margin;
return this;
}
//宽度
public BaseNiceDialog setWidth(int width) {
this.width = width;
return this;
}
//高度
public BaseNiceDialog setHeight(int height) {
this.height = height;
return this;
}
//调节灰色背景色的深浅
public BaseNiceDialog setDimAmount(float dimAmount) {
this.dimAmount = dimAmount;
return this;
}
//是否在底部显示
public BaseNiceDialog setShowBottom(boolean showBottom) {
this.showBottom = showBottom;
return this;
}
//是否取消触摸外部
public BaseNiceDialog setOutCancel(boolean outCancel) {
this.outCancel = outCancel;
return this;
}
//进入退出动画
public BaseNiceDialog setAnimStyle(@StyleRes int animStyle) {
this.animStyle = animStyle;
return this;
}
接下来要就要配置这些属性:
private void initParams() {
Window window = getDialog().getWindow();
if (window != null) {
WindowManager.LayoutParams lp = window.getAttributes();
//调节灰色背景透明度[0-1],默认0.5f
lp.dimAmount = dimAmount;
//是否在底部显示
if (showBottom) {
lp.gravity = Gravity.BOTTOM;
if (animStyle == 0) {
animStyle = R.style.DefaultAnimation;
}
}
//设置dialog宽度
if (width == 0) {
lp.width = Utils.getScreenWidth(getContext()) - 2 * Utils.dp2px(getContext(), margin);
} else {
lp.width = Utils.dp2px(getContext(), width);
}
//设置dialog高度
if (height == 0) {
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
} else {
lp.height = Utils.dp2px(getContext(), height);
}
//设置dialog进入、退出的动画
window.setWindowAnimations(animStyle);
window.setAttributes(lp);
}
setCancelable(outCancel);
}
在这个方法中,Utils已经style就是一个简单的工具类和配置。
public class Utils {
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int getScreenWidth(Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return displayMetrics.widthPixels;
}
}
而style就是自己定义的一些资源:
之后需要重写一下onStart方法:
@Override
public void onStart() {
super.onStart();
initParams();
}
以上就是BaseNiceDialog的核心部分,下一篇是BaseNiceDialog一些拓展处理,以及niceDialog其他部分的解析。