问题
Dialog 的自定义布局的根布局的宽度是写固定的,显示的时候宽度和高度不是对应的固定值。
解决
根布局外面又添加了一层 FrameLayout,设置其宽高均为 wrap_content 来包裹以前的布局。
分析
这个时候猜测是否因为添加自定义视图的时候,布局参数被改写了,然后开始查看源码,最终发现确实是这样的。
在下面的源码分析中,最终发现也是用了 mWindow.setContentView(mAlertDialogLayout) 将 R.layout.alert_dialog.xml 的默认布局添加到 PhoneWindow, 和Activity一样的。
关键的地方看一下 setupCustomContent() 这个方法,在添加自定义视图的时候布局参数设置为 MATCH_PARENT 了,所以我们设置固定大小是没有作用的,要套一层父布局解决这个问题。
原因
com.android.internal.R.layout.alert_dialog.xml 中自定义部分
<FrameLayout android:id="@+id/customPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<FrameLayout android:id="@+android:id/custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:paddingBottom="5dip" />
</FrameLayout>
AlertController 关键代码
public AlertController(Context context, DialogInterface di, Window window) {
mContext = context;
mDialogInterface = di;
mWindow = window;
...
mAlertDialogLayout = a.getResourceId(com.android.internal.R.styleable.AlertDialog_layout,
com.android.internal.R.layout.alert_dialog);
...
}
public void installContent() {
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
if (mView == null || !canTextInput(mView)) {
mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
mWindow.setContentView(mAlertDialogLayout);
setupView();
}
private void setupView() {
final View parentPanel = mWindow.findViewById(R.id.parentPanel);
...
final ViewGroup customPanel = (ViewGroup) parentPanel.findViewById(R.id.customPanel);
setupCustomContent(customPanel);
...
}
private void setupCustomContent(ViewGroup customPanel) {
...
final FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.custom);
custom.addView(customView, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
...
}
其他
- 想查看
alert_dialog.xml
布局文件可以去在线安卓源码网站查看。 - 推荐一个在线源码网站:http://androidxref.com/。
网友评论