Dialog Fragment 中的 Spinner 始终为空 - 包含具有值的 Adapter 但不显示它们

Spinner in Dialog Fragment is always empty - contains Adapter with values but isn't displaying them

我是 Android 的新手,在使用 DialogFragment 中的 Spinners 时遇到了一些问题。

我正在尝试创建一个带有两个微调器的对话框片段,这两个微调器都填充了来自字符串数组资源的数据。

我没有收到任何错误,在使用调试器逐步执行时,我可以看到在调用适当的方法后,Spinners 包含适配器,其中包含数组中的数据。

但是当对话框打开时,微调器总是显示为空。

我已经花了几个小时扫描我的代码以查找错误并查阅文档,并查看相关帖子。

其他类似此处发现的空微调器的情况 and here 似乎是由微调器的设置代码问题引起的,但我在这里找不到类似的东西。

我认为这可能与视图绑定有关,所以我尝试使用 findViewById() 来获取我对视图的引用,但这没有用。

我想知道这是否是 Fragment 或 DialogFragment 特有的问题,因为我在 Activity 中没有遇到过这个问题。

我被困住了,如果有人能提供任何指导,我将不胜感激!

对话框片段:

'''

public class AddGoalDialog extends DialogFragment {

FragmentAddGoalDialogBinding binding;

public AddGoalDialog() {
    // Required empty public constructor
}

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState){




    return new AlertDialog.Builder(requireContext())
            .setTitle(getString(R.string.new_goal_dialog_title))
            .setPositiveButton(getString(R.string.submit), (dialog, id) -> {
                doPositiveClick();
            } )
            .setNegativeButton(getString(R.string.cancel), (dialog, id) -> {
                dialog.cancel();
            })
            .setView(R.layout.fragment_add_goal_dialog)
            .create();

}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {

    binding = FragmentAddGoalDialogBinding.bind(view);
    ArrayAdapter<CharSequence> durAdapter = ArrayAdapter.createFromResource(getContext(),
            R.array.goal_duration_array, android.R.layout.simple_spinner_item);
    durAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    Spinner dialogSpinnerGoalDuration = view.findViewById(R.id.dialog_spinner_goal_duration);
    dialogSpinnerGoalDuration.setAdapter(durAdapter);

    ArrayAdapter<CharSequence> typeAdapter = ArrayAdapter.createFromResource(getContext(),
            R.array.goal_type_array, android.R.layout.simple_spinner_item);
    typeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    Spinner dialogSpinnerGoalType = binding.dialogSpinnerGoalType;
    dialogSpinnerGoalType.setAdapter(typeAdapter);
    super.onViewCreated(view, savedInstanceState);
}
}

'''

对话框片段布局:

'''

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".AddGoalDialog">

    <Spinner
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/spinner_goal_duration"/>

    <Spinner
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/spinner_goal_type"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText_enter_goal"
        android:inputType="number"
        android:hint="@string/enter_a_goal"/>

</LinearLayout>

'''

你试过这样吗?

   ArrayAdapter<String> adapter = new ArrayAdapter<String> ( getContext (), android.R.layout.simple_spinner_dropdown_item, yourArrayList  );

我的代码有两个问题导致了这个问题。

我在 DialogFragment 文档中找到了第一个问题的解决方案。

“onViewCreated() 永远不会在自定义 DialogFragment 上调用,除非您重写了 onCreateView() 并提供了一个非空视图。” https://developer.android.com/guide/fragments/dialogs#java.

我已将微调器的所有设置代码放入 onViewCreated() 方法中。虽然我也曾尝试将它放在 onCreateDialog() 方法中,但在那种类型下我没有正确设置视图绑定。

解决方案是将微调器的设置代码移至 onViewCreated() 方法,并按照此处所述设置视图绑定

@NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState){

        binding = FragmentAddGoalDialogBinding.inflate(LayoutInflater.from(getContext()));

        ArrayAdapter<CharSequence> durAdapter = ArrayAdapter.createFromResource(getContext(),
                R.array.goal_duration_array, android.R.layout.simple_spinner_item);
        durAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        Spinner dialogSpinnerGoalDuration = binding.dialogSpinnerGoalDuration;
        dialogSpinnerGoalDuration.setAdapter(durAdapter);

        ArrayAdapter<CharSequence> typeAdapter = ArrayAdapter.createFromResource(getContext(),
                R.array.goal_type_array, android.R.layout.simple_spinner_item);
        typeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        Spinner dialogSpinnerGoalType = binding.dialogSpinnerGoalType;
        dialogSpinnerGoalType.setAdapter(typeAdapter);
        
        return new AlertDialog.Builder(requireContext())
                .setTitle(getString(R.string.new_goal_dialog_title))
                .setPositiveButton(getString(R.string.submit), (dialog, id) -> {
                    doPositiveClick();
                } )
                .setNegativeButton(getString(R.string.cancel), (dialog, id) -> {
                    dialog.cancel();
                })
                .setView(binding.getRoot())
                .create();;
    }