Android Toolbar too high in landscape mode - android

My min and target sdk is 21, and I am not using the support library.
I am using the new Toolbar widget, and generally it works, I just have a glitch in the way it looks. The action icons are centered in portrait mode, whereas the toolbar in landscape mode is higher, and the icons are not centered. Please take a look at the screenshots (read lines are just to make the problem more visible):
portrait:
landscape:
This might look like nothing, but when the actions are selected (like the 'up' arrow at the very left of the bar) the result is that a strip of few pixels below it is visible. I don't like the way it looks.
The activity does not manage any configuration changes itself.
This is my code:
styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme.Material.NoActionBar">
<item name="android:toolbarStyle">#style/MyToolbarStyle</item>
</style>
<style name="MyToolbarStyle" parent="android:Widget.Toolbar">
<item name="android:background">?android:attr/colorPrimary</item>
<item name="android:elevation">2dp</item>
</style>
</resources>
XML usage:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.test.TestActivity">
<Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
I tried messing around with the android:minHeight attribute, but setting to so, say, 30dp just moved the icons even more upwards, also in portrait mode.
I found this: https://code.google.com/p/android/issues/detail?id=77874
But there is no ?attr/actionBarSize...
How, if at all, can this problem be fixed? The phone the screenshots were taken on is a Nexus 6 (xxxhdpi), and the icon is from the google icon pack, and the biggest resource is xxhdpi. Is this the problem?
Update: the workaround from the aforementioned link does work when I use ?android:attr/actionBarSize. But, is this the only way? Seems a bit wrong, to need such workarounds for a new shiny component like this, even more so that the workaround requires an attribute value for a component to be replaced by the new one.

try to use:
android:height="?android:attr/actionBarSize"
for your toolbar.

Add this in your toolbar style:
<item name="maxButtonHeight">?attr/actionBarSize</item>

I had the same problem with android.support.v7.widget.Toolbar.
My solution:
Put your toolbar into a RelativeLayout with the height you want for your toolbar. Set your toolbars layout_height to "wrap_content" and align it to the vertical center. I hope it helps.
<RelativeLayout
android:id="#+id/main_toolbar_relative_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
>
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
>
</android.support.v7.widget.Toolbar>
</RelativeLayout>

Related

Toolbar menu items squeezed after switching to support library 26 and AppBarActivity to AppCompatActivity

Yesterday I switched to new support library 26 and I also had to change the deprecated AppBarActivity to AppCompatActivity since this is not existing anymore.
I'm experiencing the same problem as described in the link below but "clean" or "rebuild" does not fix the issue.
Why option menu items squeezed if I use support library 26?
I'm having all my icons in hdpi and xhdpi. Some also in mdpi and ldpi...
So why do my toolbar icons get squeezed?
Here is the code I use in all my layouts which worked with all previous support libraries (and I'm always using the most recent versions!):
<android.support.design.widget.AppBarLayout
android:id="#+id/myAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/my_awesome_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
</android.support.design.widget.AppBarLayout>
All my icons are defined as attr so that I'm able to provide a light and a dark version.
<item
android:id="#+id/action_logbook"
android:icon="?attr/icon_book"
android:orderInCategory="100"
android:title="#string/logbook"
yourapp:showAsAction="ifRoom"/>
This is the attr in icons.xml
<attr name="icon_book" format="reference"/>
This is the style which provides the actual icon:
<style name="MyBaseThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
<item name="icon_book">#drawable/icon_book_white</item>
</style>
Here is a screenshot from before support version 26.0.0:
and this is after upgrade:
UPDATE:
It is working when I put an ImageView directly in Toolbar:
<android.support.design.widget.AppBarLayout
android:id="#+id/myAppBar"
style="#style/myAppBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/my_awesome_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?attr/bt_expenses" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
UDATE 2:
For me the code change in version 26 of ActionMenuItemView seems to be the problem since it does not resize the icons to keep width and high equal:
See:
public void setIcon(Drawable icon)
...
The workaround seems to use the Image Asset Studio from Android Studio to generate icon resources again. I didn't use that tool before and put the icon image manually in different resolution folders. it seems that com.android.support:appcompat-v7:26.0.0 changed the image resolution, my old hdpi icon was 72x72, the generated icon for hdpi is now 48x48.
See this thread on the Android issue tracker where I explain the bug: https://issuetracker.google.com/issues/64207386. I've also recompiled the library to fix the issue. Attached here: https://issuetracker.google.com/issues/64207386#comment19.
EDIT: The issue is fixed on 26.0.2
These two action bars differ. Minimum height is set from the attributes, but both have a height value set to wrap_content.
The first bar consists a second line with km, which extends height of the App Bar by wrapping both textviews. Icons on the second one are shrinked, because they probably have attributes also set to wrap_content.
Would be better if you showed both App Bars that have the same design and comparison after changing to AppCompatActivity.

How to implement Toolbar Layout

How do I remove the boundary between action and toolbar?
Bad Case
Good Case, I want to like it.
Activity XML
Fragment XML
What you are looking for is a way to remove the shadow under toolbar.
For android 4.4 or below, you will have to set the window content overlay in your activity theme like this
<style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
...
<!--To hide shadow effect in toolbar for Android 4.4 or below-->
<item name="android:windowContentOverlay">#null</item>
</style>
For Android 5.0+, you will also need to set the toolbar elevation to 0 in the activity layout like this.
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
...
>
<android.support.design.widget.AppBarLayout
...
app:elevation="0dp">
...
</android.support.design.widget.AppBarLayout>
</LinearLayout>
Actually, many people ask about this. See answer here
Try to search for existing answer next time ;)

adjustResize not working in lollipop and above with translucent status/Nav

There are questions talking about this problem but I didn't solve mine by existed answers.
This is my styles-v21.xml:
<style name="MainTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:colorBackground">#EEEEEE</item>
</style>
I've set windowSoftInputMethod="adjustResize" for related Activity of course.
Here is my layout.xml, notice that the root FrameLayout is used for specific function thus it is needed:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/rl_background"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--This View is used to fill the space of status bar-->
<View
android:id="#+id/statusbar"
android:layout_width="match_parent"
android:layout_height="#dimen/statusbar_size"/>
<!--I've set this toolbar as Actionbar-->
<android.support.v7.widget.Toolbar
android:id="#+id/actionbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_below="#id/statusbar"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/actionbar">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Two EditTexts inside -->
</RelativeLayout>
</ScrollView>
</RelativeLayout>
</FrameLayout>
When I don't touch the EditText, everything looks fine: status bar View stays where it should be and navigation bar doesn't overlay content(doen't make content invisible but content is under it in fact).
In similar questions, people often teach us to set fitsSystemWindow="true", I did this to different layouts inside my layout.xml and got different results.
Setting fitsSystemWindow="true" in:
1.FrameLayout:
AdjustResize works, but status bar View now stays below the real status bar. Status bar's color turns to windowBackground. Navigation bar became entirely transparent because it shows other fragment's content where this fragment was added.
2.First RelativeLayout:
AdjustResize works, but status bar View was below real status bar.Navigation bar isn't too transparent to show other fragment but overlays content.
3&4.ScrollView&RelativeLayout inside ScrollView:
AdjustResize doesn't work and others are same to condition 2.
I also used a method to write my own FrameLayout like this:https://stackoverflow.com/a/22266717/3952691 but as the author said, setting bottom will cause error. Because I use translucent navigation bar, I also need to draw bottom inset. And I try its upgrade version:https://gist.github.com/romannurik/8919163, no use too.
Sorry for can't provide pictures but I really need help.Thank you!

textIsSelectable property doesn't work with a Toolbar

I have a normal TextView with the android:textIsSelectable property on true. This was working perfectly fine, even while I have the TextView inside of a ListView. But now I decided to use the new Toolbar as my ActionBar and it doesn't work anymore. I don't get a crash or anything, I only see the screen flickering on Lollipop devices when I longPress the TextView. On pre-Lollypop devices I see nothing happening.
Does anybody else have the same issue and is there a fix for it?
If you app theme extends one of .NoActionBar themes, you need to enable windowActionModeOverlay, to fix this issue.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowActionModeOverlay">true</item>
</style>
In your layout.xml file: Replace fill_parent with wrap_contentfor this element.
Try this, it worked for me :
In your toolbar layout, add the textview by yourself, an example :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text = "Hi, there"
android:textColor="#ff0000"
android:textIsSelectable="true"/>
</android.support.v7.widget.Toolbar>
I tested this on android v4.0.4 ICS, its working fine for me, I am able to select text on long press.
Hope this helps...

Android Navigation Drawer and windowActionBarOverlay = true

I'm trying to implement the new Android Navigation Drawer in my application. I have created a BaseActivity.java that handles the Drawer setup and listeners, and I have two subactivities that extend this base class. On the second activity, I plan to use a different action bar style, using the following attrs:
<item name="android:windowActionBarOverlay">true</item>
<item name="android:background">#android:color/transparent</item>
to make the action bar transparent, and make content richer, as there is a picture header in my layout.
I've achieved just that, but now the problem is, that because the content is expanding to take advantage of the extra space of using the ActionBar as overlay, the Navigation Drawer itself is expanding too and it overlaps the ActionBar, creating a pretty awful looking layout:
What I'd like to have done, is the actual content (frame layout that will be populated with a fragment) to take up the extra space, but have the nav drawer still go underneath the action bar, similar to the Play Music App:
Any ideas on what I can do to make that happen?
EDIT So, as per Ahmad's assistance I set the marginTop on the ListView only. Here's the layout:
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_marginTop="?android:attr/actionBarSize"
<!-- This was added after seeing the crazy effect, but does nothing -->
android:layout_marginBottom="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_width="240dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:background="?attr/listviewBackground"
/>
And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.
Not sure what's causing it :(
And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.
If you set your ListView gravity to start|bottom it solves your problem. No additional margin is added at the bottom. Looks like the DrawerLayout default gravity is start|center
<ListView
android:id="#+id/left_drawer"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start|bottom"/>
In case anyone is interested in another take to this question. Here's what happened.
I tried setting only the margin to the top of the list view like this:
android:layout_marginTop="?android:attr/actionBarSize"
But as mentioned on the edited question, that had a weird behaviour where there was also a margin on the bottom despite not being set on the layout resource file.
So, I was looking closely at the Play Music App and noticed that it's not actually a margin, but rather some padding, and additionally they are using a custom background that fills the space specified by the padding with a transparent color.
Here's what I did:
Set Padding at the top of the ListView, rather than margin:
android:paddingTop="?android:attr/actionBarSize"
As said before, it's important to not hard code the dimensions as they vary per device.
Create a custom drawable that has a top part transparent, and then rest of a solid color:
It looks somehow like this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<solid android:color="#80000000" />
</shape>
</item>
<item android:top="#dimen/action_bar_default_height">
<shape
android:shape="rectangle">
<solid android:color="#color/light_gray" />
</shape>
</item>
Note that I tried to use ?android:attr/actionBarSize on the drawable, but that made the app force close. Instead, I searched through grepcode and found a few dimen files with different sizes for the action bar, so I added those to my own project's dimen files.
For values: 48dp
For values-land: 40dp
For values-sw600dp: 56dp
And after that, I think I looks great, notice on the screenshot how the listview and the actionbar don't overlap, and the transparent part of the listview is just the right size.
Hope that helps anyone who was wondering how to achieve this.
You can set a margin at the top of your layout, so that the content draws itself below the ActionBar.
Just add this in your parent layout:
android:layout_marginTop="?android:attr/actionBarSize"
The attribute actionBarSize refers to, like you would have already guessed, to the size of the ActionBar. You can't set an absolute value as a margin, since the ActionBar does not always have the same size across all Android devices (It's bigger on tablets, smaller on handset devices).
Edit:
Set the margin to the ListView.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/left_drawer"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
The Google Music app does the same:
I solved this problem using paddingTop:
<FrameLayout
android:id="#+id/menu_frame"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingTop="?attr/actionBarSize" >
<ListView
android:id="#+id/left_drawer_list"
android:layout_width="240dp"
android:layout_height="match_parent" />
</FrameLayout>
Hope that helps
I have created a working demo following the above guide and tested on 2.x to 5.x
You can clone from Github
The important thing to play around is in Main Activity
toolbar = (Toolbar) findViewById(R.id.toolbar);
res = this.getResources();
this.setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
findViewById(R.id.linearLayout);
scrimInsetsFrameLayout.setOnInsetsCallback(this);
}
and the call back
#Override
public void onInsetsChanged(Rect insets) {
Toolbar toolbar = this.toolbar;
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
toolbar.getLayoutParams();
lp.topMargin = insets.top;
int top = insets.top;
insets.top += toolbar.getHeight();
toolbar.setLayoutParams(lp);
insets.top = top; // revert
}
Absolutely the Theme for V21 does the magic
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- API 21 theme customizations can go here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/accent_material_light</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
</style>

Categories

Resources