Почему «findViewById» возвращает null в методе oncreate для Android?

#android

#Android

Вопрос:

Я просмотрел ответы на stackoverflow для этого вопроса для новичков Android, но я не могу понять, каково оптимальное решение.

Я пытаюсь создать простое действие (с фрагментом), в котором есть пара текстовых полей и кнопка. Когда кнопка нажата, я бы хотел, чтобы кнопка что-то делала!

Итак, у меня есть мой класс MainActivity вместе с его фрагментом кода. Я пытаюсь правильно установить «OnClickListener» для моего объекта button.

Когда я делаю это в методе «onCreate» в самом activity, он выдает исключение nullpointerexception — я предполагаю, это потому, что сама кнопка еще не создана. Однако помещение этого кода в метод OnStart приведет к тому, что он будет вызываться снова и снова и кажется неуместным.

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

Я довольно сильно застрял, и это кажется чем-то простым.

Сценарий # 1: попытка инициировать его в методе onCreate (:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_made_my_day);

////////////////////// PROBLEM IS HERE //////////////////////////////////
    Button butLogin = (Button) findViewById(R.id.but_login);
    butLogin.setOnClickListener(butLogin_OnClickListener);

///////////

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }
}
  

Версия 2 — Фрагмент кода, также не работает:

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

        Button butLogin = (Button) rootView.findViewById(R.id.but_login);
        butLogin.setOnClickListener(butLogin_OnClickListener);

        return rootView;
    }
  

Комментарии:

1. опубликуйте фрагмент кода, в частности, ту часть о намерении, которую вы не можете использовать

2. Публикуя фрагмент кода, это не дубликат, потому что я прочитал другие подобные вопросы в stackoverflow перед публикацией

3. Обратите внимание: что касается вопроса, на который ссылались выше в этой теме — он предлагает переместить код в раздел «onCreateView», что я уже сделал, и у меня все еще возникают проблемы. это не дубликат

Ответ №1:

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

 Intent intent = new Intent(getActivity(), ActivityToCall.class);
getActivity().startActivity(intent);
  

Во-вторых, but_login кнопка на самом деле находится в activity_made_my_day.xml или в fragment_made_my_day.xml ? В зависимости от чего, это то место, где вы должны использовать findViewById() (activity или fragment).

Комментарии:

1. @rockit Хорошо, тогда ваш фрагмент кода верен. Вы должны иметь возможность использовать getActivity().startActivity(intent) в коде прослушивателя кликов.

2. Когда я делаю это, я все еще получаю сообщение об ошибке «на mademyday нельзя ссылаться из статического контекста» в строке «Намерение intentSmileActivity = новое намерение (MadeMyDay.this, SmileListActivity.class ); » внутри фрагмента

3. Вам просто нужно Context для первого параметра. Используйте new Intent(getActivity(), SmileListActivity.class)

4. О! Теперь я вижу. Замените mademyday на «getActivity()», это имеет смысл. И это сработало! Спасибо за объяснение