在 android 代码中将文本设置为 textview returns null
Set text to textview returns null in android code
每次更新用户界面时,我都试图为我的文本视图设置一个文本。
public class CourseDetailsFragment extends Fragment {
private static final String TAG = "CourseDetailsFragment";
private OnFragmentInteractionListener listener;
private static CourseDetailsFragment instance;
protected @Bind(R.id.courseName)TextView courseName;
Course c;
View view;
public static CourseDetailsFragment getInstance(){
if (instance == null) {
instance = new CourseDetailsFragment();
}
return instance;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
}
@Override
public void onActivityCreated(Bundle savedInstance) {
super.onActivityCreated(savedInstance);
((AppCompatActivity)getActivity()).getSupportActionBar().setLogo(R.drawable.ic_overview);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("Course Detail"); //redundant?
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_course_details, container, false);
ButterKnife.bind(this, view);
return view;
}
public void updateUI(Course cData) {
c = cData
courseName.setText(cData.getName());
}
}
这是我尝试为我的文本视图设置文本的地方。然而 courseName
仍然是 null
.
public void updateUI(Course cData) {
c = cData
courseName.setText(cData.getName());
}
这是调用 updateUI 的地方。
public void onDataEntry(boolean saved, Fragment fragment, String identifier, Object T) {
if (T instanceof Course){
Course courseData = (Course)T;
Log.d(TAG, "onDataEntry: " + courseData.getName() + " " + courseData.getGrade());
CourseDetailsFragment.getInstance().updateUI(courseData);
}
}
这是我的堆栈跟踪:
02-19 17:31:56.317 4689-4689/hsleiden.nl.barometer E/AndroidRuntime: FATAL EXCEPTION: main
Process: hsleiden.nl.barometer, PID: 4689
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at hsleiden.nl.barometer.views.fragment.CourseDetailsFragment.updateUI(CourseDetailsFragment.java:101)
at hsleiden.nl.barometer.views.activity.BaseActivity.onDataEntry(BaseActivity.java:306)
at hsleiden.nl.barometer.adapter.CourseAdapter.onClick(CourseAdapter.java:57)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
问题出在这一行:
CourseDetailsFragment.getInstance().updateUI(courseData);
事实是,您的 @butterknife.Bind
注释 TextView
将保持为空,直到调用 ButterKnife.bind(this, view)
。要进行该调用,您需要视图层次结构的有效父级,您可以在调用 onCreateView
生命周期方法之前获得它,因此 TextView
在 onCreateView
之前为空。现在,onCreateView
在 onCreate
之后调用,后者又在 onAttach
之后调用,这是通过将片段附加到 Activity
触发的,通常是通过使用 FragmentManager
。调用 CourseDetailsFragment.getInstance().updateUI(courseData)
不会自动触发片段生命周期,它只会实例化 Fragment
实例,直到 Fragment
附加到 Activity
并且 onCreateView
是调用,你的 courseName
是一个空引用,这意味着在创建 Fragment
后立即调用 updateUi
方法注定会导致空指针异常。
这行代码可以在不抛出异常的情况下运行的唯一选择是,如果此 Fragment
之前已实例化,附加到 activity 并且它已经通过 onCreateView
方法。
出于上述原因,我不建议将片段实现为单例,尤其是当您想直接调用其他组件对此类片段的引用时。由于生命周期,Activity 和 Fragments 实际上是状态机,您的 updateUi
方法不考虑该状态,这是问题的根源。
为了快速修复,您可以覆盖 Activity
中的 onFragmentsResumed
方法 - 如果片段之前已附加,您的引用应该是有效的那时。
每次更新用户界面时,我都试图为我的文本视图设置一个文本。
public class CourseDetailsFragment extends Fragment {
private static final String TAG = "CourseDetailsFragment";
private OnFragmentInteractionListener listener;
private static CourseDetailsFragment instance;
protected @Bind(R.id.courseName)TextView courseName;
Course c;
View view;
public static CourseDetailsFragment getInstance(){
if (instance == null) {
instance = new CourseDetailsFragment();
}
return instance;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
}
@Override
public void onActivityCreated(Bundle savedInstance) {
super.onActivityCreated(savedInstance);
((AppCompatActivity)getActivity()).getSupportActionBar().setLogo(R.drawable.ic_overview);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("Course Detail"); //redundant?
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_course_details, container, false);
ButterKnife.bind(this, view);
return view;
}
public void updateUI(Course cData) {
c = cData
courseName.setText(cData.getName());
}
}
这是我尝试为我的文本视图设置文本的地方。然而 courseName
仍然是 null
.
public void updateUI(Course cData) {
c = cData
courseName.setText(cData.getName());
}
这是调用 updateUI 的地方。
public void onDataEntry(boolean saved, Fragment fragment, String identifier, Object T) {
if (T instanceof Course){
Course courseData = (Course)T;
Log.d(TAG, "onDataEntry: " + courseData.getName() + " " + courseData.getGrade());
CourseDetailsFragment.getInstance().updateUI(courseData);
}
}
这是我的堆栈跟踪:
02-19 17:31:56.317 4689-4689/hsleiden.nl.barometer E/AndroidRuntime: FATAL EXCEPTION: main
Process: hsleiden.nl.barometer, PID: 4689
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at hsleiden.nl.barometer.views.fragment.CourseDetailsFragment.updateUI(CourseDetailsFragment.java:101)
at hsleiden.nl.barometer.views.activity.BaseActivity.onDataEntry(BaseActivity.java:306)
at hsleiden.nl.barometer.adapter.CourseAdapter.onClick(CourseAdapter.java:57)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
问题出在这一行:
CourseDetailsFragment.getInstance().updateUI(courseData);
事实是,您的 @butterknife.Bind
注释 TextView
将保持为空,直到调用 ButterKnife.bind(this, view)
。要进行该调用,您需要视图层次结构的有效父级,您可以在调用 onCreateView
生命周期方法之前获得它,因此 TextView
在 onCreateView
之前为空。现在,onCreateView
在 onCreate
之后调用,后者又在 onAttach
之后调用,这是通过将片段附加到 Activity
触发的,通常是通过使用 FragmentManager
。调用 CourseDetailsFragment.getInstance().updateUI(courseData)
不会自动触发片段生命周期,它只会实例化 Fragment
实例,直到 Fragment
附加到 Activity
并且 onCreateView
是调用,你的 courseName
是一个空引用,这意味着在创建 Fragment
后立即调用 updateUi
方法注定会导致空指针异常。
这行代码可以在不抛出异常的情况下运行的唯一选择是,如果此 Fragment
之前已实例化,附加到 activity 并且它已经通过 onCreateView
方法。
出于上述原因,我不建议将片段实现为单例,尤其是当您想直接调用其他组件对此类片段的引用时。由于生命周期,Activity 和 Fragments 实际上是状态机,您的 updateUi
方法不考虑该状态,这是问题的根源。
为了快速修复,您可以覆盖 Activity
中的 onFragmentsResumed
方法 - 如果片段之前已附加,您的引用应该是有效的那时。