AlertDialog 完美地显示内容和按钮,直到内容增长到需要滚动才能显示全部内容的程度。此时,即使列表完整显示,按钮也会消失。
我看到在过去的几年里有人问过这个问题(这个问题本质上与我的相同(DialogFragment按钮被推离屏幕API 24及以上),但答案似乎都命中或错过,甚至是随意的:设置layout_weight,切换从 setMessage() 到 setTitle(),最后从 AlertDialog 切换到 Dialog
这些对我来说都不起作用,并且避免 AlertDialog 不是一个有吸引力的选择,因为我使用的 setMultiChoiceItems() 方法似乎(对我来说令人难以置信,也许考虑到我极其有限的知识)仅适用于 AlertDialog。
因此,在绝望和沮丧中,我直接向 stackoverflow 的集体智慧发出呼吁。
这是我的 DialogFragment 的精简版本:
public class SurfaceDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.surface_dialog, null))
.setTitle(mMessage)
.setMultiChoiceItems(mSurfaceList, mCheckedSurfaces, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
mCheckedSurfacesPositions.add(which);
} else {
mCheckedSurfacesPositions.remove(mCheckedSurfacesPositions.indexOf(which));
}
}
});
// builder.setCancelable(false);
builder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ProcessDialogSelections(mCheckedSurfacesPositions);
dismiss();
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
listener.onSurfaceDialogSelectedSent(mUnitSurfaces);
dismiss();
}
});
return builder.create();
}
那不起作用,然后我编写了自己的按钮并显示它们:
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
View dialogView = inflater.inflate(R.layout.surface_dialog, null);
builder.setView(dialogView)
.setTitle(mMessage)
.setMultiChoiceItems(mSurfaceList, mCheckedSurfaces, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
mCheckedSurfacesPositions.add(which);
} else {
mCheckedSurfacesPositions.remove(mCheckedSurfacesPositions.indexOf(which));
}
}
});
Button positiveButton = dialogView.findViewById(R.id.positive_button);
Button negativeButton = dialogView.findViewById(R.id.negative_button);
positiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ProcessDialogSelections(mCheckedSurfacesPositions);
dismiss();
}
});
negativeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onSurfaceDialogSelectedSent(mUnitSurfaces);
dismiss();
}
});
return builder.create();
}
这是我修改后的 XML 文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="vertical">
</ScrollView>
<Button
android:id="@+id/positive_button"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:layout_width="wrap_content"
android:text="Done"
app:layout_constraintBaseline_toBaselineOf="@+id/negative_button"
app:layout_constraintEnd_toStartOf="@+id/negative_button"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/negative_button"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:layout_width="wrap_content"
android:text="Cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/positive_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
由于这不起作用,然后我遵循了 Vikas Singh 的建议(使用自定义布局时警报对话框按钮不可见)。这就是新代码的样子(本质上是用 Java 而不是 XML 创建布局。
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// New code from Vikas Singh
LinearLayout rootLayout = new LinearLayout(getActivity());
rootLayout.setOrientation(LinearLayout.VERTICAL);
ScrollView scrollView = new ScrollView(getActivity());
LinearLayout layout = new LinearLayout(getActivity());
layout.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(layout);
rootLayout.addView(scrollView);
builder.setNegativeButton("Cancel", null);
builder.setPositiveButton("Go", null);
builder.setView(rootLayout);
builder//.setView(dialogView)
//.setTitle(mMessage)
.setMultiChoiceItems(mSurfaceList, mCheckedSurfaces, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
mCheckedSurfacesPositions.add(which);
} else {
mCheckedSurfacesPositions.remove(mCheckedSurfacesPositions.indexOf(which));
}
}
});
return builder.create();
}
当我必须滚动时仍然没有按钮。 为什么不呢?我能做什么呢?
解决方案如下:
public class SurfaceDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
//LayoutInflater inflater = requireActivity().getLayoutInflater();
builder
//.setView(inflater.inflate(R.layout.surface_dialog, null)) didn't work
// nor did setView with android.R.layout.select_dialog_multichoice
// nor android.R.layout.simple_list_item_multiple_choice work
.setTitle(mMessage)
.setMultiChoiceItems(mSurfaceList, mCheckedSurfaces, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
mCheckedSurfacesPositions.add(which);
} else {
mCheckedSurfacesPositions.remove(mCheckedSurfacesPositions.indexOf(which));
}
}
});
// builder.setCancelable(false);
builder.setPositiveButton("Done", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ProcessDialogSelections(mCheckedSurfacesPositions);
dismiss();
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
listener.onSurfaceDialogSelectedSent(mUnitSurfaces);
dismiss();
}
});
return builder.create();
}
multiChoiceItems DialogFragment 现在就像魅力一样! 我所要做的就是简单地注释掉上面的几行。 因此,没有显式膨胀的布局,也没有设置视图。 但它仍然有效。
如果有人可以向我解释,我会很高兴
当使用带有按钮的自定义视图的自定义 ListPreference 对话框时,我遇到了同样的问题,按钮未显示在长 ListView 上。就像@LameDoc 一样,它让我摸不着头脑,无论我尝试什么,按钮仍然隐藏在视图中。
最后我找到了解决方案,结果证明这是一个简单的修复。在dialog.show()之后添加以下内容,Kotlin:
dialog.show()
val params = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
params.height = 600
dialog.listView.layoutParams = params
这设置了 ListView 的高度,防止其扩展到最大并隐藏按钮。必须在dialog.show()之后设置。
现在按钮在对话框中可见。