I want to implement Toolbar something like the following design. It is called flexible toolbar and card toolbar
I tried implementing the custom view inside toolbar. I achieved something like below image!
Now what I did is added custom view to Toolbar but I want to implement like first image. I want to create a card like view on tool bar with all those action views.
To achieve that (As per my view) I can create a custom layout and add it over tool bar. Then I should attach another layout below the toolbar.
My question is whether I should do it as what I said or is there any other simpler way I can implement it?
You should use 2 ToolBars - One for the "ActionBar" and one for the CardView
<FrameLayout>
<ToolBar /> //the Actionbar ToolBar
<CardView layout_marginTop="?attr/actionBarSize">
<ToolBar /> //the Toolbar with the Menu items
...
</CardView>
</FrameLayout>
Related
I am trying to integrate Collapsing layout with Navigation Advanced example
What I tried?
Added Collapsing bar layout to main_actvity.xml
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
Modified setupBottomNavigationBar() in MainActivity.kt
private fun setupBottomNavigationBar(){
...
controller.observe(this, Observer { navController ->
mainBinding.collapsingToolbarLayout.setupWithNavController(mainBinding.toolbar, navController)
//setupActionBarWithNavController(navController)
})
...
}
Current issue:
Now I have two ActionBars instead of one. Top one have app name as the title, one below shows nothing initially but when navigated to an sub destination only a grey back arrow is shown, no destination label is shown on the actionbar
Anyone who understand this multiple backstack implementation, please help me to get things work with CollapsingToolbarLayout
Update:
Got rid of one action bar as #Manoj suggested in a comment, Now need to fix not appearing of titles in the actionbar
Update 2:
Although the destination labels(titles) are not shown when navigated to sub destinations, but back button is shown.
if the title is not displayed (and that increasing the appbar layout height "works"), just set the isTitleEnabled of the collapsingToolbarLayout to false.
It should fix the problem
I finally figured out why the toolbar title was not shown reason was I have not set enough height for appbar layout, I was using wrap_content so collapsing toolbar layout was covering the toolbar title. Solution was to set appbar layout height to value larger than 64dp. When I increased the appbar layout height, it looks unusually tall. (Forgive me for my lack of understanding of how collapsing toolbar works)
But this was not my intention, I wanted to enable collapsing toolbar for some specific fragments, I was using single activity concepts as navigation architecture component recommends.
As I read in following answers
Having two toolbars and making one transparent when doing fragment transactions.
Having separate toolbar for each fragment
IMHO Both of these are not good solutions if you are using navigation architecture component, there is no value of using navigation architecture component, if you need to manage fragment transactions or toolbars manually.
So for now I have stop using collapsing toolbar.
The proposed practise for the new navigation components were presented at I/O with the following template and proposed philosophy:
One Activity for an App
Activity contains Toolbar and Bottom Navigation Bar
A typical app often has a detail view with a CollapsingToolbar in it. How would one build that under that architecture?
Move Toolbar to each Fragment XML?
Implement the collapsing toolbar programmatically?
Move the detail fragment to its own activity (it may use its own deeplink anyway) and 'break' the philosophy?
A typical app often has a detail view with a CollapsingToolbar in it. How would one build that under that architecture?
Great question! I struggled with this for a bit as well and came to the conclusion that there should be one Activity with a NavHostFragment and, ideally, nothing else. This gives you ultimate flexibility to display (or not display) whatever you need for each screen. Importantly, make sure your theme removes the ActionBar:
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
Which leads to your next question...
Move Toolbar to each Fragment XML?
In my opinion, yup! Everything you'd typically use the ActionBar for can be done via a Toolbar. Here's a quick snippet that shows how a Toolbar can be used to do the most important things you've used ActionBar for in the past (up navigation, title, options menu, etc...):
toolbar.apply {
setNavigationOnClickListener { findNavController().navigateUp() }
setTitle(R.string.toolbar_title)
inflateMenu(R.menu.fragment_menu)
setOnMenuItemClickListener(::onMenuItemClick)
}
Implement the collapsing toolbar programmatically?
It depends on what exactly you are trying to do, but most likely, there's no need for that. You can drop an AppBarLayout, CollapsingToolbarLayout, and Toolbar into your layout and use them just like normal. Give your AppBarLayout an ActionBar theme overlay. Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="#color/primary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:navigationIcon="#drawable/ic_up_white"/>
...
Move the detail fragment to its own activity (it may use its own deeplink anyway) and 'break' the philosophy?
No need for that with the above, right? It's an approach that's flexible enough to accommodate multiple levels easily in one nav graph and still be able to customize the appearance and behavior of every destination in the graph (including ActionBar-like functionality).
try
appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
if(expandToolbar){
appBarLayout.setExpanded(true,true);
}else{
appBarLayout.setExpanded(false,true);
}
Here is a usufal link
disable expand on CollapsingToolbarLayout for certain fragments
also for other people inteasing of changing some parts of their toolBar
you should write your custom toolbar view in separate XML and try to inflate the custom view in your details Fragment grammatically then hide the unused elements
of the old toolbar if there are any.
setSupportActionBar(toolbar);
View logo = getLayoutInflater().inflate(R.layout.view_logo, null);
toolbar.addView(logo);
and here is how u can hide unwanted Views
for (int i = 0; i < toolbar.getChildCount(); ++i) {
View child = toolbar.getChildAt(i);
// here u can hide all text views for example.
if (child instanceof TextView) {
child.setVisibility(View.GONE );
}
}
this way is a lot better than writing two activities
Let's assume that we have
One Activity for an App
Activity contains Toolbar and Bottom Navigation Bar
All possible appearances for the toolbar that you need for your app should be implemented in that single toolbar and controllable be the currently active fragment.
Not to violate the Dependency inversion principle all Fragments that need a feature from the activity's toolbar must implement an interface. You could use the OnBackStackChangedListener to check for updates of the view
getFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
Fragment visibleFragment = ...
if(visibleFragment instanceof ToolbarControlFragment) {
if(visibleFragment.shouldExpandToolbar()) {
// set AppBarLayout expanded state
}
// ...
}
}
}
);
You maybe remember that principle when a Fragment requires an OptionsMenu.
I would generally recommend having only one Bottom Navigation Bar controlled by an activity and several Toolbars in Fragments. This reduces complexity and makes components of the app more independent.
I have just started migration to material theme using support library 23.1.
I have looked up the guides and all revolve around the following procedure..
1.Use theme without ActionBar provided by decor. I.e.
<style name="MyTheme" parent="Theme.AppCompat">
...
</style>
2.Put a Toolbar widget somewhere in activity layout xml:
<android.support.v7.widget.Toolbar
android:id=”#+id/myToolbar”
android:layout_height=”wrap_content”
android:layout_width=”match_parent”
android:minHeight=”?attr/actionBarSize”
android:background=”?attr/colorPrimary” />
3.In code set this toolbar as an action bar:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
}
The problem is that some of my activities use FrameLayout as a root layout and as a consequence a toolbar is placed on top of the screen and overlays existing content and therefore hides it.
One workaround would be to create vertically oriented LinearLayout and put Toolbar and FrameLayout as it's children. But, this ads complexity, another level of Views and affects performance.
My first question would be how does mechanism of setSupportActionBar(toolbar) works? Does it takes the toolbar out of its place as set in xml layout and reinserts it at the top of containing layout. Or it just leaves it there where it is?
And the main point, is it possible to use the new Toolbar as decor provided ActionBar? Leave my code unchanged and it will automagically use Toolbar instead of ActionBar? Is it possible to achieve this?
EDIT - UPDATE:
If I leave my code unchanged as if I want to leave the old ActionBar the menu in not instantiated.
EDIT - UPDATE
As far as I could gather there is no way to persuade android to create Toolbar instead of action bar. This sadly means refactoring of all activities and adding another outer enclosing Layout thereby needlessly increasing complexity.
First question: How does the setSupportActionBar(toolbar) works?
What the above statement does is make the toolbar act like an ActionBar. By default the toolbar does not have action bar capabilities, and to make the toolbar act like an action bar, you need this statement. The followin is the official documentation of this method.
Set a Toolbar to act as the ActionBar for this Activity window.
When set to a non-null value the getActionBar() method will return an
ActionBar object that can be used to control the given toolbar as if
it were a traditional window decor action bar. The toolbar's menu will
be populated with the Activity's options menu and the navigation
button will be wired through the standard home menu select action.
setSupportActionBar replaces the decor action bar with the toolbar that you are supplying as a view in the activity. This means that unlike action bar, toolbar will live as a view in your activity. It doesn't take the toolbar out of the layout and reinserts it at the top of containing layout. This means that you can have the toolbar anywhere you want in the screen, not necessarily at the top.
Second Question: Leave my code unchanged and it will automagically use Toolbar instead of ActionBar?
No, you can't do this. Toolbar has to be present in your layout, (either via xml or inflated via code). This is the whole purpose of the toolbar. With action bar you don't have this control. Toolbar allows you to modify it as much as possible and you can a different one in different activity. So how do you do it? What's the best practice?
Well, it's recommended that all activities have an accompanying fragment. So you could have a common layout for all activities (like the one below). Now, you could just inflate the fragment in the FrameLayout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<FrameLayout
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
of course you don't have to add the toolBar if you don't want to (but you will lost some of the cool navigation patterns the toolbar is involved at).
Just make your activity extend a theme with toolbar and you will find it there where its supposed to be.
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
Then in your activity you will be able to get ActionBar instance as usual:
ActionBar actionBar = getSupportActionBar();
I basically want to add a menu button to the far left of my action bar; like it does in the navigation drawer layout:
There must be an easy way to do this, all of the tutorials I am reading seem far to complicated for something that is already available for a application template.
Simplest solution: create a custom toolbar
Add a imageview and a textview to it.
<toolbar ...>
<imageview... /><--your image-->
</toolbar>
Or you can change Activity icon.
getActionBar().setIcon(R.drawable.my_icon);
How to add a custom view top the android navigation bar like above image. when user click on the action bar need to push the main content down and add the custom layout top of the action bar.please how to accomplish this any one suggest a solution
Thanks
Rahul
An easy solution would be to use those views in the actual ActionBar like this: http://developer.android.com/guide/topics/ui/actionbar.html#ActionView. And then take all your layouts and put them inside a RelativeLayout and set their android:layout_below="" to a layout that corresponds to the ActionBar you want to use. So in a step by step way:
Create an action_bar.xml that has the items you want your actionbar to have (ImageViews or Buttons, w/e)
Include this layout in all the Layouts you will use (or in your main layout if you're using Fragments to display content).Like this:
<include layout="#layout/action_bar"
android:id="#+id/action_bar"
android: ... />
Make your Layout position itself below this layout (Using a FrameLayout for example)
<FrameLayout
android:id="#+id/content_frame"
android:layout_below="#+id/action_bar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
Include the ActionViews (Spinner and tabs) in the ActionBar like it's taught in the link up there.