Почему виджет EditText должен создаваться в методе фрагмента onStart - PullRequest
0 голосов
/ 07 сентября 2018

Исправляя ошибку, которую я представил при рефакторинге вручную, я обнаружил, что поместил этот код в метод onCreateView фрагмента вместо onStart

    EditText et = getActivity().findViewById(R.id.testEditText);
    et.setOnEditorActionListener(new TextView.OnEditorActionListener()
    {
        @Override
        public boolean onEditorAction(TextView textView, int actionId, KeyEvent event)
        {

            boolean handled = false;

            if (actionId == EditorInfo.IME_ACTION_DONE)
            {
                // Do something.
                handled = true;
            }

            return handled;
        }
    });

Исправив ошибку, я обнаружил, что размышляю над тем, почему виджет EditText в null в onCreateView, и я не знаю ответа. Я никогда не задумывался об этом раньше, поэтому я гуглил и проверил руководства, но не могу найти ответ, так может кто-нибудь сказать мне, почему?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Причиной этого может быть то, что onCreateView () вызова вызван перед onActivityCreated() обратным вызовом, который получает фрагмент, когда возвращается onCreate() родительской активности. Следовательно, getActivity() возвращает ноль в onCreateView(), тогда как работает в onStart(), который вызывается после обратного вызова onActivityCreated().

0 голосов
/ 07 сентября 2018

Ответ связан с тем, как соотносятся жизненный цикл Fragment и его хостинг Activity.

В коде, который вы разместили, вы ищете EditText внутри действия:

EditText et = getActivity().findViewById(R.id.testEditText);

Это логически нормально, но зависит от двух вещей. Во-первых, действие должно существовать, иначе getActivity() вернет ноль. Во-вторых, у действия должен быть вызван метод setContentView(), иначе findViewById() вернет ноль.

Внутри фрагмента onCreateView() мы знаем, что действие уже прикреплено, поэтому первая проблема в порядке. Тем не менее, нет никакой гарантии, что метод действия onCreate() будет завершен, и поэтому нет гарантии, что setContentView() был вызван.

Первое место в жизненном цикле фрагмента, где его хостинг имеет гарантированное завершение выполнения onCreate(), - это обратный вызов onActivityCreated() фрагмента. Все, что зависит от полностью «работающего» действия, должно быть здесь.

0 голосов
/ 07 сентября 2018

Инициализация должна происходить в методе onCreateView, а не в onStart.

Неправильный способ инициализации.

Правильный способ инициализации во фрагменте:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
     Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.example_layout, parent, false);
    EditText et = (EditText) view.findViewById(R.id.editText1);

    et.setOnEditorActionListener(new TextView.OnEditorActionListener()
    {....}

}
...