Custom Toolbar for each fragment using Navigation component
I tried to use this method (activity as? AppCompatActivity)?.setSupportActionBar(toolbar) in Fragment but it duplicated toolbar.
This is expected because the toolbar is hosted by the activity, and as Jetpack navigation architecture components uses a single-activity model, then all navGraph fragments hosted by this activity share this toolbar (because it's a part of the activity).
And therefore resetting the toolbar again will duplicate it.
The solution to this is to remove the toolbar from the activity, and use a unique toolbar within every fragment layout, this way when a fragment is transacted to another; the layout of the old fragment is replaced with the new layout of the new fragment, so the old toolbar is gone, and we've a new toolbar; and at this time you need to call setSupportActionBar(toolbar)
for the new toolbar.
But notice that every time you call setSupportActionBar(toolbar)
you have to recall setupActionBarWithNavController()
because it needs to be attached to the new toolbar.
UPDATE
So, I have to call setSupportActionBar(toolbar) and setupActionBarWithNavController() in Fragment?
Actually you can call setSupportActionBar(toolbar)
in the activity. But you can use requireActivity()
in fragment to do that:
In order not to repeat things, you can have a function the activity to do that:
In activity:
fun setupActionBar(toolBar: Toolbar) {
setSupportActionBar(toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
setupActionBarWithNavController(navController)
}
And in fragment:
val toolbar = findViewById<Toolbar>(R.id.foo)
(requireActivity() as MainActivity).setupActionBar(toolbar)
How to put custom toolbar inside fragment?
So this is how I did it. My app is based on single activity-multi-fragment model.
I had set activity theme to AppTheme.NoActionBar
, so it enabled me to set a custom toolbar.
Later for each fragment I had a separate layout and within which added a custom toolbar like below
<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary">
....
....
</androidx.appcompat.widget.Toolbar>
Within this layout I had added menu items.
If you don't want to follow this, may be you should look at getActionBar().setCustomView()
. Keep your activity theme set, so getActionBar()
is not null.
You can control action bar layout by calling getActionBar().setCustomView()
in fragment onResume() or probably when you are adding or removing a fragment in your activity.
Add Toolbar inside fragment (AndroidX)
so what was the successfull answer for me:
Inside onCreate method just add setHasOptionsMenu(true);
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Inside my WallFragment.java in onCreateView I added setOnMenuItemClickListener just right after initializing the Toolbar
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View inflatedView = inflater.inflate(R.layout.fragment_wall, container, false);
TopActivityToolbar = inflatedView.findViewById(R.id.update_wall_page_toolbar);
TopActivityToolbar.setTitle("someTitle");
TopActivityToolbar.inflateMenu(R.menu.menu_app_actionbar_wall);
// and finally set click listener
TopActivityToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// Your code inside Toolbar onClick...
return false;
}
});
return inflatedView;
}
Do not forget to to INFLATE the menu from res/menu/...
Add SearchView to Custom Toolbar in a Fragment
Solved it with adding setSupportActionBar(toolbar)
in onCreateView()
How to add Toolbar to a fragment in android?
Cast your activity from getActivity()
to AppCompatActivity
first. I think this will solve your error:
((AppCompatActivity) getActivity()).getSupportActionBar(toolbar);
Or in your case:
((AppCompatActivity) getActivity()).setSupportActionController(toolbar);
getActivity()
returns a FragmentActivity
and you need to get AppCompatActivity
returned. Hope this helps!
How to get Toolbar from fragment?
You need to cast your activity from getActivity()
to AppCompatActivity
first. Here's an example:
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle();
The reason you have to cast it is because getActivity()
returns a FragmentActivity
and you need an AppCompatActivity
In Kotlin:
(activity as AppCompatActivity).supportActionBar?.title = "My Title"
custom toolbar not visible in fragment
Height of toolbar and other relative layouts are same i.e. android:layout_height="?android:attr/actionBarSize"
That's why there is only Header layout is visible not the search layout because header layout occupying the whole height of the toolbar and search layout is below the header layout.
Change the height of toolbar and you will get the desired result.
Related Topics
Failure Install Parse Failed Manifest Malformed
Add Text to Image in Android Programmatically
Recyclerview Indicates That Reaches the Last Item
How to Know Which Fragment the User Is Viewing
How to Refresh the Fragment After Activity Finished in Android
How to Select Only One Checkbox in Recyclerview and Notifydataset Changed
Android: How to Send an Image as Email Attachment from Application
How to Show Text in Lower Case in Android
Error: Open Failed: Enoent (No Such File or Directory)
How to Change the Default Height of a Bottomsheetdialog
Edittext Background Base Line Color Changing Based on Its Focus in Android
Background Drawable Not Applying to Button
How to Restrict Entry of Numbers But Allow All the Special Characters and Alphabets in Edittext
Videoview to Match Parent Height and Keep Aspect Ratio
Chrome on Android Resizes Font
How to Programmatically Take a Screenshot on Android
Could Not Connect to React Native Development Server on Android