如果一起使用,AlertDialog 不适合长列表、视图和按钮



不久前,我遇到了AlertDialog:的问题

如果它有时与列表适配器(通过setAdpater/setSingleChoiceItems/setMultiChoiceItems(和自定义视图(通过setView(和按钮一起使用,并且列表太长,不适合对话框的高度,我的自定义添加的视图和对话框按钮没有显示。。。(它正在显示,但由于被listview下移而不可见(这是一个测试代码:

final int TEST_COUNT = 20; //increase it if list fit your screen...
List<String> list = new LinkedList<>();
for (int i = 1; i <= TEST_COUNT; i++)
list.add("item "+i);
TextView testView = new TextView(this); //type of view doesn't matter
testView.setText("test view");
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.select_dialog_item, list);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog dialog = builder
.setTitle("Test AlertDialog")
.setAdapter(adapter, (dlg, which) -> {})
.setView(testView) //this line broke all!
.setPositiveButton("Yes", (dlg, which) -> dlg.dismiss())
.setNegativeButton("No", (dlg, which) -> dlg.dismiss())
.show();

我在谷歌和SO上搜索过,但没有找到有效的解决方案,只有一个建议——用自定义布局编写自己的对话框。。。我决定去寻找真相。

因为我没有找到有效的解决方案,所以我进行了调查并制定了自己的解决方案。首先,我检查了默认的AlertDialog布局和来源:

  1. alert_dialog_material.xml
  2. AlertDialog.java
  3. AlertController.java

上面的链接是在谷歌中找到的,你当然可以在IDE中查看源代码。

正如我们从布局的xml中可以理解的那样,根AlertDialogLayout视图继承自LinearLayout(Compat(,所有子项的高度都为WRAP_CONTENT。但我们需要列表视图适合在标题和我们的自定义视图之间的空间。我找到的解决方案是将"contentPanel"视图的权重设置为1。以下是解决问题的示例代码,只需将问题的第一段代码中的.show((替换为.create((即可:

dialog.setOnShowListener(dlg -> {
AlertDialog adlg = (AlertDialog)dlg;
View v = adlg.getWindow().findViewById(R.id.contentPanel);
if (v != null)
((LinearLayoutCompat.LayoutParams)v.getLayoutParams()).weight = 1;
});
dialog.show();

当然,在谷歌改变默认警报对话框布局之前,它会一直有效。。。

也许有人可以提供更好的解决方案?

感谢您的关注!

最新更新