NullPointerException – доступ к представлениям в onCreate ()

Это канонический вопрос для проблемы, часто заданной в StackOverflow.

Я следую учебнику. Я создал новое действие с помощью мастера. Я получаю NullPointerException при попытке вызвать метод в View s, полученный с findViewById() в моей активности onCreate() .

Активность onCreate() :

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); View something = findViewById(R.id.something); something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } } 

Макет XML ( fragment_main.xml ):

    

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

Представление находится в макете fragmentа ( fragment_main.xml ), а не в макете activity_main.xml ( activity_main.xml ). onCreate() слишком рано на жизненном цикле, чтобы найти его в иерархии onCreate() деятельности, и возвращается null . Вызов метода с null вызывает NPE.

Предпочтительным решением является переместить код в fragment onCreateView() , вызывая findViewById() на раздутом fragmentах rootView :

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); View something = rootView.findViewById(R.id.something); // not activity findViewById() something.setOnClickListener(new View.OnClickListener() { ... }); return rootView; } 

В качестве дополнительной заметки макет fragmentа в конечном итоге станет частью иерархии видов деятельности и обнаруживается с помощью операции findViewById() но только после выполнения транзакции fragmentа. Незавершенные транзакции fragmentов выполняются в super.onStart() после onCreate() .

Попробуйте метод OnStart() и просто используйте

 View view = getView().findViewById(R.id.something); 

или Объявить любой вид с помощью getView().findViewById Метод getView().findViewById в onStart()

Объявите прослушиватель кликов в представлении anyView.setOnClickListener(this);

Попытайтесь переместить свои просмотры доступа методу fragmentа onViewCreated, потому что иногда, когда вы пытаетесь получить доступ к представлениям в методе onCreate, они не отображаются в момент возникновения исключения null-указателя.

  @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); View something = findViewById(R.id.something); something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } } 

Согласитесь, это типичная ошибка, потому что люди часто не понимают, как работают Фрагменты, когда они начинают работать над разработкой Android. Чтобы облегчить путаницу, я создал простой примерный код, который я изначально разместил в приложении, остановлен в эмуляторе Android , но я также разместил его здесь.

Примером может служить следующее:

 public class ContainerActivity extends FragmentActivity implements ExampleFragment.Callback { @Override public void onCreate(Bundle saveInstanceState) { super.onCreate(saveInstanceState); this.setContentView(R.layout.activity_container); if (saveInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.activity_container_container, new ExampleFragment()) .addToBackStack(null) .commit(); } getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() { public void onBackStackChanged() { int backCount = getSupportFragmentManager().getBackStackEntryCount(); if (backCount == 0) { finish(); } } }); } @Override public void exampleFragmentCallback() { Toast.makeText(this, "Hello!", Toast.LENGTH_LONG).show(); } } 

activity_container.xml:

     

ExampleFragment:

 public class ExampleFragment extends Fragment implements View.OnClickListener { public static interface Callback { void exampleFragmentCallback(); } private Button btnOne; private Button btnTwo; private Button btnThree; private Callback callback; @Override public void onAttach(Activity activity) { super.onAttach(activity); try { this.callback = (Callback) activity; } catch (ClassCastException e) { Log.e(this.getClass().getSimpleName(), "Activity must implement Callback interface.", e); throw e; } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_example, container, false); btnOne = (Button) rootView.findViewById(R.id.example_button_one); btnTwo = (Button) rootView.findViewById(R.id.example_button_two); btnThree = (Button) rootView.findViewById(R.id.example_button_three); btnOne.setOnClickListener(this); btnTwo.setOnClickListener(this); btnThree.setOnClickListener(this); return rootView; } @Override public void onClick(View v) { if (btnOne == v) { Toast.makeText(getActivity(), "One.", Toast.LENGTH_LONG).show(); } else if (btnTwo == v) { Toast.makeText(getActivity(), "Two.", Toast.LENGTH_LONG).show(); } else if (btnThree == v) { callback.exampleFragmentCallback(); } } } 

fragment_example.xml:

       

И это должен быть верный пример, он показывает, как вы можете использовать Activity для отображения fragmentа и обрабатывать события в этом fragmentе. А также, как общаться с содержащейся активностью.

Представление «что-то» находится в fragmentе, а не в активности, поэтому вместо доступа к нему в действии вы должны получить к нему доступ в classе fragmentов, например

В PlaceholderFragment.class

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_main, container, false); View something = root .findViewById(R.id.something); something.setOnClickListener(new View.OnClickListener() { ... }); return root; } 

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

Добавьте в свой файл activity_main.xml следующее:

   

Поскольку вы объявили свой вид в onCreateView() fragment_main.xml , переместите этот fragment кода, где вы получаете NPE в onCreateView() fragmentа. Это должно решить проблему.

в распространенном выше коде в вопросе возникает проблема: вы используете R.layout.activity_main в методе oncreate, но имя файла xml – «fragment_main.xml», означает, что вы пытаетесь получить представление файла fragment_main.xml который не отображается, поэтому он дает исключение с помощью исключающего указателя. измените код следующим образом:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main);// your xml layout ,where the views are View something = findViewById(R.id.something); something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } } 

Вы должны помнить, что важно следующее: NullPointerException возникает, когда вы объявили свою переменную и пытаетесь вернуть ее значение, прежде чем назначать ему значение.

Используйте метод onViewCreated () всякий раз, когда вы используете или вызываете представления из fragmentов.

 override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) View v = view.findViewById(R.id.whatever) } 

У меня есть тот же NullPointerException инициализирующий слушателя после вызова методов findViewById() onCreate() и onCreateView() .

Но когда я использовал onActivityCreated(Bundle savedInstanceState) {...} он работает. Таким образом, я мог получить доступ к GroupView и установить свой прослушиватель.

Надеюсь, это будет полезно.

Самая популярная библиотека для поиска просмотров, которая используется почти каждым разработчиком.

Нож для масла

Как я могу их, достаточно ответов, объясняющих поиск взглядов с помощью правильной методологии. Но если вы разработчик Android и код часто на ежедневной основе, то вы можете использовать масляный нож, который экономит много времени на поиск взглядов, и у вас нет кода для записи. С помощью 2-3 шагов вы можете просматривать просмотры в миллисекундах ,

Добавить зависимость в графе уровня приложения:

 implementation 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' 

Добавить плагин для масляного ножа:

 File -> Settings -> plugins-> 

Затем найдите Android ButterKnife Zelezny и установите плагин и перезапустите свою студию, и вы закончите с ней.

Теперь просто перейдите в метод Oncreate вашей деятельности и щелкните правой кнопкой мыши на своем макете имя и нажмите на кнопку генерации и выберите вариант инъекции butterknife, и ваши ссылки будут автоматически создаваться, как указано ниже:

  @BindView(R.id.rv_featured_artist) ViewPager rvFeaturedArtist; @BindView(R.id.indicator) PageIndicator indicator; @BindView(R.id.rv_artist) RecyclerView rvArtist; @BindView(R.id.nsv) NestedScrollingView nsv; @BindView(R.id.btn_filter) Button btnFilter; 
  • Как ограничить пропускную способность в Java?
  • Почему значение 09 слишком велико для целого числа?
  • Изменение размера изображения до полной ширины и фиксированной высоты с помощью Picasso
  • Не удалось выполнить dex: несколько файлов dex определяют
  • Можно ли использовать Java 8 для разработки Android?
  • конкатенация строки и чисел Java
  • Попытка реализовать текстовую игру Hangman в Java
  • Доступны ли значения, определенные в MANIFEST.MF программно?
  • Создать папку в Android
  • Как изменить стиль TextView во время выполнения
  • java.lang.NullPointerException: попытка вызвать виртуальный метод для ссылки на нулевой объект
  • Давайте будем гением компьютера.