I have a style for all buttons declared in values->styles.xml, like this.
<style name="BlueButton" parent="android:style/Widget.Button">
<item name="android:background">#color/blue</item>
</style>
and in the overall theme as
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:buttonStyle">#style/BlueButton</item>
</style>
I want to change the color of all buttons in my application, depending on what color the user chooses. Is there a way to define different styles in styles.xml and assign them to buttons dynamically.
Please note, i want to change the color of all the buttons in my application at a time and not one by one. For example, let's say, currently all my buttons are in black and when user chooses a theme of red, i want all the buttons in the application to have red background.
Hi try this code.
ThemeUtils class:
public class ThemeUtils {
private static int cTheme;
public final static int RED = 0;
public final static int GREEN = 1;
public static void changeToTheme(Activity activity, int theme) {
cTheme = theme;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
public static void onActivityCreateSetTheme(Activity activity) {
switch (cTheme) {
case BLUE:
activity.setTheme(R.style.AppBaseTheme);
break;
default:
}
}
}
And to set theme use this code:
ThemeUtils.changeToTheme(this, ThemeUtils.BLUE);
If you want to create custom theme in android see this link:
http://romannurik.github.io/AndroidAssetStudio/
Try to use theming concept.
First create attribute for the button
<attr format="reference" name="button_style"/>
Then create a style as you want:
<style name="BlueButton" parent="android:style/Widget.Button">
<item name="android:background">#color/blue</item>
</style>
And then apply to Theme:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="button_style">#style/BlueButton</item>
</style>
Finally apply this to button in Layout xml
<Button style="?button_style" />
Then if you want to change other theme create same like (2 and 3 point) it will automatically apply to your button
You can change the button background programmatically. And yes, call this method only once in every Activity such as you declare a theme for an Activity in manifest.xml. One color or drawable resource is applied for all button in your Activity. So, follow my steps:
Create a new third party class
Here, I named this class with ButtonBackground:
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.Button;
public class ButtonBackground {
/* This method is used to change the background with "drawable" resource. Maximum
* button to change its background is 5, no more. It caused by button's parameter
* only available for 5. You can add new parameter (button6, button 7, etc) with "int" type if needed.
*/
public void setButtonBackgroundDrawable(Context context, Activity activity, int drawable,
int button1, int button2, int button3, int button4, int button5) {
Drawable backgroundDrawable = context.getResources()
.getDrawable(drawable);
Button a = (Button) activity.findViewById(button1);
Button b = (Button) activity.findViewById(button2);
Button c = (Button) activity.findViewById(button3);
Button d = (Button) activity.findViewById(button4);
Button e = (Button) activity.findViewById(button5);
if (button1 != 0) {
a.setBackground(backgroundDrawable);
}
if (button2 != 0) {
b.setBackground(backgroundDrawable);
}
if (button3 != 0) {
c.setBackground(backgroundDrawable);
}
if (button4 != 0) {
d.setBackground(backgroundDrawable);
}
if (button5 != 0) {
e.setBackground(backgroundDrawable);
}
}
/* This method is used to change the background with "color" resource. Maximum
* button to change its background is 5, no more. It caused by button's parameter
* only available for 5. You can add new parameter (button6, button 7, etc) with "int" type if needed.
*/
public void setButtonBackgroundColor(Context context, Activity activity, int color,
int button1, int button2, int button3, int button4, int button5) {
int backgroundColor = context.getResources().getColor(color);
Button a = (Button) activity.findViewById(button1);
Button b = (Button) activity.findViewById(button2);
Button c = (Button) activity.findViewById(button3);
Button d = (Button) activity.findViewById(button4);
Button e = (Button) activity.findViewById(button5);
if (button1 != 0) {
a.setBackgroundColor(backgroundColor);
}
if (button2 != 0) {
b.setBackgroundColor(backgroundColor);
}
if (button3 != 0) {
c.setBackgroundColor(backgroundColor);
}
if (button4 != 0) {
d.setBackgroundColor(backgroundColor);
}
if (button5 != 0) {
e.setBackgroundColor(backgroundColor);
}
}
}
How to use?
For example, I have 3 buttons and I want to change its background using drawable resource. They are buttonId1, buttonId2 and buttonId3. My drawable's name is background_button_drawable.xml, and my current Activity named MainActivity. So I write the code below inside onCreate() method:
ButtonBackground buttonBackground = new ButtonBackground();
buttonBackground.setButtonBackgroundDrawable(getApplicationContext(), MainActivity.this,
R.drawable.background_button_drawable, R.id.buttonId1, R.id.buttonId2, R.id.buttonId3, 0, 0);
Note:
There are two 0 on the code above. It means button4 and button5 are empty in the parameter. So give 0 value if a button is empty or excess parameter.
What if I have 6 buttons?
You need one parameter again and must add a new parameter (button6). The parameter must int type:
public void setButtonBackgroundDrawable(... , int button6) {
And add it inside:
Button f = (Button) activity.findViewById(button6);
if (button6 != 0) {
f.setBackground(backgroundDrawable);
}
So when you use it:
ButtonBackground buttonBackground = new ButtonBackground();
buttonBackground.setButtonBackgroundDrawable(getApplicationContext(), MainActivity.this,
R.drawable.background_button_drawable, R.id.buttonId1, R.id.buttonId2, R.id.buttonId3, buttonId4, buttonId5, buttonId6);
What about change its background using color resource?
You need to change setButtonBackgroundDrawable() method with setButtonBackgroundColor(). It will looks like this:
ButtonBackground buttonBackground = new ButtonBackground();
buttonBackground.setButtonBackgroundColor(getApplicationContext(), MainActivity.this,
R.color.background_button_blue, R.id.buttonId1, R.id.buttonId2, R.id.buttonId3, 0, 0);
It's very simple to use, isn't?
Related
I am trying change theme when the app device is offline. But to achieve changing the background color is not gonna help and i needed to change the whole view and the text colors. But for that getting all the view with FindViewById is not an effective method to achieve that as I got lots of views to the Activity and as i tried using Themes
<item name="android:textColor">#android:color/black</item>
<item name="android:windowBackground">#android:color/white</item>
But as it shows only one colored TextView I cant use this method to activity as it has multiple colors and changing theme has to be done before you create the activity.
Please provide a solution which supports changing theme with multiple colored View
public class Utils {
private static int sTheme;
public final static int THEME_MATERIAL_LIGHT = 0;
public final static int THEME_YOUR_CUSTOM_THEME = 1;
public static void changeToTheme(Activity activity, int theme) {
sTheme = theme;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
activity.overridePendingTransition(android.R.anim.fade_in,
android.R.anim.fade_out);
}
public static void onActivityCreateSetTheme(Activity activity) {
switch (sTheme) {
default:
case THEME_MATERIAL_LIGHT:
activity.setTheme(R.style.Theme_Material_Light);
break;
case THEME_YOUR_CUSTOM_THEME:
activity.setTheme(R.style.Theme_YOUR_CUSTOM_THEME);
break;
}
}
}
In Your Activity:
#Override // Any Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// MUST BE SET BEFORE setContentView
Utils.onActivityCreateSetTheme(this);
// AFTER SETTING THEME
setContentView(R.layout.activity_theme);
}
First of all, this question asks a very similar question. However, my question has a subtle difference.
What I'd like to know is whether it is possible to programmatically change the colorPrimary attribute of a theme to an arbitrary color?
So for example, we have:
<style name="AppTheme" parent="android:Theme.Material.Light">
<item name="android:colorPrimary">#ff0000</item>
<item name="android:colorAccent">#ff0000</item>
</style>
At runtime, the user decides he wants to use #ccffff as a primary color. Ofcourse there's no way I can create themes for all possible colors.
I don't mind if I have to do hacky stuff, like relying on Android's private internals, as long as it works using the public SDK.
My goal is to eventually have the ActionBar and all widgets like a CheckBox to use this primary color.
Themes are immutable, you can't.
I read the comments about contacts app and how it use a theme for each contact.
Probably, contacts app has some predefine themes (for each material primary color from here: http://www.google.com/design/spec/style/color.html).
You can apply a theme before a the setContentView method inside onCreate method.
Then the contacts app can apply a theme randomly to each user.
This method is:
setTheme(R.style.MyRandomTheme);
But this method has a problem, for example it can change the toolbar color, the scroll effect color, the ripple color, etc, but it cant change the status bar color and the navigation bar color (if you want to change it too).
Then for solve this problem, you can use the method before and:
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.md_red_500));
getWindow().setStatusBarColor(getResources().getColor(R.color.md_red_700));
}
This two method change the navigation and status bar color.
Remember, if you set your navigation bar translucent, you can't change its color.
This should be the final code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.MyRandomTheme);
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.myrandomcolor1));
getWindow().setStatusBarColor(getResources().getColor(R.color.myrandomcolor2));
}
setContentView(R.layout.activity_main);
}
You can use a switch and generate random number to use random themes, or, like in contacts app, each contact probably has a predefine number associated.
A sample of theme:
<style name="MyRandomTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/myrandomcolor1</item>
<item name="colorPrimaryDark">#color/myrandomcolor2</item>
<item name="android:navigationBarColor">#color/myrandomcolor1</item>
</style>
You can use Theme.applyStyle to modify your theme at runtime by applying another style to it.
Let's say you have these style definitions:
<style name="DefaultTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/md_lime_500</item>
<item name="colorPrimaryDark">#color/md_lime_700</item>
<item name="colorAccent">#color/md_amber_A400</item>
</style>
<style name="OverlayPrimaryColorRed">
<item name="colorPrimary">#color/md_red_500</item>
<item name="colorPrimaryDark">#color/md_red_700</item>
</style>
<style name="OverlayPrimaryColorGreen">
<item name="colorPrimary">#color/md_green_500</item>
<item name="colorPrimaryDark">#color/md_green_700</item>
</style>
<style name="OverlayPrimaryColorBlue">
<item name="colorPrimary">#color/md_blue_500</item>
<item name="colorPrimaryDark">#color/md_blue_700</item>
</style>
Now you can patch your theme at runtime like so:
getTheme().applyStyle(R.style.OverlayPrimaryColorGreen, true);
The method applyStylehas to be called before the layout gets inflated! So unless you load the view manually you should apply styles to the theme before calling setContentView in your activity.
Of course this cannot be used to specify an arbitrary color, i.e. one out of 16 million (2563) colors. But if you write a small program that generates the style definitions and the Java code for you then something like one out of 512 (83) should be possible.
What makes this interesting is that you can use different style overlays for different aspects of your theme. Just add a few overlay definitions for colorAccent for example. Now you can combine different values for primary color and accent color almost arbitrarily.
You should make sure that your overlay theme definitions don't accidentally inherit a bunch of style definitions from a parent style definition. For example a style called AppTheme.OverlayRed implicitly inherits all styles defined in AppTheme and all these definitions will also be applied when you patch the master theme. So either avoid dots in the overlay theme names or use something like Overlay.Red and define Overlay as an empty style.
I've created some solution to make any-color themes, maybe this can be useful for somebody. API 9+
1. first create "res/values-v9/" and put there this file: styles.xml
and regular "res/values" folder will be used with your styles.
2. put this code in your res/values/styles.xml:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#000</item>
<item name="colorPrimaryDark">#000</item>
<item name="colorAccent">#000</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDarkActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#000</item>
<item name="colorPrimaryDark">#000</item>
<item name="colorAccent">#000</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#android:anim/fade_in</item>
<item name="android:windowExitAnimation">#android:anim/fade_out</item>
</style>
</resources>
3. in to AndroidManifest:
<application android:theme="#style/AppThemeDarkActionBar">
4. create a new class with name "ThemeColors.java"
public class ThemeColors {
private static final String NAME = "ThemeColors", KEY = "color";
#ColorInt
public int color;
public ThemeColors(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
String stringColor = sharedPreferences.getString(KEY, "004bff");
color = Color.parseColor("#" + stringColor);
if (isLightActionBar()) context.setTheme(R.style.AppTheme);
context.setTheme(context.getResources().getIdentifier("T_" + stringColor, "style", context.getPackageName()));
}
public static void setNewThemeColor(Activity activity, int red, int green, int blue) {
int colorStep = 15;
red = Math.round(red / colorStep) * colorStep;
green = Math.round(green / colorStep) * colorStep;
blue = Math.round(blue / colorStep) * colorStep;
String stringColor = Integer.toHexString(Color.rgb(red, green, blue)).substring(2);
SharedPreferences.Editor editor = activity.getSharedPreferences(NAME, Context.MODE_PRIVATE).edit();
editor.putString(KEY, stringColor);
editor.apply();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) activity.recreate();
else {
Intent i = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivity(i);
}
}
private boolean isLightActionBar() {// Checking if title text color will be black
int rgb = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3;
return rgb > 210;
}
}
5. MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new ThemeColors(this);
setContentView(R.layout.activity_main);
}
public void buttonClick(View view){
int red= new Random().nextInt(255);
int green= new Random().nextInt(255);
int blue= new Random().nextInt(255);
ThemeColors.setNewThemeColor(MainActivity.this, red, green, blue);
}
}
To change color, just replace Random with your RGB, Hope this helps.
There is a complete example: ColorTest.zip
You can have a look at this GitHub project from Rumit Patel.
I used the Dahnark's code but I also need to change the ToolBar background:
if (dark_ui) {
this.setTheme(R.style.Theme_Dark);
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setNavigationBarColor(getResources().getColor(R.color.Theme_Dark_primary));
getWindow().setStatusBarColor(getResources().getColor(R.color.Theme_Dark_primary_dark));
}
} else {
this.setTheme(R.style.Theme_Light);
}
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.app_bar);
if(dark_ui) {
toolbar.setBackgroundColor(getResources().getColor(R.color.Theme_Dark_primary));
}
You can change define your own themes, or customize existing android themes in res > values > themes, find where it says primary color and point it to the color defined in color.xml you want
<style name="Theme.HelloWorld" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#color/my_color</item>
<item name="colorPrimaryVariant">#color/my_color</item>
<item name="colorOnPrimary">#color/white</item>
from an activity you can do:
getWindow().setStatusBarColor(i color);
You cannot change the color of colorPrimary, but you can change the theme of your application by adding a new style with a different colorPrimary color
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
</style>
<style name="AppTheme.NewTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/colorOne</item>
<item name="colorPrimaryDark">#color/colorOneDark</item>
</style>
and inside the activity set theme
setTheme(R.style.AppTheme_NewTheme);
setContentView(R.layout.activity_main);
USE A TOOLBAR
You can set a custom toolbar item color dynamically by creating a custom toolbar class:
package view;
import android.app.Activity;
import android.content.Context;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.support.v7.internal.view.menu.ActionMenuItemView;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomToolbar extends Toolbar{
public CustomToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
public CustomToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomToolbar(Context context) {
super(context);
// TODO Auto-generated constructor stub
ctxt = context;
}
int itemColor;
Context ctxt;
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.d("LL", "onLayout");
super.onLayout(changed, l, t, r, b);
colorizeToolbar(this, itemColor, (Activity) ctxt);
}
public void setItemColor(int color){
itemColor = color;
colorizeToolbar(this, itemColor, (Activity) ctxt);
}
/**
* Use this method to colorize toolbar icons to the desired target color
* #param toolbarView toolbar view being colored
* #param toolbarIconsColor the target color of toolbar icons
* #param activity reference to activity needed to register observers
*/
public static void colorizeToolbar(Toolbar toolbarView, int toolbarIconsColor, Activity activity) {
final PorterDuffColorFilter colorFilter
= new PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.SRC_IN);
for(int i = 0; i < toolbarView.getChildCount(); i++) {
final View v = toolbarView.getChildAt(i);
doColorizing(v, colorFilter, toolbarIconsColor);
}
//Step 3: Changing the color of title and subtitle.
toolbarView.setTitleTextColor(toolbarIconsColor);
toolbarView.setSubtitleTextColor(toolbarIconsColor);
}
public static void doColorizing(View v, final ColorFilter colorFilter, int toolbarIconsColor){
if(v instanceof ImageButton) {
((ImageButton)v).getDrawable().setAlpha(255);
((ImageButton)v).getDrawable().setColorFilter(colorFilter);
}
if(v instanceof ImageView) {
((ImageView)v).getDrawable().setAlpha(255);
((ImageView)v).getDrawable().setColorFilter(colorFilter);
}
if(v instanceof AutoCompleteTextView) {
((AutoCompleteTextView)v).setTextColor(toolbarIconsColor);
}
if(v instanceof TextView) {
((TextView)v).setTextColor(toolbarIconsColor);
}
if(v instanceof EditText) {
((EditText)v).setTextColor(toolbarIconsColor);
}
if (v instanceof ViewGroup){
for (int lli =0; lli< ((ViewGroup)v).getChildCount(); lli ++){
doColorizing(((ViewGroup)v).getChildAt(lli), colorFilter, toolbarIconsColor);
}
}
if(v instanceof ActionMenuView) {
for(int j = 0; j < ((ActionMenuView)v).getChildCount(); j++) {
//Step 2: Changing the color of any ActionMenuViews - icons that
//are not back button, nor text, nor overflow menu icon.
final View innerView = ((ActionMenuView)v).getChildAt(j);
if(innerView instanceof ActionMenuItemView) {
int drawablesCount = ((ActionMenuItemView)innerView).getCompoundDrawables().length;
for(int k = 0; k < drawablesCount; k++) {
if(((ActionMenuItemView)innerView).getCompoundDrawables()[k] != null) {
final int finalK = k;
//Important to set the color filter in seperate thread,
//by adding it to the message queue
//Won't work otherwise.
//Works fine for my case but needs more testing
((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
// innerView.post(new Runnable() {
// #Override
// public void run() {
// ((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
// }
// });
}
}
}
}
}
}
}
then refer to it in your layout file. Now you can set a custom color using
toolbar.setItemColor(Color.Red);
Sources:
I found the information to do this here: How to dynamicaly change Android Toolbar icons color
and then I edited it, improved upon it, and posted it here: GitHub:AndroidDynamicToolbarItemColor
This is what you CAN do:
write a file in drawable folder, lets name it background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="?attr/colorPrimary"/>
</shape>
then set your Layout's (or what so ever the case is) android:background="#drawable/background"
on setting your theme this color would represent the same.
I create many activities and classes in my app. However I have a function to change font size and color in every activity. This function changes text in own activity. When I go to other activity I must change textSize and color again. How can I create a function to change TextView in many classes and activities in one shot?
My app Structure:
Main.java main.xml/
Suad1.java suad1.xml/
Suad2.java suad2.xml/
Suad3.java suad3.xml/
Suad4.java suad4.xml/
I want to change these activity in one time. Here my code in Suad1.class.
public void ShowDialog() {
final AlertDialog.Builder popDialog = new AlertDialog.Builder(this);
final SeekBar seek = new SeekBar(this);
seek.getProgress();
seek.setMax(100);
popDialog.setIcon(R.drawable.conp);
popDialog.setTitle(R.string.menu_settings);
popDialog.setView(seek);
try {
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
subtitles.setTextSize(progress);
}
});
}
catch (Exception e) {
e.printStackTrace();
}
popDialog.setSingleChoiceItems(items , -1,
new DialogInterface.OnClickListener() {
int i;
public void onClick(DialogInterface dialog, int item) {
i = item;
if(items[i] =="Blue") {
subtitles.setTextColor(getResources().getColor(R.color.font3));
} else if(items[i] == "Yellow") {
subtitles.setTextColor(getResources().getColor(R.color.font1));
} else if(items[i]== "Red") {
subtitles.setTextColor(getResources().getColor(R.color.font2));
}
}
}
);
// Button
popDialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(Suad1.this, "Your setting is complete", Toast.LENGTH_LONG).show();
dialog.dismiss();
}
}
);
popDialog.create();
popDialog.show();
}
And two more questions:
Can I update SeekBar when out dialog and back again?
Can I have two Titles or more in one AlertDialog?
Create a separate class with method which you can use in multiple Activities for Changing TextView text,color :
public class ChangetextAttr {
public Activity context;
public ChangetextAttr(Activity context){
this.context=context;
}
// Create an Method for Changing TextView Attributes
public void settextViewAttr(Activity activity, TextView txtView){
txtView.setTextSize(15);
txtView.setTextColor(activity.getResources().getColor(R.color.font1));
//....
}
and from Any Activity you can settextViewAttr method for setting TextView Attributes :
ChangetextAttr obj=new ChangetextAttr(Your_Activity.this);
obj.settextViewAttr(this,any_textview_instance);
Hey create a(Customized textview) class which extends TextView and do whatever you want to do for the textview like changing text color and textstyle. now use this class in all your xml's . if your class name MyTextView. then your xml should be like the following...
<urpackage.MyTextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
To answer your questions:
1- What you need is two styles (Bold & normal) and change between the used style for Text using View.setTextAppearance. Check Android documentaion and this answer.
2- To update seekbar with a value that is unchanged from View to View, then you need to keep its progress in a shared preference for e.g. and set the progress in onResume.
3- Consider using a custom Dialog instead (you can define it in XML as you wish). Or you can include /n to have multi lines in the Title string
Android provides you with mechanisms already to change the appearance of widgets, via Styles and Themes.
Here is how you define a style that sets the text size and color of any view that holds text:
<style name="BigColoredText">
<item name="android:textColor">#FF0000</item>
<item name="android:textSize">25sp</item>
</style>
and here is how you apply it to a TextView:
<TextView style="#style/BigColoredText" .../>
Styles can only be supplied to Views at construction time, you cannot change it afterwards. However, you can programmatically change the textAppearance with is the subset of a style that refers to text attributes via:
TextView v = ...;
v.setTextAppearance(R.styles.BigColoredText);
Now, if you want all TextViews within your Activity or Application using that same style (or at least use it by default), then you need a Theme:
<style name="Theme.MyTheme" parent="#android:style/Theme">
<item name="android:textViewStyle">#style/BigColoredText</item>
</style>
and then apply the theme to either the entire Application or one or more Activities in your manifest:
<application or activity android:theme="#style/Theme.MyTheme" .../>
Or you can change it programmatically at runtime via:
Activity activity = ...;
activity.setTheme(R.style.Theme_MyTheme);
I am writing a program with only one button. At beginning, the button is in default color; when clicking on the button, it's background color turns to red, and then clicking once more, its background color turns to it's default color. Any suggestion on writing a code in myButton.setOnClickListener(new OnClickListener(){} method? Thanks
// Class member variable
private Drawable defaultDrawable;
myButton.setOnClickListener(new OnClickListener()
{
if(defaultDrawable == null)
{
defaultDrawable = myButton.getDrawable();
myButton.setBackgroundColor(Color.BLUE);
}
else
{
myButton.setBackgroundDrawable(defaultDrawable);
defaultDrawable=null;
}
}
You can definitely improve the logic to be more readable.
Also you can simply use ToggleButton, which has two states. Each state has its own background drawable/color which you can specify in xml file. No need of listener.
you can do simply this:
boolean isSelected = false;
int color1 = R.color.mycolor1;
int color2 = R.color.mycolor2;
myButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(isSelected){
btn.setBackgroundColor( color1 );
} else {
btn.setBackgroundColor( color2 );
}
isSelected = !isSelected;
}
});
Another solution is to extend the Button Class, storing your isSelected flag as a member class. In this way, you can reuse this kind of button wherever you need.
You can get the color from the R.attr.buttonStyle of your current theme like so:
public static int getAttrResId( Context context, int attrId ) {
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute( attrId, outValue, true );
return outValue.resourceId;
}
I have a field where the user can type a search query in the action bar of the application. This is declared in the action bar using a menu inflate in the Activity:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:id="#+id/action_search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"
android:title="#string/search"
></item>
</menu>
I need to customize the appearance of the SearchView (for instance background and text color). So far I could not find a way to do it using XML (using styles or themes).
Is my only option to do it in the code when inflating the menu?
Edit #1: I have tried programmatically but I cannot get a simple way to set the text color. Plus when I do searchView.setBackgroundResource(...) The background is set on the global widget, (also when the SearchView is iconified).
Edit #2: Not much information on the Search Developer Reference either
Seibelj had an answer that is good if you want to change the icons. But you'll need to
do it for every API version. I was using ICS with ActionBarSherlock and it didn't do justice for me but it did push me in the correct direction.
Below I change the text color and hint color. I showed how you might go about changing the
icons too, though I have no interest in that for now (and you probably want to use the default icons anyways to be consistent)
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Set up the search menu
SearchView searchView = (SearchView)menu.findItem(R.id.action_search).getActionView();
traverseView(searchView, 0);
return true;
}
private void traverseView(View view, int index) {
if (view instanceof SearchView) {
SearchView v = (SearchView) view;
for(int i = 0; i < v.getChildCount(); i++) {
traverseView(v.getChildAt(i), i);
}
} else if (view instanceof LinearLayout) {
LinearLayout ll = (LinearLayout) view;
for(int i = 0; i < ll.getChildCount(); i++) {
traverseView(ll.getChildAt(i), i);
}
} else if (view instanceof EditText) {
((EditText) view).setTextColor(Color.WHITE);
((EditText) view).setHintTextColor(R.color.blue_trans);
} else if (view instanceof TextView) {
((TextView) view).setTextColor(Color.WHITE);
} else if (view instanceof ImageView) {
// TODO dissect images and replace with custom images
} else {
Log.v("View Scout", "Undefined view type here...");
}
}
adding my take on things which is probably a little more efficient and safe across different android versions.
you can actually get a numeric ID value from a string ID name. using android's hierarchyviewer tool, you can actually find the string IDs of the things you are interested in, and then just use findViewById(...) to look them up.
the code below sets the hint and text color for the edit field itself. you could apply the same pattern for other aspects that you wish to style.
private static synchronized int getSearchSrcTextId(View view) {
if (searchSrcTextId == -1) {
searchSrcTextId = getId(view, "android:id/search_src_text");
}
return searchSrcTextId;
}
private static int getId(View view, String name) {
return view.getContext().getResources().getIdentifier(name, null, null);
}
#TargetApi(11)
private void style(View view) {
ImageView iv;
AutoCompleteTextView actv = (AutoCompleteTextView) view.findViewById(getSearchSrcTextId(view));
if (actv != null) {
actv.setHint(getDecoratedHint(actv,
searchView.getContext().getResources().getString(R.string.titleApplicationSearchHint),
R.drawable.ic_ab_search));
actv.setTextColor(view.getContext().getResources().getColor(R.color.ab_text));
actv.setHintTextColor(view.getContext().getResources().getColor(R.color.hint_text));
}
}
You can use the attribute android:actionLayout instead which lets you specify a layout to be inflated. Just have a layout with your SearchView and you won't have to modify anything really.
As to changing text style on the SearchView that is probably not possible as the SearchView is a ViewGroup. You should probably try changing text color via themes instead.
In case anyone wants to modify the views directly, here is how you can change the colors/fonts/images and customize the search box to your pleasure. It is wrapped in a try/catch in case there are differences between versions or distributions, so it won't crash the app if this fails.
// SearchView structure as we currently understand it:
// 0 => linearlayout
// 0 => textview (not sure what this does)
// 1 => image view (the search icon before it's pressed)
// 2 => linearlayout
// 0 => linearlayout
// 0 => ImageView (Search icon on the left of the search box)
// 1 => SearchView$SearchAutoComplete (Object that controls the text, subclass of TextView)
// 2 => ImageView (Cancel icon to the right of the text entry)
// 1 => linearlayout
// 0 => ImageView ('Go' icon to the right of cancel)
// 1 => ImageView (not sure what this does)
try {
LinearLayout ll = (LinearLayout) searchView.getChildAt(0);
LinearLayout ll2 = (LinearLayout) ll.getChildAt(2);
LinearLayout ll3 = (LinearLayout) ll2.getChildAt(0);
LinearLayout ll4 = (LinearLayout) ll2.getChildAt(1);
TextView search_text = (TextView) ll3.getChildAt(1);
search_text.setTextColor(R.color.search_text);
ImageView cancel_icon = (ImageView)ll3.getChildAt(2);
ImageView accept_icon = (ImageView)ll4.getChildAt(0);
cancel_icon.setBackgroundDrawable(d);
accept_icon.setBackgroundDrawable(d);
} catch (Throwable e) {
Log.e("SearchBoxConstructor", "Unable to set the custom look of the search box");
}
This example shows changing the text color and the background colors of the cancel/accept images. searchView is a SearchView object already instantiated with it's background color:
Drawable d = getResources().getDrawable(R.drawable.search_widget_background);
searchView.setBackgroundDrawable(d);
Here is the drawable code:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/white" />
</shape>
Obviously, this is hacky, but it will work for now.
From ICS this is doable using themes and styles. I'm using ActionBarSherlock which makes it applicable also for HC and below.
Add a style to define "android:textColorHint":
<style name="Theme.MyHolo.widget" parent="#style/Theme.Holo">
<item name="android:textColorHint">#color/text_hint_corp_dark</item>
</style>
Apply this as "actionBarWidgetTheme" to your theme:
<style name="Theme.MyApp" parent="#style/Theme.Holo.Light.DarkActionBar">
...
<item name="android:actionBarWidgetTheme">#style/Theme.MyHolo.widget</item>
</style>
Presto! Make sure that you use getSupportActionBar().getThemedContext() (or getSupportActionBar() for ActionBarSherlock) if any widgets are initiated where you might have other themes in effect.
How do you inflate the menu xml in your Activity? if you inflate the menu by using getMenuInflator() in your Activity, then the menu and also the searchView get the themed context, that have attached to the activity.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater.inflate(R.menu.search_action_menu, menu);
}
if you check the source code of Activity.getMenuInflator() at API-15, you can see the themed context codes. Here it is.
*/
public MenuInflater getMenuInflater() {
// Make sure that action views can get an appropriate theme.
if (mMenuInflater == null) {
initActionBar();
if (mActionBar != null) {
mMenuInflater = new MenuInflater(mActionBar.getThemedContext());
} else {
mMenuInflater = new MenuInflater(this);
}
}
return mMenuInflater;
}