Предыдущий фрагмент onCreateOptionMenu вызывается при загрузке нового фрагмента
В моем mainActivity
я определил ящик и заменит mainActivity
макет ограничения с выбранным элементом в ящике (как фрагмент).
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
/**
* Perform logout logic if logout is selected, otherwise go display corresponding screen
*/
if (id == R.id.nav_logout) {
logout(null, true);
} else {
switch(id) {
case R.id.nav_event:
fragment = new EventDashboard();
Log.d(logTag, "showing Event screen " + fragment.toString());
fragmentTag = "event";
break;
case R.id.nav_contacts:
fragment = new Contacts();
Log.d(logTag, "showing Contact screen " + fragment.toString());
fragmentTag = "contacts";
break;
}
if (fragment != null) {
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_main, fragment, fragmentTag);
ft.commit();
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
return true;
}
В этом фрагменте EventDashboard, UpComing Event & Past Event, есть две вкладки (SectionPagerAdapter), и я могу без проблем пролистывать их между каждой вкладкой. А контакт - это просто простая раскладка с информацией о пользователе.
Этот код работал без проблем, до недавнего времени я добавлял searchView на страницу событий.
searchView
был добавлен к EventDashboard
фрагмент через onCreateOptionMenu
public class EventDashboard extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
/**
* Enable option menu
*/
setHasOptionsMenu(true);
return inflater.inflate(R.layout.fragment_event, container, false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
//super.onCreateOptionsMenu(menu, inflater);
/**
* Inflate menu
*/
inflater.inflate(R.menu.event_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
...
}
И в обоих EventTabUpComing
а также EventTabPast
фрагменты, у меня есть следующий код:
public class EventTabUpcoming extends Fragment implements SearchView.OnQueryTextListener {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.event_tab_upcoming, container, false);
Log.d(logTag, "Showing Up-Coming events");
sectionAdapter = new SectionedRecyclerViewAdapter();
Log.i(logTag, "create recyclerView");
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.listUpcomingEvent);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(sectionAdapter);
setHasOptionsMenu(true);
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
/**
* Inflate menu
*/
MenuItem item = menu.findItem(R.id.action_event_search);
searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
}
EventTabPast
имеет очень похожий код, за исключением того, что данные, которые он показывает, отличаются. Кнопка поиска работает просто отлично, я могу отфильтровать любое событие без проблем в каждой вкладке.
Теперь проблема заключается в том, как только я проведу по другой вкладке в EventDashboard
фрагмент, а затем выберите контакт из ящика, теперь он генерирует исключение, как показано ниже, который я не понимаю, в то время как текущий фрагмент заменяется выбранным фрагментом, почему он пытается вызвать onCreateOptionMenu
из предыдущего фрагмента. Странно то, что, если я не проведу пальцем по другой вкладке в EventDashboard
фрагмент, переключиться на фрагмент контакта не будет проблем.
Вот исключение:
2019-02-26 22:49:19.286 21132-21132/com.myapp.event I/MyApp.MainActivity: Displaying selected screen id: 2131362023
2019-02-26 22:49:19.286 21132-21132/com.myapp.event D/MyApp.MainActivity: Displaying selectedScreen with id 2131362023
2019-02-26 22:49:19.293 21132-21132/com.myapp.event D/MyApp.MainActivity: showing Contact screen Contacts{8d6ec57}
2019-02-26 22:49:19.400 21132-21132/com.myapp.event E/MyApp.Contacts: loading user list and user lookup for the list
2019-02-26 22:49:19.412 21132-21209/com.myapp.event E/MyApp.UserListsRepository: getUsersForList Christmas
2019-02-26 22:49:19.412 21132-21209/com.myapp.event E/MyApp.UserListsLocalDataSource: getUsersForList Christmas
2019-02-26 22:49:19.417 21132-21132/com.myapp.event D/AndroidRuntime: Shutting down VM
--------- beginning of crash
2019-02-26 22:49:19.417 21132-21132/com.myapp.event E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.event, PID: 21132
java.lang.NullPointerException: Attempt to invoke interface method 'android.view.View android.view.MenuItem.getActionView()' on a null object reference
at android.support.v4.view.MenuItemCompat.getActionView(MenuItemCompat.java:188)
at com.myapp.event.Fragments.Events.EventTabPast.onCreateOptionsMenu(EventTabPast.java:94)
at android.support.v4.app.Fragment.performCreateOptionsMenu(Fragment.java:2547)
at android.support.v4.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:3319)
at android.support.v4.app.FragmentController.dispatchCreateOptionsMenu(FragmentController.java:331)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:369)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:94)
at android.support.v7.app.AppCompatDelegateImpl$AppCompatWindowCallback.onCreatePanelMenu(AppCompatDelegateImpl.java:2546)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:94)
at android.support.v7.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:455)
at android.support.v7.app.ToolbarActionBar$1.run(ToolbarActionBar.java:56)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Как показано в трассировке, mainActivity уже загрузил новый фрагмент Contact, но по какой-то причине он также пытается вызвать onCreateOptionMenu. Проблемная строка - EventTabPast.java:94, которая является "searchView = (SearchView) MenuItemCompat.getActionView(item);"
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
/**
* Inflate menu
*/
MenuItem item = menu.findItem(R.id.action_event_search);
searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
}
1 ответ
Всякий раз, когда пишут onCreateOptionMenu() во фрагменте, это означает, что он создает на родительской активности Fragment
Вы пишете ниже код в onResume() фрагмента контакта
@Override
public void onResume()
{
super.onResume();
setHasOptionsMenu(false)
}