【问题标题】:Can't access the Fragment View's LifecycleOwner when getView() is nullgetView() 为 null 时无法访问 Fragment View 的 LifecycleOwner
【发布时间】:2020-08-25 11:39:51
【问题描述】:

我正在尝试从我的AlertDialog 中的 ROOM 数据库中观察所有练习名称的列表。

但是我收到以下错误消息:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.Application android.app.Activity.getApplication()' on a null object reference

错误信息出现在这里:

childExerciseViewModel = ViewModelProviders.of((FragmentActivity) context).get(ChildExerciseViewModel.class);
                       

如何避免错误?

AddExerciseDialog

public class AddExerciseDialog extends AppCompatDialogFragment {

    private EditText editTextExerciseName;
    private ChildExerciseViewModel childExerciseViewModel;
    String userEnteredExerciseName;
    int exerciseTypeID;
    Button cancelBtn;
    Button addBtn;
    Context context;

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

        childExerciseViewModel = ViewModelProviders.of((FragmentActivity) context).get(ChildExerciseViewModel.class);
        //return view;
        return inflater.inflate(R.layout.layout_dialog_add_exercise, container, false);
    }

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

        editTextExerciseName = getView().findViewById(R.id.editTextExerciseName);
        addBtn = (Button) getView().findViewById(R.id.addBtn);
        cancelBtn = (Button) getView().findViewById(R.id.cancelBtn);
        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle mArgs = getArguments();
                exerciseTypeID = mArgs.getInt("ExerciseTypeID");
                userEnteredExerciseName = editTextExerciseName.getText().toString();
                childExerciseViewModel.getAllChildExerciseNames().observe((FragmentActivity) context, this::checkIfChildExerciseNameAlreadyExists);
                // this checks if child exercise already exists, if so add error toast
            }

            private void checkIfChildExerciseNameAlreadyExists(List<String> childExercisesList) {
                for (int i = 0; i < childExercisesList.size(); i++) {

                    if (childExercisesList.contains(userEnteredExerciseName)) {
                        Toast.makeText(getContext(), "An exercise with that name already exists", Toast.LENGTH_SHORT).show();
                    } else {
                        final ChildExercises childExercise = new ChildExercises(0, userEnteredExerciseName, null, exerciseTypeID);
                        childExerciseViewModel.insert(childExercise);
                    }
                }
            }
        });
    }
}

【问题讨论】:

  • AddExerciseDialog 是扩展 dialogfragment 吗?
  • 是的AddExerciseDialog extends AppCompatDialogFragment
  • 然后在 oncreateview 中编写相同的代码,他们的视图将始终可用并解决您的问题
  • 感谢您的回复,onCreateViewonCreateDialog 不同。我想创建一个对话框弹出。请您澄清您的建议。
  • 是的 onCreateView 和 onCreateDialog 不一样,但这取决于您希望如何使用对话框,对于您的用例,我建议您将其用作视图,因为您需要视图模型和视图模型取决于在视图生命周期中,这就是为什么它在 onCreateDialog 中始终为空。此外,如果您移至 onCreateView,一切都会几乎相同。

标签: java android android-alertdialog android-livedata android-viewmodel


【解决方案1】:

试试这个:

使用this 而不是getViewLifecycleOwner()

【讨论】:

  • 不幸的是这不起作用:无法解析方法getActivity()
  • 必需:生命周期所有者,提供:onClickListener
  • 像 this@yourFragmentName 一样使用它。因为我的片段名称是 SelectDriverFragment。我正在使用 this@SelectDriverFragment 而不是 viewLifecycleOwner。并在我的方法之上使用 @SuppressLint("FragmentLiveDataObserve") 。我的问题现在解决了。
猜你喜欢
  • 2020-03-03
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多