What is the difference between the two following approaches of having an action bar in an Activity?
Manually use Toolbar
Set the app's theme to Theme.AppCompat.NoActionBar and then include a Toolbar manually into the layout like this:
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/toolbar" />
In code then use AppCompatActivity's setSupportActionBar() method to use the toolbar.
Use a theme with action bar
Set the app theme to Theme.AppCompat.Light.DarkActionBar (or any other theme with action bar) and don't include a separate Toolbar into the layout. In the debugger I can see that the resulting action bar is an android.support.v7.app.WindowDecorActionBar. Checking the source code of it, I find that it at least "knows" about Toolbar.
My questions are:
In both cases I can use the Activity's callbacks to populate the actions, to get information about a tapped action/option etc. Also the visual appearance seems to be identical. Which makes me wonder...
What is the correct approach?
Is the theme based approach also using the Toolbar or is it something else?
Advantages of either approach?
Related
I have a simple app with just one activity. I'm trying to hide the navigation bar from the landscape version of the main activity's layout file.
I tried to find the specific attribute in AppCompat theme and create a custom style that would hide the bar from my layout but haven't found anything matching my goal. I know that it can be done in my activity's class code but I wonder if this is possible to set up in the layout file.
No way, you can hide navigation bar from swipe gesture in setting device.
I'm trying to add the edge-to-edge stuff for the gesture navigation bar to the Tip Time app from Google. I added the transparent navigationBarColor XML tag to themes.xml as well as the following code to the onCreate() function of MainActivity.kt:
This was directly copy-pasted from the documentation. Android Studio says that "it cannot find a parameter with this name" for each of the three margins. I noticed that changing the parenthesis right after <ViewGroup.MarginLayoutParams> to curly braces fixes the compiler error. Maybe the documentation is just wrong?
Anyways, even after fixing that, the app still doesn't look right:
As you can see, the entire view gets shifted up slightly and the "Cost of Service" TextView is partially cut-off by the app bar. What would I need to change to implement the system/navigation bar insets for edge-to-edge content so the UI looks nice? Also, as a side-question, how can I change the dark blue color of the system status bar to match the color of the app bar so that they look blended?
As per documentation for edge to edge contents:
Draw behind the status bar if it makes sense for your content and
layout, such as in the case of full-width imagery. To do this, use
APIs such as AppBarLayout, which defines an app bar pinned to the top
of the screen.
So, while handing the window insets (especially the top one), you can't use the default ActionBar, instead you need to customize that with AppBarLayout and ToolBar, and to make it act as the ActionBar, use setSupportActionBar(), and a NoActionBar app theme; it'd be <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.NoActionBar"> in the shared repo.
the entire view gets shifted up slightly and the "Cost of Service" text field is partially cut-off by the app bar.
The reason that the sample uses the default ActionBar instead of a customized one; when it comes to handle the top window insets, it won't affect the default ActionBar; notice that you pass in the activity's root layout to setOnApplyWindowInsetsListener callback, and as the ActionBar is not a part of the activity, it won't be affected. Therefore the activity is shifted up behind the ActionBar when the top inset is removed. So, to solve this you have either to totally remove the default ActionBar or to use a custom toolbar instead.
Also, as a side-question, how can I change the dark blue color of the system status bar to match the color of the app bar so that they look blended?
Use a transparent status bar color in the app's theme:
<item name="android:statusBarColor" tools:targetApi="l">#android:color/transparent</item>
If there is a toolbar, it is usually passed into setSupportActionBar(). Why?
As per docs
A Toolbar is a generalization of action bars for use within application layouts. While an action bar is traditionally part of an Activity's opaque window decor controlled by the framework, a Toolbar may be placed at any arbitrary level of nesting within a view hierarchy. An application may choose to designate a Toolbar as the action bar for an Activity using the setActionBar() method.
But in simple ways, this is a way of telling the Activity that you are interested in using the features related to Toolbar. It will delegate the functionalities related to your defined toolbar. It helps activity to understand the many of the requirements some of them mentioned below.
1) Setting menu options
2) Setting Navigation drawer
3) Setting common Toolbar
4) Setting back button on the top left
5) Using an icon for brand identification
6) Setting a common title or subtitle
7) And many more
If you don't mention for these functionalities by telling the activity using setSupportActionBar then you have to create all this by your self and support them back to the older version. With Toolbar it comes free and you have to just tell a activity to use it will take of supporting different functionalities itself.
if you want to apply your custom toolbar instead of default toolbar then to set toolbar into that specific screen/activity you must be use setSupportActionBar() along with your toolbar. ;)
I have a library project providing a few activities. Some are immersive, and I need the action bar to be created. On the other hand, the clients using the library must be able to customize its theme (mainly the colors).
One of my clients is using the Theme.AppCompat.Light.NoActionBar theme, which removes the action bar from my activities.
Is there a way to ensure that the action bar will be shown (so, my activities' themes have to inherit from Theme.AppCompat.Light.DarkActionBar), while leaving the colors customizable?
Programmatically creating the action bar would be fine, but I'm not sure that this is possible, right?
EDIT: It works if my client declare the library's activities in their manifest, and set a DarkActionBar theme on each. But I'd really prefer to avoid that solution, as currently they don't have to declare our activities thanks to the manifest merger.
I'm in the process of migrating an app from AppCompat-v20 to AppCompat-v21. As part of that process, I'm trying to move away from the Action Bar, and replace it with a Toolbar so we can take advantage of all the new Material design goodness.
Previously, we had defined all of the information about the AB's displayOptions in a style, and then we set that style as the actionBarStyle in the Activity's theme. However, now that I'm extending Theme.AppCompat.NoActionBar those properties aren't respected anymore, which makes sense, because my theme extends Theme.AppCompat.NoActionBar. At the same time, I would still like to have those displayOptions be applied in the same places they were before (i.e. I'd like to be able to specify whether I want to use a logo or show home as part of the theme).
I know I can probably do this by putting displayOptions onto the theme and parsing them myself, but I'm wondering if there's any support within AppCompat for Toolbars to handle this logic automatically.
With the Toolbar what you have to remember is that it is basically just a view group so you can customize it a lot easier and more so than you could with the ActionBar. That being said, you can use styles to alter the appearance of the Toolbar however there are methods for settings things like title/logo/navigation.
Here's an example of styling your Toolbar:
<android.support.v7.widget.Toolbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.ActionBar" />
If you are using ActionBarActivities and Fragments then you can call the following to let Android know to use your Toolbar as the supportActionBar. This means that all of your calls to getSupportActionBar() will still be valid.
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
The new Material Design guidelines have started to move away from using Logos but if you insist on settings one you can like so:
toolbar.setLogo();
Your question was slightly vague so for more info checkout this post by Chris Banes and Nick Butcher and then the documentation.