当显示的列表需要滚动时,按钮会从 DialogFragment 中消失

问题描述 投票:0回答:2

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();
    }

当我必须滚动时仍然没有按钮。 为什么不呢?我能做什么呢?

java android scroll android-alertdialog android-dialogfragment
2个回答
0
投票

解决方案如下:

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 现在就像魅力一样! 我所要做的就是简单地注释掉上面的几行。 因此,没有显式膨胀的布局,也没有设置视图。 但它仍然有效。

如果有人可以向我解释,我会很高兴

  1. 其工作原理的详细信息,
  2. 为什么对方没有,以及
  3. 鉴于之前的失败,如何实现自定义布局来实现视图滚动时不丢失操作按钮的结果

0
投票

当使用带有按钮的自定义视图的自定义 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()之后设置。

现在按钮在对话框中可见。

© www.soinside.com 2019 - 2024. All rights reserved.