Is it possible to customize layout of android.widget.SearchView (I'm using it in actionBar)?
I want to change icon and TextField background.
I've found the only one way to do that- to use reflections.
SearchView mSearchView = (SearchView)menu.findItem(R.id.search).getActionView();
try
{
Field searchField = SearchView.class.getDeclaredField("mSearchButton");
searchField.setAccessible(true);
ImageView searchBtn = (ImageView)searchField.get(mSearchView);
searchBtn.setImageResource(R.drawable.search_img);
searchField = SearchView.class.getDeclaredField("mSearchPlate");
searchField.setAccessible(true);
LinearLayout searchPlate = (LinearLayout)searchField.get(mSearchView);
((ImageView)searchPlate.getChildAt(0)).setImageResource(R.drawable.search_img);
searchPlate.setBackgroundResource(R.drawable.edit_text_bkg);
}
catch (NoSuchFieldException e)
{
Log.e(TAG,e.getMessage(),e);
}
catch (IllegalAccessException e)
{
Log.e(TAG,e.getMessage(),e);
}
If you use Appcompat v7, there is a way to do it without using reflection:
Declare the following style, and customize only those properties you need to customize, remove the rest (so they are inerhited from the parent style):
<style name="Widget.AppCompat.SearchView.CustomSearchView" parent="#style/Widget.AppCompat.SearchView">
<item name="layout">#layout/abc_search_view</item>
<item name="queryBackground">#drawable/abc_textfield_search_material</item>
<item name="submitBackground">#drawable/abc_textfield_search_material</item>
<item name="closeIcon">#drawable/abc_ic_clear_mtrl_alpha</item>
<item name="goIcon">#drawable/abc_ic_go_search_api_mtrl_alpha</item>
<item name="voiceIcon">#drawable/abc_ic_voice_search_api_mtrl_alpha</item>
<item name="commitIcon">#drawable/abc_ic_commit_search_api_mtrl_alpha</item>
<item name="suggestionRowLayout">#layout/abc_search_dropdown_item_icons_2line</item>
<item name="searchIcon">#drawable/ic_action_search</item>
</style>
Now, in your theme, use the same property:
<item name="searchViewStyle">#style/Widget.AppCompat.SearchView.Bonial</item>
Of course, your theme must inherit from one of the AppCompat themes, in my case, it was something like this:
<style name="Theme.MyActionBarActivity" parent="#style/Theme.AppCompat.Light">
Also your activities should extend ActionBarActivity and use the "support" version of the action bar methods. More info here.
I also read an article of a guy that declared the styles in some other way, but also using AppCompat v7:
http://www.jayway.com/2014/06/02/android-theming-the-actionbar/
If you are using android native SearchView and you want to change small search icon, which appears when searchView is expanded, then you are in trouble. Because attribute searchViewSearchIcon is internal, and can't be modified using styles.
Code snippet from SearchView class:
private int getSearchIconId() {
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(com.android.internal.R.attr.searchViewSearchIcon,
outValue, true);
return outValue.resourceId;
}
In ActionBarSherlock:
<style name="Your_Theme" parent="#style/Theme.Sherlock">
<item name="searchViewSearchIcon"> #drawable/ic_menu_search </item>
</style>
In Holo:
<style name="Your_Theme" parent="#style/Theme.Light">
<item name="android:searchViewSearchIcon"> #drawable/ic_search </item>
</style>
Related
My SearchView is located in a LinearLayout / RelativeLayout rather than the action bar.
Its default text color is white, how to change it?
Digging into the source code of the appcompat SearchView I found that it uses an AppCompatAutoCompleteTextView which by default uses the autoCompleteTextView style.
Creating a different autocomplete style and setting it in the app theme solved the problem for me.
<style name="SearchAutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
<item name="android:textColor">#color/my_text_color</item>
<item name="android:textColorHint">#color/my_hint_color</item>
</style>
<style name="AppTheme" parent="Theme.AppCompat.Light">
...
<item name="autoCompleteTextViewStyle">#style/SearchAutoCompleteTextView</item>
</style>
For Androidx Library
SearchView searchView = (SearchView) findViewById(R.id.search);
EditText searchEditText = searchView.findViewById(androidx.appcompat.R.id.search_src_text);
searchEditText.setTextColor(getResources().getColor(R.color.white));
searchEditText.setHintTextColor(getResources().getColor(R.color.white));
For Android Support Library
SearchView searchView = (SearchView) findViewById(R.id.search);
EditText searchEditText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchEditText.setTextColor(getResources().getColor(R.color.white));
searchEditText.setHintTextColor(getResources().getColor(R.color.white));
Try this,
SearchView searchView= (SearchView) findViewById(R.id.searchView1);
int id = searchView.getContext()
.getResources()
.getIdentifier("android:id/search_src_text", null, null);
TextView textView = (TextView) searchView.findViewById(id);
textView.setTextColor(Color.WHITE);
or
((EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text))
.setHintTextColor(getResources().getColor(R.color.white));
or
searchView.setQueryHint(Html.fromHtml("<font color = #ffffff>" +
getResources().getString(R.string.your_str) + "</font>"));
This may helps you.
For me worked next approach:
1.add style into your styles.xml
<style name="SearchViewStyle" parent="Widget.AppCompat.SearchView">
<item name="android:textColor">#color/white</item>
<item name="android:editTextColor">#color/white</item>
<item name="android:textColorHint">#color/light_gray</item>
</style>
2.add this line in your SearchView layout code
app:theme="#style/SearchViewStyle"
I would do this kind of job through the xml layout file. This can be found in the res/layout folder.
You would need to do something similar to the following:
Add this to the parent theme.
<item name="android:editTextColor">#android:color/white</item>
This should change the entered text.
You can also use something like this:
<item name="android:textColorHint">#android:color/white</item>
It will change the hint text for the SearchView.
Hope this helps :)
Just override the default color using the android:theme attribute:
<androidx.appcompat.widget.SearchView
android:theme="#style/ThemeOverlay.SearchView"
with
<style name="ThemeOverlay.SearchView" parent="">
<!-- Text color -->
<item name="android:editTextColor">#color/...</item>
<!-- Hint text color -->
<item name="android:textColorHint">#color/...</item>
</style>
Try this, if its not working try to change your theme.
((EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text)).setHintTextColor(getResources().getColor(R.color.white));
or try like this
searchView.setQueryHint(Html.fromHtml("<font color = #ffffff>" + getResources().getString(R.string.hintSearchMess) + "</font>"));
In this link colors of search icon, search hint icon, close icon, plate, query hint color, query color are changed
This worked for me:
EditText searchEditText = searchView.findViewById(androidx.appcompat.R.id.search_src_text);
searchEditText.setTextColor(getResources().getColor(R.color.white));
searchEditText.setHint("Search");
searchEditText.setHintTextColor(getResources().getColor(R.color.white));
I have set android:textAllCaps="false" in my android.support.design.widget.TabLayout thought it is showing the Tab Title in All caps only.
How can I remove all caps?
UPDATE FOR DESIGN LIBRARY 23.2.0+
The original answer doesn't work with design library 23.2.0 or later. Thanks for #fahmad6 pointed out in comment, in case someone missed that comment, I'll put it here. You need to set both textAllCaps and android:textAllCaps to false to disable all capitalize setting.
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
ORIGINAL ANSWER
By default, tabs are created by TabLayout sets the textAllCaps property to be true, you have to define a style making this flag false.
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
#Paresh Mayani answer is correct however you can create only tab style
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
And use it using
<android.support.design.widget.TabLayout
app:tabTextAppearance="#style/MyCustomTextAppearance"
.../>
use this attribute app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
It will work.
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:tabGravity="fill"
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabIndicatorColor="#color/colorPrimary"
app:tabMode="fixed"
app:tabPaddingStart="0dp" />
https://stackoverflow.com/a/34678235/1025379
<android.support.design.widget.TabLayout
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
/>
In my case two variants work:
1) By Bogdan (susemi99):
<android.support.design.widget.TabLayout
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
/>
2) By Paresh Mayani. I wanted to have android:textAllCaps="false" and android:textSize="15sp" simultaneously, so his old method works.
In styles.xml write (parent may vary, for instance, "#android:style/TextAppearance.Widget.TabWidget", "TextAppearance.Design.Tab"):
<style name="TabLayout" parent="Widget.Design.TabLayout">
<item name="tabIndicatorColor">#color/color_blue</item>
<item name="tabSelectedTextColor">#color/color_blue</item>
<item name="tabTextColor">#color/black</item>
<item name="tabTextAppearance">#style/TabLayoutTextAppearance</item>
</style>
<style name="TabLayoutTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">15sp</item>
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
Apply this style in layout:
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/TabLayout"
/>
For those who can't get working other answers.
Defining a style is working fine when you have single line tab text.
If you take a close look into the TabLayout, you'll see that it's using a field design_tab_text_size_2line when the tabs has more than one line.
The only way I could find to effect this field is to override it in your dimen file.
So put this in your values/dimens.xml
<dimen name="design_tab_text_size_2line" tools:override="true">10sp</dimen>
Hope it helps.
This works for me in just one line
<android.support.design.widget.TabLayout
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"/>
Here is simple solution....Enjoy
for (int tabIndex = 0; tabIndex <tabLayout.getTabCount() ; tabIndex++) {
TextView tabTextView = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(tabIndex)).getChildAt(1));
tabTextView.setAllCaps(false);
}
Change: <item name="android:textAllCaps">false</item>
With: <item name="textAllCaps">false</item>
This Worked For Me...
<style name="TabLayoutStyle" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/TabTextAppearance</item>
</style>
<style name="TabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
In versions priror to 14, you need to set (as commented by Paresh Mayani):
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
But, in case of android version is equal or greater than 14, you need to set:
<item name="android:textAllCaps">false</item>
So, if you need to be compatible with versions before and after 14, you also need to create a folder values-v14, and a file styles.xml in that folder with the content:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textAllCaps">false</item>
</style>
</resources>
Try following method and you can implement all the methods of TextView in TabLayout
private void setCustomTab() {
ViewGroup vg = (ViewGroup) mTabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(ResourcesCompat.getFont(this,R.font.montserrat_medium));
((TextView) tabViewChild).setAllCaps(false);
}
}
}
}
Hope it helps.
Here the Simple solution to Avoid Capitalize and change font size , font family on TabLayout design in Android 100% Working
Add following style on res/values/stye.xml
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">#font/poppins_semi_bold</item>
</style>
Call this style in your tab layout as app:tabTextAppearance="#style/MyCustomTextAppearance"
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#FFF"
app:tabTextAppearance="#style/MyCustomTextAppearance"
app:tabIndicatorHeight="3dp"
android:layout_marginBottom="#dimen/_5sdp"
app:tabSelectedTextColor="#color/text_app_color"
app:tabTextColor="#color/text_app_color_1"
app:tabMode="auto" />
</com.google.android.material.appbar.AppBarLayout>
You can also do this in your Java code. If you are using a SlidingTabLayout look at this sample:
protected TextView createDefaultTabView(Context context){
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);//see line 38 above change the value their in TAB_VIEW_TEXT_SIZE_SP.
textView.setTypeface(Typeface.DEFAULT);//From DEFAULT_BOLD
textView.setTextColor(Color.parseColor("#536DFE"));//Text color of the words in the tabs. Indigo A200
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
// If we're running on Honeycomb or newer, then we can use the Theme's
// selectableItemBackground to ensure that the View has a pressed state
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
textView.setBackgroundResource(outValue.resourceId);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
// If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
textView.setAllCaps(true);
}
int padding = (int)(TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
textView.setPadding(padding, padding, padding, padding);
return textView;
}
Notice that textView.setAllCaps() has true as the perimeter:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
// If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
textView.setAllCaps(true);
}
When I changed this to (false) it solved the problem for me:
textView.setAllCaps(false);
Also my string resource file that I use for the tabs looks like this:
<string name="tab_title">Title with capital and smaller case</string>
However if it had all caps like >TITLE WITH ALL CAPS< you would still of course get all caps in your tabs.
I made no other changes.
It is noteworthy that you can set textView.setAllCaps(false) too, but this made no difference in my case. I just commented out textView.setAllCaps(true).
Changing attributes in XML file doesn't work in Android 11 (SDK 30). Here is code that I use to setup tabs individually using a tab label. It's safer than setting new styles for all text fields in the tabs or relying on the existing tab layout, because the current tab design can be changed by Android. This method assumes that a tab text has been set before the function below is called. Second parameter in the call, txt is a tab label.
private fun setTabStyle(tabs: TabLayout, txt: String) {
val av = ArrayList<View?>()
tabs.findViewsWithText(av, txt, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION )
if (av.count() > 0) {
val avt = ArrayList<View?>()
(av[0] as? ViewGroup)?.let {
for ( i in 0 until it.childCount) {
val tv = it.getChildAt(i) as? TextView
tv?.let {t ->
if (tv.text == txt) {
t.isAllCaps = false
t.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11.toFloat())
}
}
}
}
}
}
Long story short (programmatically)...
/**
* #param view Target TabLayout view
* #param caps Present the text caps style
*/
public static void setAllCaps(View view, boolean caps) {
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
setAllCaps(((ViewGroup) view).getChildAt(i),caps);
} else if (view instanceof TextView) ((TextView) view).setAllCaps(caps);
}
Call setAllCaps like this :
tabLayout.addTab(tabLayout.newTab().setText("Recent"));
tabLayout.addTab(tabLayout.newTab().setText("New"));
setAllCaps(tabLayout,false);
It'll work if you only add one of these calls.
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabTextAppearance="#style/TextAppearance.AppCompat.Medium"
app:tabTextAppearance="#style/TextAppearance.AppCompat.Small"
Just add this to your custom style file
<item name="android:textStyle">normal</item>
I read all the above solutions and all lead to this.
I am trying to make the text the user types of the search view white. "android:searchViewTextField" give an error. I can't find the right name for a global style:
<style name="AppTheme" parent="#style/_AppTheme"/>
<style name="_AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:searchViewTextField">#color/white_color</item>
</style>
Is there a global style which will only affect the text of the Searchview and not all text boxes?
Define the theme "SearchTextViewTheme"
<style name="SearchTextViewTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:textColor">#color/white_color</item>
</style>
Then inside the TextView
<TextView
style="#style/SearchTextViewTheme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
In fact applying theme must be explicitly defined in the layout XML. Therefore you do not have to worry about the theme affecting other text boxes
If your targed SDK is 20 or less, the attributes Goolge uses to style the SearchView are hidden and you’ll end up with compilation errors if you try overriding them in your theme.
You can use the AppCompat v20 SearchView instead of the the native SearchView following this tutorial. AppCompat exposes attributes like searchViewTextField and searchViewAutoCompleteTextView to change the style of the AutoCompleteTextView.
Here's how it's done ins Xamarin (I based the idea from Patrick's answer):
[assembly: ExportRenderer(typeof (CustomSearchBar), typeof (CustomSearchBarRenderer))]
namespace Bahai.Android.Renderers
{
public class CustomSearchBarRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
SearchBar element = (SearchBar) this.Element;
var native = (global::Android.Widget.SearchView) Control;
// do whatever you want to the controls here!
//--------------------------------------------
// element.BackgroundColor = Color.Transparent;
// native.SetBackgroundColor(element.BackgroundColor.ToAndroid());
// native.SetBackgroundColor(Color.White.ToAndroid());
//The text color of the SearchBar / SearchView
AutoCompleteTextView textField = (AutoCompleteTextView)
(((Control.GetChildAt(0) as ViewGroup)
.GetChildAt(2) as ViewGroup)
.GetChildAt(1) as ViewGroup)
.GetChildAt(0);
if (textField != null)
textField.SetTextColor(Color.White.ToAndroid());
}
}
}
}
this did the trick
<style name="myTheme" parent="#style/Theme.AppCompat.Light">
<item name="android:editTextColor">#fffff</item>
</style>
The above solutions might work in java but they don't work in xamarin and i guess this solution will work in java.
Is there a way to change programmatically the primary colors. I would like to do it in code depending on the screen/state of the app.
Currently I can only set the colors in the theme (static) :
<item name="android:colorPrimary">#color/primary_color</item>
<item name="android:colorPrimaryDark">#color/dark_color</item>
<item name="android:colorBackground">#android:color/white</item>
<item name="android:colorAccent">#color/primary_color</item>
<item name="android:colorControlHighlight">#color/primary_color</item>
You can, of course, implement custom subclasses of View that have methods for setting colors.
You can also define multiple themes with you various color schemes.
Views look up theme information from the context when they are created. So to change the styles applied from a theme you will have to recreate your view hierarchy with a context that uses the right theme.
One way to do that, is to create a new ContextThemeWrapper and then get a LayoutInflator that uses that theme wrapper, remove the old version of your layout and re-inflate your layout.
Roughly:
ContextThemeWrapper themeWrapper = new ContextThemeWrapper(this, R.style.AppThemeWithColorScheme2);
LayoutInflater layoutInflater = LayoutInflater.from(themeWrapper);
viewContainer.removeAllViews();
layoutInflater.inflate(R.layout.my_layout, viewContainer, true );
If you are using Action Bar, that may be a bit more tricky, because the Action Bar is created once per activity.
USe this code for setting toolbarcolor and status bar (darker toolbar color)
toolbar.setBackgroundColor(toolbarColor);
factor=0.8f;
int a = Color.alpha(toolbarcolor);
int r = Math.round(Color.red(toolbarcolor) * factor);
int g = Math.round(Color.green(toolbarcolor) * factor);
int b = Math.round(Color.blue(toolbarcolor) * factor);
int statusColor=Color.argb(a,
Math.min(r, 255),
Math.min(g, 255),
Math.min(b, 255));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = MainActivity.this.getWindow();
window.setStatusBarColor(statusColor);
}
This is most practical with no error, there is no need to do any extra coding, just go to android tree project
res > values > colors then edit these codes:
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
add these under style:
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
add into manifest just after ".MainActivity" :
android:theme="#style/AppTheme.NoActionBar">
This change everything in text
<item name="android:textColorPrimary">#color/textGrey</item>
<item name="android:textColorSecondary">#color/textGrey</item>
<item name="android:textColorTertiary">#color/textGrey</item>
<item name="android:listDivider">#color/textGrey</item>
I want to use different ActionBar Icons depending on which style I use (Dark or Light).
I couldn't figure it out how, heres what I tried:
<style name="AppThemeDark" parent="Theme.Sherlock.ForceOverflow">
<item name="android:actionButtonStyle">#style/customActionButtonStyleDark</item>
<item name="actionButtonStyle">#style/customActionButtonStyleDark</item>
</style>
<style name="AppThemeLight" parent="Theme.Sherlock.Light.ForceOverflow">
<item name="android:actionButtonStyle">#style/customActionButtonStyleLight</item>
<item name="actionButtonStyle">#style/customActionButtonStyleLight</item>
</style>
<style name="customActionButtonStyleDark" >
<item name="#drawable/action_search">#drawable/action_search</item>
</style>
<style name="customActionButtonStyleLight" >
<item name="#drawable/action_search">#drawable/action_search_light</item>
</style>
I also tried to insert <item name="#drawable/action_search">#drawable/action_search</item> directly into the theme style, but nothing worked.
Any ideas how?
Even though you found a workaround, maybe this will help someone else. I found a simple way to do this in xml (what logcat's answer is referring to). The trick I used was to create custom attributes for my menu/actionbar icons. You have to have one attribute per menu item icon.
You need to create attrs.xml in your values folder, and add your custom attributes. Think of each attribute as a constant that your themes/styles set, and then your styles/views can use those contants to set properties.
<declare-styleable name="customAttrs">
<attr name="customSearchIcon" format="reference" />
</declare-styleable>
In your styles.xml in your values folder, have your themes/styles that set your custom icon attributes to drawable references.
<style name="AppThemeDark" parent="Theme.Sherlock.ForceOverflow">
<item name="customSearchIcon">#drawable/action_search</item>
</style>
<style name="AppThemeLight" parent="Theme.Sherlock.Light.ForceOverflow">
<item name="customSearchIcon">#drawable/action_search_light</item>
</style>
Lastly, in your [menu_name].xml in your menu folder, have your menu item set its icon to your matching custom icon attribute.
<item
android:id="#+id/menuitem_search"
android:icon="?attr/customSearchIcon"/>
Now, depending on what theme is set, the icon for the menu item will change. Also, this allows you to still have API specific versions of your drawables (light and dark) using resource identifiers with your drawable folders, so you can have different menu style icons for pre 3.0 and actionbar style icons for 3.0+.
Also, remember when setting a theme at runtime (vs AndroidManifest.xml), you must set it before calling setContentView() in your Activity. It is recommended to restart your activity after changing the theme of an Activity that has already been created.
I think you did not get theming :) When you are trying to do:
<style name="customActionButtonStyleDark" >
<item name="#drawable/action_search">#drawable/action_search</item>
</style>
You are trying to overload some attribute in theme with name "#drawable/action_search"
I have bad news for you, I think there is no such. So you can go to the theme Theme.Sherlock.ForceOverflow and it's parents and see what you can overload.
If nothing help's you, and you want to have custom attribute in your theme for different icons, It's different topic. You need to create attribute in attrs.xml, point your icon source to this new attribute and define attribute value in theme. For every different button.
Solved it, but gave it up to try it with XML, I did it now programmatically:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
SharedPreferences prefs = getSharedPreferences("app", 0);
boolean isDark = "Dark".equals(prefs.getString("theme", "Dark"));
com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main, menu);
// set Icons
menu.findItem(R.id.menuitem_search).setIcon(isDark ? R.drawable.action_search : R.drawable.action_search_light);
menu.findItem(R.id.menuitem_add).setIcon(isDark ? R.drawable.content_new : R.drawable.content_new_light);
menu.findItem(R.id.menuitem_share).setIcon(isDark ? R.drawable.social_share : R.drawable.social_share_light);
return true;
}
See res/xml/ic_search.xml in blog post AppCompat — Age of the vectors (Chris Barnes)
Notice the reference to ?attr/colorControlNormal
<vector xmlns:android="..."
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:pathData="..."
android:fillColor="#android:color/white"/>
</vector>