2016-02-19 5 views
0

Я пытаюсь установить текст для своего текстового просмотра каждый раз, когда я обновляю пользовательский интерфейс.Установить текст textview возвращает null в коде Android

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()); 
} 

}

Это где я пытаюсь установить текст для моего TextView. Однако 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); 
    } 
} 

Это мой StackTrace:

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$1.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) 
+0

hola David, por favor postea el logcat –

+0

Можете ли вы предоставить трассировку стека исключений? –

+1

Одним из наиболее важных навыков программиста Java является обнаружение ошибок и их устранение. Самый важный инструмент, который поможет вам в этом, - вызов stacktrace. Он дает имя файла и номер строки, где происходит ошибка. –

ответ

1

Проблема эта линия:

CourseDetailsFragment.getInstance().updateUI(courseData); 

Дело в том, ваш @butterknife.Bind аннотированный TextView не останется нулевой до вызова ButterKnife.bind(this, view). Чтобы выполнить этот вызов, вам нужен действительный родитель вашей иерархии представлений, который вы можете получить не раньше, чем когда вызывается метод жизненного цикла onCreateView, поэтому TextView имеет значение null до onCreateView. Теперь onCreateView вызывается после onCreate, который, в свою очередь, вызывается после onAttach, который запускается путем присоединения фрагмента к Activity, обычно с использованием FragmentManager. Вызов CourseDetailsFragment.getInstance().updateUI(courseData) не автоматически запускать жизненный цикл фрагмента, он только инициализирует экземпляр Fragment, а также до тех пор, что Fragment не присоединен к Activity и onCreateView называется, ваш courseName является пустой ссылкой, что означает, что вызов метода updateUi сразу после создания Fragment обречен на получение исключения с нулевым указателем.

Единственный вариант, с которым эта строка кода работает без исключения исключения, - это то, что этот Fragment был ранее создан, присоединен к действию и прошел через метод onCreateView.

По причинам, описанным выше, я не рекомендую внедрять фрагменты как одиночные, особенно если вы хотите сделать прямые вызовы ссылкой на такой фрагмент из других компонентов. Из-за жизненных циклов действия и фрагменты являются государственными машинами на практике, и ваш метод updateUi не учитывает это состояние, которое является корнем вашей проблемы.

Для быстро исправить, вы можете переопределить метод onFragmentsResumed в вашем Activity - если фрагмент ранее был присоединен, ваши ссылки должны быть действительны в этой точке.