【问题标题】:Unable to initialize the Context无法初始化上下文
【发布时间】:2017-08-12 03:21:25
【问题描述】:

我有一个活动,它使用一个适配器和一个显示回收器列表视图的片段。当用户点击任何行时,我会显示一个 AlertDialog(创建为 DialogFragment)供他们输入数据。

来自 AlertDialog 的回调被 Fragment 监听,一旦 Fragment 中的所有字段都被捕获,完成的对象将被发送回 Activity 以将其保存在数据库中。

这是截图……

现在,在我输入名称并点击继续后,我遇到了崩溃,因为来自 DisplayTextEntryAlert 类(即 DialogFragment)的侦听器未初始化。

java.lang.NullPointerException: Attempt to invoke interface method 'void alerts.DisplayTextEntryAlert$DisplayTextEntryAlertListener.onYesButtonClicked(android.support.v4.app.DialogFragment, java.lang.String)' on a null object reference
at alerts.DisplayTextEntryAlert$1.onClick(DisplayTextEntryAlert.java:97)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)

在我的 DisplayTextEntryAlert 类中,它在执行 mListener.onYesButtonClicked 时崩溃。

public Dialog onCreateDialog(Bundle savedInstanceState) {

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    ....
    ....
    ....
    builder.setPositiveButton(R.string.stgContinue, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
             mTextEntered = editTextControl.getText().toString();
             mListener.onYesButtonClicked(DisplayTextEntryAlert.this, mTextEntered);
        }
    });    

mListener 对象在 DisplayTextEntryAlert 类的 'onAttach' 方法中初始化

public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof DisplayTextEntryAlertListener) {
        mListener = (DisplayTextEntryAlertListener)context;
    } else {
        Log.d(this.toString(),"trackContext");
        Log.d(this.toString(),context.toString());
        //throw new RuntimeException(context.toString() + " must implement DisplayTextEntryAlertListener");
    }
}    

但是在调试时,我注意到这条线永远不会被执行。

mListener = (DisplayTextEntryAlertListener)context;

此 AlertDialog 是从从 Activity (AddFriendActivity) 启动的 Fragment 类 (AddFriendFragment) 创建的

DisplayTextEntryAlert displayTextEntryAlertFragment = DisplayTextEntryAlert.newInstance("","Enter the first name");
FragmentManager fragmentManager = ((FragmentActivity) mContext).getSupportFragmentManager();
displayTextEntryAlertFragment.show(fragmentManager, "newFriendFragment"); // give it a name for retrieving

这里的 'mContext' 是通过这个片段中的 onCreateView 方法创建的

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_newfriend_list, container, false);

    // Set the adapter
    if (view instanceof RecyclerView) {
        mContext = view.getContext();
        ....
        ....
        ....
        mNewFriendAdapter = new NewFriendAdapter(mNewFriendFields, this);
        recyclerView.setAdapter(mNewFriendAdapter);
    }
    return view;
}

问题:我显然在这里遗漏了一些东西,否则 mListener 将在 DisplayTextEntryAlert 类的 onAttach 方法中初始化。

有什么线索吗?

这里是完整的源代码供参考 https://gist.github.com/ArdenDev/229c69f803dce62a1e46acb0e05c7f1a

【问题讨论】:

  • 可以尝试在onYesButtonClicked的参数中将DisplayTextEntryAlert.this改为getActivity()
  • @KeLiuyue 不,那是行不通的。参数必须是 DialogFragment。

标签: android android-fragments android-alertdialog android-context


【解决方案1】:

让你的AddFriendActivity 实现DisplayTextEntryAlertListener

然后在 AddFriendActivity 中覆盖该功能

@Override
public void onYesButtonClicked(String text)
{
    // Do anything with your text
}

如果您需要Context 来代替Listener,请使用getActivity()getContext() 而不是DisplayTextEntryAlert.this

mListener.onYesButtonClicked(getActivity());

还有一件事,当你膨胀你的视图时,你不必检查instance of。因为我看到你的布局中不仅有RecyclerView,还有ToolBar,所以view肯定不是RecyclerView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_newfriend_list, container, false);

// Remove the instance of condition
mContext = view.getContext();
    ....
    ....
    ....
    mNewFriendAdapter = new NewFriendAdapter(mNewFriendFields, this);
    recyclerView.setAdapter(mNewFriendAdapter);
return view;
}

【讨论】:

  • 我不需要将回调发送到活动。我想在 AddFriendFragment 内部处理这个问题。
  • 请查看源代码要点链接。一旦用户输入了所有字段,我希望将整个 Person 对象发送到活动。
【解决方案2】:

因此,您在 onAttach(Content context) 上使用的问题是在 23 API 版本(Android 6)中添加的,并且它永远不会在较低的 API 版本中调用。您应该同时覆盖 onAttach(Context context) 和 onAttach(Activity activity)

【讨论】:

  • 几周前刚开始编写 Android 代码。你能给我一些关于覆盖应该是什么的上下文吗?
  • @ArdenDev 只是将您在 onAttach(上下文上下文)中的代码复制到 onAttach(活动活动)
  • 如果我这样做,它希望我在 AddFriendActivity 中实现 DisplayTextEntryAlertListener。我想处理 AddFriendFragment 中的回调。
  • @ArdenDev 您可以在活动中创建一个公共方法,该方法将返回您的片段。在 onAttach 中,您将活动转换为 YouActivityName,调用方法并将结果转换为您的侦听器。
【解决方案3】:

所以诀窍是使用 setFragment。这现在有效

DisplayTextEntryAlert displayTextEntryAlertFragment = DisplayTextEntryAlert.newInstance("","Enter the first name");
displayTextEntryAlertFragment.setTargetFragment(this, 0);
displayTextEntryAlertFragment.show(getActivity().getSupportFragmentManager(), "newFriendFragment");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-10
    • 2014-09-15
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多