Android Jetpack Navigation component Condtional navigation issue - android

I was trying to add conditional navigation following this. But I ran into a problem.
So the steps I followed are:
Created navigation drawer in the MainActivity with HomeFragment as a start destination.
Conditionally navigated to FromBlackFragment from BlankFragment.
Want to go to HomeFragment from FromBlackFragment by clicking up/back button.
The problem is with step 3 above. I am going back to HomeFragment by clicking back button whereas I am navigated to BlankFragment on up button click. The code for step 3 is: (inside FromBlackFragment.java file)
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(),
new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
Navigation.findNavController(view).popBackStack(R.id.homeFragment, false);
}
});
The MainActivity.java file:
public class MainActivity extends AppCompatActivity {
private NavController navController;
private DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.my_toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navController = findNavController(this, R.id.nav_host_fragment);
AppBarConfiguration appBarConfiguration =
new AppBarConfiguration.Builder(navController.getGraph())
.setOpenableLayout(drawerLayout).build();
NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
}
}
BlankFragment.java file:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
#Override
public void onViewCreated(#NonNull final View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedPreferences sp = requireActivity().getSharedPreferences("Testing",0);
if(!sp.getBoolean("b",false)){
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("b",true);
editor.apply();
Navigation.findNavController(view).navigate(R.id.fromBlackFragment);
}
}
FromBlackFragment.java file:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_from_black, container, false);
}
#Override
public void onViewCreated(#NonNull final View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(),
new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
Navigation.findNavController(view).popBackStack(R.id.homeFragment, false);
}
});
}
Note: Shared preferences used in the code is not part of the problem.
Please help. Thanks.
Edit: (More specifically the question is) How to sync upNavigation and back button?

Step1: In MainActivity's onCreate, you need to call setSupportActionBar(toolbar);
Step2: Call setupActionBarWithNavController() from NavigationUI, passing in the proper arguments, this will:
Set up the ActionBar returned by
AppCompatActivity.getSupportActionBar() for use with a NavController.
Step3: By calling setupActionBarWithNavController(), you should now override onSupportNavigateUp(), putting in the call to navigate:
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp();
}
If NavigationUI.navigateUp won't get you to home fragment destination, you maybe want call a Navigation method that explicitly get you there.

Related

android update navController from button

I started a new app with the default android bottom navigation menu.
In the basic main fragment I added the buttons for all the fragments (I want to show them in the bottom navigation but also in the main fragment.)
Then I added this in HomeFragment to handle on button press to switch fragments:
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
final TextView textView = root.findViewById(R.id.text_home);
homeViewModel.getText().observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
Button btnConnect = (Button) root.findViewById(R.id.btnConnect);
btnConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment = new ConnectFragment();
replaceFragment(fragment);
}
});
Button btnOptions = (Button) root.findViewById(R.id.btnOptions);
btnOptions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment = new OptionsFragment();
replaceFragment(fragment);
}
});
return root;
}
private void replaceFragment(Fragment someFragment) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.nav_host_fragment, someFragment);
transaction.addToBackStack(null);
transaction.commit();
}
Now I am able to switch between the fragments, but the navigation controller isn't being updated, and when I switch from those buttons to another fragment, in the navigation controller at the bottom, the icons are not updated, and t looks like I am still on the home fragment.
this is the code inside MainActivity for the navigation controller:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view);
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_options, R.id.navigation_contact)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
}
So what do I need to do, in order to make the navigation controller update the icons wen I switch fragments from the customized buttons and not from the navigation controller menu?
EDIT:
here is an image to clarify:
on the left is the main activity, on the middle is how it looks like when I switch fragment by pressing on the button "CONNECT" from the main activity, and on the right is how it looks like if I press the "connect" button from the menu.
I want that the menu will be updated, even when I press the "CONNECT" button from the main activity, and not only from the menu.
You can use something like this
yourBottomNavigationView.setSelectedItemId(R.id.navigation_contact);
When you click on your Button

BottomNavigationView with NavigationUI and multiple fragments will re-creation

When i change BottomNavigation tab , the fragment will be re-creation.
How to cache the created fragment and not re-creation?
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
bottomNavigationView = view.findViewById(R.id.bottom_navigation);
NavController navController = Navigation.findNavController(getActivity(), R.id.bottom_nav_host_fragment);
NavigationUI.setupWithNavController(bottomNavigationView, navController);
this.initBottomNavigation();
}
private void initBottomNavigation() {
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
NavController navController = Navigation.findNavController(getActivity(), R.id.bottom_nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
}

I am try to create BottomNavigationView with fragment and I want to use fragment in main layout

It can build and run successfully but in virtual device has stopped.
this is the code of my main layout in fragment:
public class BlankFragment14 extends Fragment {
#Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState ) {
return inflater.inflate(R.layout.fragment_blank_fragment14, container, false);
}
#Override
public void onCreate( #Nullable Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
BottomNavigationView bottomNav = getView( ).findViewById(R.id.bottom_navigation);
BottomNavigationView.OnNavigationItemSelectedListener navListener = null;
bottomNav.setOnNavigationItemSelectedListener(navListener);
getFragmentManager( ).beginTransaction( ).replace(R.id.fragment_container1, new ProfileFragment( )).commit( );
navListener = new BottomNavigationView.OnNavigationItemSelectedListener( ) {
#Override
public boolean onNavigationItemSelected( #NonNull MenuItem menuItem ) {
Fragment selectedFragment = null;
switch (menuItem.getItemId( )) {
case R.id.nav_profile1:
selectedFragment = new ProfileFragment( );
break;
case R.id.nav_appointment1:
selectedFragment = new AppointmentFragment( );
break;
case R.id.nav_patientdata1:
selectedFragment = new PatientdataFragment( );
break;
}
getFragmentManager( ).beginTransaction( ).replace(R.id.fragment_container1, selectedFragment).commit( );
return true;
}
};
}
}
I don't know that It can be possible to work ? or I must use activity to be a main layout.
Use Navigation component to implement BottomNavigationView. Your MainActivity must have NavHostFragment, that can display other fragment destinations. In MainActivity's onCreate
setup NavController as shown below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar1);
setSupportActionBar(myToolbar);
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
//NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
}

Navigation component shared element transitions works for enter but not for popping back

I'm trying to use a shared element animation between 2 fragments, BlankFragment and BlankFragment2. BlankFragment has a recycler view and BlankFragment2 is a details screen. They share an image and I'm using the new navigation component.
In BlankFragment I'm building FragmentNavigator.Extras and passing the extras to my call to navigate with the transition name of the shared image (as its a recycler view and these need to be unique),
In BlankFragment2 I'm receiving this name setting it to my image and setting the setSharedElementEnterTransition
The result is that the enter animation works fine but the exit/return doesn't, I've tried setting them and not setting them (because I believe the navigation component should handle this for me) can anyone help?
MainActivity Navigation Setup
private void setNavigation() {
navController = Navigation.findNavController(this, R.id.main_fragment);
NavigationUI.setupActionBarWithNavController(this, navController);
}
Handling back button
#Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.main_fragment).navigateUp()
|| super.onSupportNavigateUp();
}
BlankFragment OnClick
#Override
public void onClick(View view, int position) {
NavController navController = Navigation.findNavController(recyclerView);
FragmentNavigator.Extras extras = new FragmentNavigator.Extras.Builder().addSharedElement(view, view.getTransitionName()).build();
BlankFragmentDirections.ActionBlankFragmentToBlankFragment2 directions = BlankFragmentDirections.actionBlankFragmentToBlankFragment2(view.getTransitionName());
navController.navigate(directions,extras);
}
BlankFragment2 onCreate with return/exit transition
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.no_transition));
setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
getFragmentArguments();
}
Get Arguments Method
private void getFragmentArguments(){
if (getArguments() != null){
transitionName = BlankFragment2Args.fromBundle(getArguments()).getTransitionName();
Log.d(TAG, "transition name " + transitionName);
}
}
Set image transition name
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
image = view.findViewById(R.id.image);
image.setTransitionName(transitionName);
text = view.findViewById(R.id.text);
}
Java
To Fix on return transition, use viewTreeObserver.addOnPreDrawListener
In BlankFragment (fragment with recycle view)
We need to call postponeEnterTransition(); so the transition
will be pospone
Setup addOnPreDrawListener on recycleView as following
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
//setup for recycle view adapter
ViewTreeObserver viewTreeObserver = recyclerView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
startPostponedEnterTransition();
return true;
}
});
That's it.
Follow this link to get more info on ViewTreeObserver follow this link
FIN !!

Manage toolbar's navigation and back button from fragment in android

All of my fragments are controlled through ActionBarActivity (mainActivity), inside mainActivity a DrawerLayout is implemented and all the child fragments are pushed through drawerLayout's list item click. The problem that I'm facing is after pushing a fragment through drawerLayout I want to change the drawer icon into back icon of ToolBar so that user can navigate to previous fragment and to handle the callback of android.R.id.home either inside the same fragment or inside the mainActivity.
The code that I am using is:
MainActivity.java
public class MainActivity extends ActionBarActivity {
private DrawerLayout layoutDrawer;
private ActionBarDrawerToggle drawerToggler;
private Stack<Fragment> stack;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stack = new Stack<Fragment>();
layoutDrawer = (DrawerLayout) findViewById(R.id.layout_drawer);
drawerToggler = new ActionBarDrawerToggle(this, layoutDrawer, toolbar,
R.string.app_name, R.string.app_name);
layoutDrawer.setDrawerListener(drawerToggler);
setUpDrawerList();
pushFragment(new FirstFragment(), true);
Session.setContext(getApplicationContext());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggler.isDrawerIndicatorEnabled()
&& drawerToggler.onOptionsItemSelected(item))
return true;
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "Back from activity", Toast.LENGTH_SHORT)
.show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggler.syncState();
}
#Override
public void onBackPressed() {
popFragment();
}
private void setUpDrawerList() {
ListView listView = (ListView) findViewById(R.id.list_drawer);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
Arrays.asList(new String[] { "First Fragment",
"Second Fragment" }));
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
layoutDrawer.closeDrawers();
drawerToggler.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
pushFragment(getFragment(position), true);
}
});
}
private Fragment getFragment(int pos) {
switch (pos) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
}
return null;
}
public void pushFragment(Fragment fragment, boolean add) {
FragmentTransaction transation = getSupportFragmentManager()
.beginTransaction();
if (add)
stack.push(fragment);
transation.replace(R.id.layout_content, fragment);
transation.commit();
}
public void popFragment() {
if (!stack.isEmpty()) {
Fragment fragment = stack.elementAt(stack.size() - 2);
stack.pop();
pushFragment(fragment, false);
} else
super.onBackPressed();
drawerToggler.setDrawerIndicatorEnabled(stack.size() == 1);
}
public void clearBackStack() {
stack.clear();
}
}
FirstFragment.java
public class FirstFragment extends Fragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
#Override
public void onResume() {
super.onResume();
ActionBar actionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
actionBar.setTitle("First Fragment");
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.fragment_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
Toast.makeText(getActivity(), "Back from fragment", Toast.LENGTH_SHORT).show();
getActivity().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}
From the above code I am not able to get the callback of android.R.id.home and setting home button is not working everytime actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true);
Any help will be really appreciated.
Thanks
Add a toolbar to your xml
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment title"/>
</android.support.v7.widget.Toolbar>
Then inside your onCreateView method in the Fragment:
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_button);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
You have to manage your back button pressed action on your main Activity because your main Activity is container for your fragment.
First, add your all fragment to transaction.addToBackStack(null) and now navigation back button call will be going on main activity. I hope following code will help you...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
you can also use
Fragment fragment =fragmentManager.findFragmentByTag(Constant.TAG);
if(fragment!=null) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment).commit();
}
And to change the title according to fragment name from fragment you can use the following code:
activity.getSupportActionBar().setTitle("Keyword Report Detail");
I have head around lots of solutions and none of them works perfectly. I've used variation of solutions available in my project which is here as below. Please use this code inside class where you are initialising toolbar and drawer layout.
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);// show back button
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
//show hamburger
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerFragment.mDrawerToggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawerFragment.mDrawerLayout.openDrawer(GravityCompat.START);
}
});
}
}
});
Probably the cleanest solution:
abstract class NavigationChildFragment : Fragment() {
abstract fun onCreateChildView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View?
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true)
return onCreateChildView(inflater, container, savedInstanceState)
}
override fun onDestroyView() {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
setHasOptionsMenu(false)
super.onDestroyView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val activity = activity as? MainActivity
return when (item.itemId) {
android.R.id.home -> {
activity?.onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
Just use this class as parent for all Fragments that should support navigation.
You can use Toolbar inside the fragment and it is easy to handle. First add Toolbar to layout of the fragment
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimaryDark">
</android.support.v7.widget.Toolbar>
Inside the onCreateView Method in the fragment you can handle the toolbar like this.
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
IT will set the toolbar,title and the back arrow navigation to toolbar.You can set any icon to setNavigationIcon method.
If you need to trigger any event when click toolbar navigation icon you can use this.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//handle any click event
});
If your activity have navigation drawer you may need to open that when click the navigation back button. you can open that drawer like this.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
Full code is here
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate the layout to the fragement
view = inflater.inflate(R.layout.layout_user,container,false);
//initialize the toolbar
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//open navigation drawer when click navigation back button
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
return view;
}
First you add the Navigation back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Then, add the Method in your HostActivity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==android.R.id.home)
{
super.onBackPressed();
Toast.makeText(this, "OnBAckPressed Works", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
Try this, definitely work.
if you are using androidx fragment and want to go back to MainActivity when back home button is clicked, use the following codes .
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
....
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
requireActivity().onBackPressed();
}
return super.onOptionsItemSelected(item);
}
(Kotlin)
In the activity hosting the fragment(s):
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
I have found that when I add fragments to a project, they show the action bar home button by default, to remove/disable it put this in onViewCreated() (use true to enable it if it is not showing):
val actionBar = this.requireActivity().actionBar
actionBar?.setDisplayHomeAsUpEnabled(false)
The easiest solution I found was to simply put that in your fragment :
androidx.appcompat.widget.Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NavController navController = Navigation.findNavController(getActivity(),
R.id.nav_host_fragment);
navController.navigate(R.id.action_position_to_destination);
}
});
Personnaly I wanted to go to another page but of course you can replace the 2 lines in the onClick method by the action you want to perform.
Generic method in Kotlin which can handle both the title bar back press action as well as navigation bar back press action and can be called from all the fragments is :
fun configureToolbarBackPress(
customToolBar: Toolbar,
parentVw: View,
activity: Activity,
title: String,
targetResId: Int
) {
customToolBar.setNavigationIcon(R.drawable.ic_arrow_back)
customToolBar.title = title
customToolBar.setNavigationOnClickListener {
parentVw.findNavController().navigate(targetResId)
}
(activity as DashboardActivityNew).onBackPressedDispatcher.addCallback(
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
parentVw.findNavController().navigate(targetResId)
}
}
)
}
Now call this method onViewCreated() from any of the fragment as follows :
AppUtils.configureToolbarBackPress(
customToolbar as Toolbar,
view,
requireActivity(),
getString(R.string.title),
R.id.mainFragment
)
Include the toolbar in fragment.xml as follows :
<include
android:id="#+id/customToolbar"
layout="#layout/dashboard_toolbar" />
The layout of dashboard_toolbar.xml is as follows :
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="#dimen/abc_action_bar_default_height_material"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="#color/colorPrimary"/>
OnToolBar there is a navigation icon at left side
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
toolbar.setTitle(getResources().getString(R.string.title_activity_select_event));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
By using this at left side navigation icon appear and on navigation icon click it call parent activity.
and in manifest we can notify system about parent activity.
<activity
android:name=".CategoryCloudSelectActivity"
android:parentActivityName=".EventSelectionActivity"
android:screenOrientation="portrait" />

Categories

Resources