ActionBarStyle from style.xml with AppCompat v7 support library - android

I searched whole web. Tried tens of solutions. I also followed documentation of Android but I couldn't manage to do want I need. I just want to make actionbar background gradient. I made my drawable xml file:
action_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:angle="270"
android:startColor="#color/colorActionBarStart"
android:endColor="#color/colorActionBarEnd" />
</shape>
My style.xml:
<resources>
<!-- the theme applied to the application or activity -->
<style name="AppTheme"
parent="Theme.AppCompat.Light">
<item name="actionBarStyle">#style/MyActionBarStyle</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- ActionBar styles -->
<style name="MyActionBarStyle"
parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
<item name="background">#drawable/action_bar</item>
</style>
</resources>
I saw same thing many times with android. There are tons of answers but none of them works. What I'm trying to do is just make a gradient background for actionbar. Isn't there anybody done this before with appcompat v7 library? Why is this so hard?
May be I can't get because I'm so new at android development. If this is the case tell me right point of view.
Please help me.
Thank you.

Personally, I do not use the default action bar provided by a theme like Theme.AppCompat.Light. Instead, I'll do this:
Use a theme like Theme.AppCompat.Light.NoActionBar
Include a <Toolbar> tag in my layout
Call setSupportActionBar() and pass my toolbar
This lets me set the background of my toolbar directly in my layout file. That said...
I tried playing around with the base themes you posted, and I was also unable to set the background of the default actionbar using styles. However, I got a gradient working by deleting the actionBarStyle theme item and just doing it in Java, in onCreate():
Drawable d = ContextCompat.getDrawable(this, R.drawable.action_bar);
getSupportActionBar().setBackgroundDrawable(d);
If your goal is to do this for every screen in your app, you could create a BaseActivity class and have all of your other activites extend that instead of AppCompatActivity:
public class BaseActivity extends AppCompatActivity {
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Drawable d = ContextCompat.getDrawable(this, R.drawable.action_bar);
getSupportActionBar().setBackgroundDrawable(d);
}
}

Related

Styling the popup menu in Android 5.0

I'm making my app ready for Android 5.0, I'm using the latest compatibility library, here is what my style looks like.
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
</style>
</resources>
(The ActionBar color is being set programmatically.)
Now, I want the overflow/popup menu to have the dark background like it had in the holo implementation, but I can't get it to work, here is what it looks like:
I have tried setting the popupMenuStyle but it didn't work.
How can I make the popup menu darker?
Stop using the ActionBar. If you want a ToolBar to be set up like an ActionBar, follow this guide on the android-developers blog.
It actually mentions your use case at Dark Action Bar and provides this code:
<android.support.v7.widget.Toolbar
android:layout_height=”wrap_content”
android:layout_width=”match_parent”
android:minHeight=”#dimen/triple_height_toolbar”
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
Not a full answer but what I found so far:
In past versions you needed to specify a drawable (Check https://github.com/StylingAndroid/StylingActionBar code and tutorials)
Apparently, now that is a color. To modify it you need to do specify the following theme:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:actionBarPopupTheme">#style/popupNew</item>
</style>
<style name="popupNew" parent="android:ThemeOverlay.Material.Light">
<item name="android:colorBackground">#color/red</item>
</style>
</resources>
This works correctly if the theme applied to the app is just this.
If I add android:actionBarPopupTheme to my existing theme, it doesn't work. I am trying to figure out why.
Solved my problem by using this style:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
<item name="actionBarStyle">#style/AbStyle</item>
<item name="actionModeBackground">#color/actionmode_bg</item>
</style>
<style name="AbStyle" parent="Widget.AppCompat.Toolbar">
<item name="elevation">2dp</item>
<item name="displayOptions">homeAsUp|showTitle</item>
<!--showHome-->
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorAccent">#color/theme_accent_secondary</item>
<item name="actionBarStyle">#style/AbStyle</item>
</style>
I had to use Widget.AppCompat.Toolbar as the parent actionBarStyle
Add the property popupTheme to your toolbar:
<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_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/color_primary"
app:theme="#style/Theme.AppCompat.Light"
app:popupTheme="#style/Theme.AppCompat" />
Or define a new style for your toolbar:
<style name="MyToolBarStyle" parent="Widget.AppCompat.Toolbar">
<item name="android:background">#color/green</item>
<item name="popupTheme">#style/Theme.AppCompat.Light</item>
<item name="theme">#style/Theme.AppCompat</item>
</style>
This question has already been answered for styling via XML, but I'm adding an explanation here of how to work out the solution to this and similar styling questions yourself.
First, this is the solution when using AppCompat. To your App's style.xml add actionBarPopupTheme to your theme:
<style name="Theme.MyTheme" parent="#style/Base.Theme.AppCompat.Light.DarkActionBar">
...other stuff here
<item name="actionBarPopupTheme">#style/Theme.MyTheme.ActionBarPopupTheme</item>
</style>
<style name="Theme.MyTheme.ActionBarPopupTheme" parent="#style/ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#android:color/white</item>
<item name="android:background">#android:color/black</item>
</style>
Here's the steps I took to arrive at this solution (it takes a bit of detective work as the Android documentation is poor):
Open your App's style.xml in Android Studio
On the line where you App's theme is defined, put your screen cursor in the parent theme (e.g. click in #style/Base.Theme.AppCompat.Light.DarkActionBar) then press F4. This should take you to the source code for the style in the appcompat library.
Within this style I saw this line:
< item name="actionBarPopupTheme">#style/ThemeOverlay.AppCompat.Light< /item>
This looked like a possible place to change the theme of the popup. I searched for "actionBarPopupTheme" in the poor
Android developers documentation and found "Reference to a theme that should be used to
inflate popups shown by widgets in the action bar". So this was worth playing with.
I copied the appcompat line containing "actionBarPopupTheme" to my style.xml then in this line replaced the item's theme reference (the bit in bold above) with Theme.MyTheme.ActionBarPopupTheme.
In my style.xml I created my new style named Theme.MyTheme.ActionBarPopupTheme. I used the same parent that was used in the style I copied from the appcompat source (the bit in bold above).
To ensure my new popup style was working, I changed the parent style to ThemeOverlay.AppCompat.Dark then ran and tested the code on a device. The popup style changed, so now I knew my overriding of actionBarPopupTheme was the correct thing to do. Then I changed back to ThemeOverlay.AppCompat.Light.
The next challenge is to work out what item names to override in Theme.MyTheme.ActionBarPopupTheme. I changed the text and background colours. To find the correct item names that change the style of something can be tricky in some cases. One way to find less obvious style item names is to look through the style definitions in the appcompat xml file (the one you opened when pressing F4 in the 2nd step above), continually descending into parent styles (F4 again!) until you find something that may do what you want. Google searches will help here too.

ActionBarCompat & Transparency

I would like to make the ActionBar in the support library fully transparent, however, it seems that changing the background drawable won't suffice since the backgrounds stack. If you put a semi-transparent background you end up with the default background behind it.
Does anyone know a way to remove that background?
This is what happens:
The code for the background drawable:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#66336688"/>
</shape>
As you can see, the drawable has a transparent blue that overlaps with the default gray background.
Ok, I found the solution messing around with the SDK.
It seems that it is pretty simple, you need to do 3 things:
Create a background drawable as shown on my question.
Create an ActionBar style like so:
<!-- Application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">#style/MyActionBar</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">#style/MyActionBar</item>
</style>
<!-- ACTION BAR STYLES -->
<style name="MyActionBar" parent="#style/Widget.AppCompat.ActionBar">
<item name="android:background">#drawable/actionbar_background</item>
<item name="android:windowActionBarOverlay">true</item>
<!-- Support library compatibility -->
<item name="background">#drawable/actionbar_background</item>
<item name="windowActionBarOverlay">true</item>
</style>
Use the Window feature for ActionBar overlay using the Support method (ignore Eclipse's warning regarding API level for the constant; I used the SuppressLint annotation to remove the warning):
#SuppressLint("InlinedApi") #Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.activity_home);}
ChristianGuerrero answer is great but you should directly put the item:
<item name="android:windowActionBarOverlay">true</item>
inside the AppTheme style. Then you don't have to add anything in your onCreate method.

Change ActionBarSherlock background color

I'm trying to implement ActionBarSherlock because I was told it is relatively easy to implement and customize. I've found it was pretty easy to implement, but I'm trying to change the background color of the ActionBar and it's proving difficult.
According to the the site (link), it seems you can inherit one of the ActionBarSherlock's themes and then override the properties you need.
This is what I have so far:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="Theme.ActionBar" parent="Theme.Sherlock.ForceOverflow">
<item name="android:background">#000000</item>
<item name="background">#000000</item>
</style>
</resources>
I'm noticing the built-in theme are using images for the background, but I'm praying I don't have to create images to change the background color.
Thanks.
The action bar background color is defined in a style for the action bar, not in the theme itself. You'll need to do something like this:
<style name="Theme.MyTheme" parent="Theme.Sherlock.ForceOverflow">
<item name="actionBarStyle">#style/Widget.MyTheme.ActionBar</item>
<item name="android:actionBarStyle">#style/Widget.MyTheme.ActionBar</item>
</style>
<style name="Widget.MyTheme.ActionBar" parent="Widget.Sherlock.ActionBar">
<item name="android:background">#ff000000</item>
<item name="background">#ff000000</item>
</style>
Be careful using colors defined in XML. ColorDrawable did not respect it's view bounds on pre-Honeycomb so if you use tab navigation with a separate background for the stacked tab view you will have problems.
I just used
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00853c")));
It changed the background color. Hope it helps.
The code mentioned by Jake Wharton is true. But when applying the code to the styles.xml may not work if you have minSDK<11 because android:actionBarStyle is supported in API-11+
To solve that error:
Make a folder of values-v11 in your res folder and create the XML file as mentioned above.

Android: customize all UI widgets using one theme

How can I customize all widgets in the application by creating one style and apply it to application through android:theme in AndroidManifest?
Here's an example that might help (it might not work verbatim as I've tweaked it to simplify it, and to showcase some of the other things you can do).
In res\values\styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="TextColorForTheme">
<item name="android:textColor">#color/red</item>
</style>
</resources>
In res\values\themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="myTheme" parent="#style/android:Theme">
<item name="android:listSeparatorTextViewStyle">#style/TextColorForTheme</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowFrame">#null</item>
</style>
</resources>
Then in your AndroidManifest.xml, set either the whole application, or individual Activities to use that theme:
<application
android:theme="#style/myTheme"
<snip>
<activity
android:theme="#style/myTheme"
<snip>
Alternatively, you can set the theme in the code for your Java Activity:
#Override
public void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setTheme(R.style.myTheme);
<snip>
You won't be able to do this by creating just one style. A theme is in essence a meta-style that defines the default styles for each of the different widgets available. You will start by creating a theme (which is itself a style) with a parent of one of the existing system themes and setting the default style attributes for each widget you wish to change from the base theme. For example, if you had a different button style that you wanted to set as default in your theme, you might add the following to your theme definition:
<item name="android:buttonStyle">#style/MyButtonStyle</item>
See http://developer.android.com/guide/topics/ui/themes.html for more info.

ActionBar background image

I've inherited the Holo Light Theme and customized the background of the ActionBar with the following:
Content of styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ActionBar" parent="#android:style/Widget.Holo.ActionBar">
<item name="android:background">#drawable/actionbar_background</item>
</style>
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/ActionBar</item>
</style>
</resources>
Content of actionbar_background.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#raw/actionbar_background"
android:tileMode="repeat" />
Instead of being repeated, the image is stretched, any idea of why android:tileMode="repeat" is not applied?
Thanks in advance
Drawable d=getResources().getDrawable(R.drawable.background_image_name);
getActionBar().setBackgroundDrawable(d);
The above code sets the background image for the action bar.
Hope it helps.
Ok, thanks to Romain Guy on #android-dev IRC channel, it's a known bug on honeycomb / Android 3.0 which will be fixed on the next release. Since then, the only solution is do it from code, and it works :-)
final ActionBar actionBar = getActionBar();
BitmapDrawable background = new BitmapDrawable (BitmapFactory.decodeResource(getResources(), R.raw.actionbar_background));
background.setTileModeX(android.graphics.Shader.TileMode.REPEAT);
actionBar.setBackgroundDrawable(background);
You can easily do this thing. If you would like to change Action Bar background image then you place this code to your res/styles.xml file.
<style name="Theme.MyAppTheme" parent="#android:style/Theme.Holo">
<item name="android:actionBarStyle">#style/Theme.MyAppTheme.ActionBar</item>
</style>
<style name="Theme.MyAppTheme.ActionBar" parent="#android:style/Widget.Holo.ActionBar">
<item name="android:background">#drawable/top_black_bg</item>
</style>
For this you have to select an image from "drawable" folder . Here I select an image "tp_black_bg.png"
After that don't forget to declare this theme to your AndroidManifest.xml file
<application
.
.
.
android:theme="#style/Theme.MyAppTheme" >.............</application>
Now you can reopen any XML layout file , you can easily see the effect. In the same way you can also able to change the background color of ActionBar.
Thanks.
mActionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.navbar));
Use getSupportActionBar() from android.support.v7 for backward compatability.

Categories

Resources