首先看一下AlertDialog简单的用法。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("hello")
.setTitle("AlertDialog")
.create()
.show();
}
一步一步来看看到底在源码中做了什么。
首先调用AlertDialog.Builder()创建了一个Builder类的对象,它是一个AlertDialog的内部类。
public class AlertDialog {
...
public static class Builder {
...
public Builder(@NonNull Context context) {
this(context, resolveDialogTheme(context, 0));
}
...
}
...
}
通过this调用另一个构造方法。
public Builder(@NonNull Context context, @StyleRes int themeResId) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, themeResId)));
mTheme = themeResId;
}
创建了一个AlertParams类的对象P。
class AlertController {
...
public static class AlertParams {
...
public AlertParams(Context context) {
mContext = context;
mCancelable = true;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
...
}
...
}
AlertParams是AlertController的静态内部类。用户在调用Builder方法后会创建一个对应的AlertParams实例P。
接着调用了一系列Builder的set方法。我们看其中一个setTitle方法。
public Builder setTitle(@Nullable CharSequence title) {
P.mTitle = title;
return this;
}
为P中的对应属性赋值。setMessage和其他的一些set方法也是类似的
public Builder setMessage(@Nullable CharSequence message) {
P.mMessage = message;
return this;
}
通过我们调用一系列的set方法,P中的各个属性已经被填充为我们传入的参数。
接着调用了Builder的create()方法。
public AlertDialog create() {
// We can't use Dialog's 3-arg constructor with the createThemeContextWrapper param,
// so we always have to re-set the theme
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme)