无法初始化上下文
Unable to initialize the Context
我有一个 activity,它使用一个适配器和一个显示回收列表视图的片段。当用户点击任何一行时,我会显示一个 AlertDialog(创建为 DialogFragment)供他们输入数据。
来自 AlertDialog 的回调被 Fragment 侦听,一旦 Fragment 中捕获了所有字段,完成的对象将发送回 activity 以将其保存在数据库中。
这是截图...
现在,在我输入名称并点击继续后,我遇到了崩溃,因为来自 DisplayTextEntryAlert class(即 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.onClick(DisplayTextEntryAlert.java:97)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
在我的 DisplayTextEntryAlert class 中,它在执行 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' 方法中初始化 class
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)
启动的片段 class (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 class 的 onAttach 方法中初始化。
有什么线索吗?
这里是完整的源代码供参考
https://gist.github.com/ArdenDev/229c69f803dce62a1e46acb0e05c7f1a
让你的AddFriendActivity
实现DisplayTextEntryAlertListener
然后在 AddFriendActivity
中覆盖该功能
@Override
public void onYesButtonClicked(String text)
{
// Do anything with your text
}
如果 Listener
需要 Context
,请使用 getActivity()
或 getContext()
而不是 DisplayTextEntryAlert.this
mListener.onYesButtonClicked(getActivity());
还有一件事,您在膨胀视图时不必检查 instance of
。因为我看到你的layout里面不仅有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;
}
所以,您在 onAttach(Content context) 上使用的问题是在 23 API 版本(Android 6)中添加的,它从不调用较低的 API 版本。您应该同时覆盖 onAttach(Context context) 和 onAttach(Activity activity)
所以诀窍是使用 setFragment。这现在有效
DisplayTextEntryAlert displayTextEntryAlertFragment = DisplayTextEntryAlert.newInstance("","Enter the first name");
displayTextEntryAlertFragment.setTargetFragment(this, 0);
displayTextEntryAlertFragment.show(getActivity().getSupportFragmentManager(), "newFriendFragment");
我有一个 activity,它使用一个适配器和一个显示回收列表视图的片段。当用户点击任何一行时,我会显示一个 AlertDialog(创建为 DialogFragment)供他们输入数据。
来自 AlertDialog 的回调被 Fragment 侦听,一旦 Fragment 中捕获了所有字段,完成的对象将发送回 activity 以将其保存在数据库中。
这是截图...
现在,在我输入名称并点击继续后,我遇到了崩溃,因为来自 DisplayTextEntryAlert class(即 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.onClick(DisplayTextEntryAlert.java:97)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
在我的 DisplayTextEntryAlert class 中,它在执行 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' 方法中初始化 class
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)
启动的片段 class (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 class 的 onAttach 方法中初始化。
有什么线索吗?
这里是完整的源代码供参考 https://gist.github.com/ArdenDev/229c69f803dce62a1e46acb0e05c7f1a
让你的AddFriendActivity
实现DisplayTextEntryAlertListener
然后在 AddFriendActivity
@Override
public void onYesButtonClicked(String text)
{
// Do anything with your text
}
如果 Listener
需要 Context
,请使用 getActivity()
或 getContext()
而不是 DisplayTextEntryAlert.this
mListener.onYesButtonClicked(getActivity());
还有一件事,您在膨胀视图时不必检查 instance of
。因为我看到你的layout里面不仅有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;
}
所以,您在 onAttach(Content context) 上使用的问题是在 23 API 版本(Android 6)中添加的,它从不调用较低的 API 版本。您应该同时覆盖 onAttach(Context context) 和 onAttach(Activity activity)
所以诀窍是使用 setFragment。这现在有效
DisplayTextEntryAlert displayTextEntryAlertFragment = DisplayTextEntryAlert.newInstance("","Enter the first name");
displayTextEntryAlertFragment.setTargetFragment(this, 0);
displayTextEntryAlertFragment.show(getActivity().getSupportFragmentManager(), "newFriendFragment");