I have a list view and when the user taps down on the item it looks like this.
This is what it looks like noramally:
How do I change this default light blue color?
I need the color to be set programatically in the activity file, as it is not always the same color, and also how do you change the color of the fuzzy stuff that comes up at the bottom of a ListView when you continue to scroll down?
Thanks for the help
EDIT
Also how do you change the tap down color of the action bar back button,
For the row color, you need to create a StateListDrawable and set it as the selector for the ListView.
The states to include should be, at least:
pressed (android.R.attr.state_pressed)
selected (android.R.attr.state_selected)
"normal" (empty state list)
For each state you can set any drawable. If what you need is a plain color, you can programmatically create a ColorDrawable on the spot.
For example:
StateListDrawable selector = new StateListDrawable();
ColorDrawable red = new ColorDrawable(Color.RED);
ColorDrawable transparent = new ColorDrawable(Color.TRANSPARENT);
selector.addState(new int[] { android.R.attr.state_pressed }, red);
selector.addState(new int[] { android.R.attr.state_selected }, red);
selector.addState(new int[] { }, transparent);
listView.setSelector(selector);
As for the "fuzzy stuff that comes up at the bottom", it's slightly more complicated.
Prior to Android 5.0 there was no public API for changing it.
In Lollipop it can be set via the theme, but not programmatically.
For pre-5.0 there is a well-known workaround (described here) which involves tampering with the drawables that are used. However this solution crashes in 5.0, because those resources do not exist anymore.
For Android 5.0, if a static color is acceptable, you can just configure the new theme attribute android:colorEdgeEffect (which is the same as android:colorPrimary by default).
If a programmatic solution for Android 5.0 is necessary, you could alternatively change the EdgeEffect objects that the ListView has internally using reflection. I've tested this and it works, though it's not the prettiest code:
EdgeEffect edgeEffectTop = new EdgeEffect(this);
edgeEffectTop.setColor(Color.RED);
EdgeEffect edgeEffectBottom = new EdgeEffect(this);
edgeEffectBottom.setColor(Color.RED);
try {
Field f1 = AbsListView.class.getDeclaredField("mEdgeGlowTop");
f1.setAccessible(true);
f1.set(listView, edgeEffectTop);
Field f2 = AbsListView.class.getDeclaredField("mEdgeGlowBottom");
f2.setAccessible(true);
f2.set(listView, edgeEffectBottom);
} catch (Exception e) {
e.printStackTrace();
}
Therefore, a full programmatic solution may run something like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
// For Android >= 5.0, use setColor() on EdgeEffect
EdgeEffect edgeEffectTop = new EdgeEffect(this);
edgeEffectTop.setColor(Color.RED);
EdgeEffect edgeEffectBottom = new EdgeEffect(this);
edgeEffectBottom.setColor(Color.RED);
try {
Field f1 = AbsListView.class.getDeclaredField("mEdgeGlowTop");
f1.setAccessible(true);
f1.set(listView, edgeEffectTop);
Field f2 = AbsListView.class.getDeclaredField("mEdgeGlowBottom");
f2.setAccessible(true);
f2.set(listView, edgeEffectBottom);
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
// For Android < 5.0, change overscroll_glow and overscroll_edge
int glowDrawableId = getResources().getIdentifier("overscroll_glow", "drawable", "android");
Drawable androidGlow = getResources().getDrawable(glowDrawableId);
androidGlow.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
int edgeDrawableId = getResources().getIdentifier("overscroll_edge", "drawable", "android");
Drawable androidEdge = getResources().getDrawable(edgeDrawableId);
androidEdge.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
}
How do I change this default light blue color?
you have to create StateListDrawable and set it as the selector for the ListView. the answer of matiash is good and I do not want to explain it again.
change the color of the fuzzy stuff that comes up at the bottom of a
ListView when you continue to scroll down
setCacheColorHint (int color)
Also how do you change the tap down color of the action bar back
button
<style name="actionbarCustomBackground" parent="#style/Theme.Holo.Light" >
<item name="android:selectableItemBackground">#drawable/actionbar_item_background</item>
</style>
then in the actionbar_item_background:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item
android:state_focused="true"
android:state_pressed="true"
android:drawable="#android:color/holo_orange_dark" />
<item
android:state_pressed="true"
android:drawable="#android:color/holo_orange_dark" />
<item
android:drawable="#android:color/transparent" />
</selector>
You can set row's background dynamically in getView(..) method.
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
.......... //your code
view.setBackgroundColor(Color.RED)
return view;
}
Related
I have two buttons in my layout like this:
The one on the left has android:backgroundTint="?attr/colorAccent" and correctly displays purple. The button on the right has android:backgroundTint="#color/button_color" where #color/button_color is defined in XML as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#color/gray"/>
<item android:color="?attr/colorAccent" />
</selector>
On android versions >22, both buttons correctly display purple, however on API 21 and 22 only (I haven't tested below as my app only supports >=21), the button that uses android:backgroundTint="#color/button_color" shows a (seemingly random) red color.
How can i make ?attr/colorAccent display the correct color when used in button_color.xml?
I am still unsure what causes this issue but i have worked around it by applying the ColorStateList in code like this:
button.setBackgroundTintList(
new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_enabled}, //Disabled
new int[]{} //Default
},
new int[]{
disabledColor,
defaultColor
}
)
);
To set defaultColor equal to the accent color attribute, i use the following method:
public static int getAccentColor(final Context context) {
final TypedValue typedValue = new TypedValue();
final TypedArray a = context.obtainStyledAttributes(typedValue.data, new int[]{android.R.attr.colorAccent});
final int color = a.getColor(0, 0);
a.recycle();
return color;
}
Is there any way to set the background color of the new design libraries BottomNavigationView in code to a custom color value instead of a color resource? Any "trick" maybe?
My current solution:
I make the BottomNavigationView transparent
I add a second view behind the bottomNavigationView
I update this view's background
But this looks ugly, especially as I have to use a custom behaviour for the background view to be animated in parallel with the BottomNavigationView in the parent CoordinatorLayout...
Solved it myself.
Solution 1
I just setup all items with a transparent background (this needs one resource file only) and then I theme the BottomNavigationView actual background itself.
bottomBar.setBackground(new ColorDrawable(color));
bottomBar.setItemBackgroundResource(R.drawable.transparent);
Resource drawable - transparent.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#android:color/transparent" />
</shape>
Solution 2 - via reflection (support library 25.0.0)
public void themeBottomBarBackgroundWithReflection(BottomNavigationView bottomBar, int color)
{
try
{
Field mMenuViewField = BottomNavigationView.class.getDeclaredField("mMenuView");
mMenuViewField.setAccessible(true);
BottomNavigationMenuView mMenuView = (BottomNavigationMenuView)mMenuViewField.get(bottomBar);
Field mButtonsField = BottomNavigationMenuView.class.getDeclaredField("mButtons");
mButtonsField.setAccessible(true);
BottomNavigationItemView[] mButtons = (BottomNavigationItemView[])mButtonsField.get(mMenuView);
for (BottomNavigationItemView item : mButtons) {
ViewCompat.setBackground(item, new ColorDrawable(color));
}
}
catch (NoSuchFieldException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
After many search, only this resolve my case:
bottomNavigationView.setItemBackground(new ColorDrawable(color));
Here I set each one of background item.
I used the following hack to change the homeAsupIndicator programmatically.
int upId = Resources.getSystem().getIdentifier("up", "id", "android");
if (upId > 0) {
ImageView up = (ImageView) findViewById(upId);
up.setImageResource(R.drawable.ic_action_bar_menu);
up.setPadding(0, 0, 20, 0);
}
But this is not working on most new phones (HTC One, Galaxy S3, etc). Is there a way that can be changed uniformly across devices. I need it to be changed only on home screen. Other screens would have the default one. So cannot use the styles.xml
This is what i did to acheive the behavior. I inherited the base theme and created a new theme to use it as a theme for the specific activity.
<style name="CustomActivityTheme" parent="AppTheme">
<item name="android:homeAsUpIndicator">#drawable/custom_home_as_up_icon</item>
</style>
and in the android manifest i made the activity theme as the above.
<activity
android:name="com.example.CustomActivity"
android:theme="#style/CustomActivityTheme" >
</activity>
works great. Will update again when i check on all devices I have. Thanks #faylon for pointing in the right direction
The question was to change dynamically the Up Home Indicator, although this answer was accepting and it is about Themes and Styles. I found a way to do this programmatically, according to Adneal's answer which gives me the clue and specially the right way to do. I used the below snippet code and it works well on (tested) devices with APIs mentioned here.
For lower APIs, I use R.id.up which is not available on higher API. That's why, I retrieve this id by a little workaround which is getting the parent of home button (android.R.id.home) and its first child (android.R.id.up):
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// get the parent view of home (app icon) imageview
ViewGroup home = (ViewGroup) findViewById(android.R.id.home).getParent();
// get the first child (up imageview)
( (ImageView) home.getChildAt(0) )
// change the icon according to your needs
.setImageResource(R.drawable.custom_icon_up));
} else {
// get the up imageview directly with R.id.up
( (ImageView) findViewById(R.id.up) )
.setImageResource(R.drawable.custom_icon_up));
}
Note: If you don't use the SDK condition, you will get some NullPointerException.
API 18 has new methods ActionBar.setHomeAsUpIndicator() - unfortunately these aren't supported in the support library at this moment
http://developer.android.com/reference/android/app/ActionBar.html#setHomeAsUpIndicator(android.graphics.drawable.Drawable)
edit: these are now supported by the support library
http://developer.android.com/reference/android/support/v7/app/ActionBar.html#setHomeAsUpIndicator(android.graphics.drawable.Drawable)
All you need to do is to use this line of code:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
This will change the icon with the up indicator. To disable it later, just call this function again and pass false as the param.
The solution by checking Resources.getSystem() doesn't work on all devices, A better solution to change the homeAsUpIndicator is to set it #null in style and change the logo resource programmatically.
Below is my code from style.xml
<style name="Theme.HomeScreen" parent="AppBaseTheme">
<item name="displayOptions">showHome|useLogo</item>
<item name="homeAsUpIndicator">#null</item>
<item name="android:homeAsUpIndicator">#null</item>
</style>
In code you can change the logo using setLogo() method.
getSupportActionBar().setLogo(R.drawable.abc_ic_ab_back_holo_light); //for ActionBarCompat
getActionBar().setLogo(R.drawable.abc_ic_ab_back_holo_light); //for default actionbar for post 3.0 devices
Also note that the Android API 18 has methods to edit the homeAsUpIndicator programatically, refer documentation.
You can achieve this in an easier way. Try to can change the homeAsUpIndicator attribute of actionBarStyle in your theme.xml and styles.xml.
If you want some padding, just add some white space in your image.
You can try this:
this.getSupportActionBar().setHomeAsUpIndicator( R.drawable.actionbar_indicator ); //for ActionBarCompat
this.getActionBar().setHomeAsUpIndicator( R.drawable.actionbar_indicator ); //for default actionbar for post 3.0 devices
If you need change the position of the icon, you must create a drawable file containing a "layer-list" like this:
actionbar_indicator.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="#drawable/indicator"
android:right="5dp"
android:left="10dp" />
</layer-list>
use getActionBar().setCustomView(int yourView); because ActionBar haven't method to change homeUp icon!
Adding to Fllo answer Change the actionbar homeAsUpIndicator Programamtically
I was able to use this hack on Android 4+ but could not understand why the up/home indicator was back to the default one when search widget was expanded. Looking at the view hierarchy, turns out that the up/home indicator + icon section of the action bar has 2 implementations and of course the first on is the one for when the search widget is not expanded. So here is the code I used to work around this and get the up/home indicator changed in both cases.
mSearchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
// https://stackoverflow.com/questions/17585892/change-the-actionbar-homeasupindicator-programamtically
int actionBarId = getResources().getIdentifier("android:id/action_bar", null, null);
View view = getActivity().getWindow().getDecorView().findViewById(actionBarId);
if (view == null
|| !(view instanceof ViewGroup)) {
return true;
}
final ViewGroup actionBarView = (ViewGroup)view;
// The second home view is only inflated after
// setOnActionExpandListener() is first called
actionBarView.post(new Runnable() {
#Override
public void run() {
//The 2 ActionBarView$HomeView views are always children of the same view group
//However, they are not always children of the ActionBarView itself
//(depends on OS version)
int upId = getResources().getIdentifier("android:id/up", null, null);
View upView = actionBarView.findViewById(upId);
ViewParent viewParent = upView.getParent();
if (viewParent == null) {
return;
}
viewParent = viewParent.getParent();
if (viewParent == null
|| !(viewParent instanceof ViewGroup)) {
return;
}
ViewGroup viewGroup = (ViewGroup) viewParent;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = viewGroup.getChildAt(i);
if (childView instanceof ViewGroup) {
ViewGroup homeView = (ViewGroup) childView;
upView = homeView.findViewById(upId);
if (upView != null
&& upView instanceof ImageView) {
Drawable upDrawable = getResources().getDrawable(R.drawable.ic_ab_back_holo_dark_am);
upDrawable.setColorFilter(accentColorInt, PorterDuff.Mode.MULTIPLY);
((ImageView) upView).setImageDrawable(upDrawable);
}
}
}
}
});
If someone uses the library support-v7 appcompat, you can directly call this method:
getSupportActionBar().setHomeAsUpIndicator(int redId)
In other case you can use this solution:
https://stackoverflow.com/a/23522910/944630
If you are using DrawerLayout with ActionBarDrawerToggle, then check out this answer.
this.getSupportActionBar().setDisplayUseLogoEnabled(true);
this.getSupportActionBar().setLogo(R.drawable.about_selected);
Also you can define the logo in manifest in attribute android:logo of and tags and set in theme that you want to use logo instead of app icon in the action bar.
I've created a spreadsheet in Android to display the results of a data search using TableRow. The TableRows are dynamically created so there can be up to 30 rows displayed at a time.
I'm trying to toggle the background color of a row when the user touches the row, and can easily change the background color with an android:onClick event. However once the row is clicked and the color changes I cannot toggle the color back when another android:onClick event is initiated.
So how do I determine the color state of the TableRow so I can construct the proper control flow and toggle the color appropriately? There are plenty of examples of how to set the background color, but nothing helpful in GETTING the background color.
Thanks
Try this:
// save old view style
Drawable defaultViewStyle = view.getBackground();
// set new style
view.setBackgroundResource(R.drawable.new_view_style);
// return default view style
view.setBackgroundDrawable(defaultViewStyle);
But I think it's not the right way. It is best to override all of the possible conditions for the view:
// res drawable my_table_row_style:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/my_table_row_style_selected"/>
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/my_table_row_style_selected"/>
<item android:state_focused="true" android:state_pressed="false" android:drawable="#drawable/my_table_row_style_selected"/>
<item android:state_focused="false" android:state_pressed="false" android:drawable="#drawable/my_table_row_style_default"/>
</selector>
Example:
int MyPosition=100000;
...
...
onclick()
{
if(MyPosition==100000)
{
//first time selection
MyPosition=a//a=any int position
//change bg of selected row
}
else
{
//now u r selecting second or N th time
//so first set previous bg of MyPosition
//and clear MyPosition
//Now set bg of current bg nd set MyPosition
}
}
You can save the color you set by setTag() and retrive it by getTag().
void OnClick(View v)
{
Integer color = v.getTag();
if (null == color) // not clicked yet
{
color = COLOR_NOT_TOGLED;
}
if (COLOR_NOT_TOGLED == color)
{
color = COLOR_TOGLED;
}
else
{
color = COLOR_NOT_TOGLED;
}
v.setBackGround(color);
v.setTag(color); // save
}
UPDATE
Ok, let's fix it))
void OnClick(View v)
{
Object o = v.getTag();
Integer color = (null == o) ? COLOR_NOT_TOGLED : (Integer) o;
if (COLOR_NOT_TOGLED == color) {
color = COLOR_TOGLED;
} else {
color = COLOR_NOT_TOGLED;
}
v.setBackgroundColor(color);
v.setTag(color); // save
}
If you take a look in source code of setBackgroundColor() you see how it works:
TableRow tr = (TableRow)v;
Drawable bg = tr.getBackground();
int oldColor = ((ColorDrawable) bg.mutate()).getColor();
I'm creating an application which uses Android 4.0.
I'm wondering if it is possible to change the text color of the text in a switch.
I've tried setting the text color, but it doesn't work.
Any ideas?
Thanks in advance!
You must use android:switchTextAppearance attribute, eg:
android:switchTextAppearance="#style/SwitchTextAppearance"
and in styles:
<style name="SwitchTextAppearance" parent="#android:style/TextAppearance.Holo.Small">
<item name="android:textColor">#color/my_switch_color</item>
</style>
you can also do it in code, also using above styles:
mySwitch.setSwitchTextAppearance(getActivity(), R.style.SwitchTextAppearance);
...and as for setTextColor and Switch - this color will be used if your SwitchTextAppearance style doesn't provide a textColor
you can check it in Switch source code in setSwitchTextAppearance:
ColorStateList colors;
int ts;
colors = appearance.getColorStateList(com.android.internal.R.styleable.
TextAppearance_textColor);
if (colors != null) {
mTextColors = colors;
} else {
// If no color set in TextAppearance, default to the view's textColor
mTextColors = getTextColors();
}
ts = appearance.getDimensionPixelSize(com.android.internal.R.styleable.
TextAppearance_textSize, 0);
if (ts != 0) {
if (ts != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(ts);
requestLayout();
}
}
I think you have to look at the theme which you are using for your application. Because the color of the switch is the responsibility of the theme, afaik. So I would suggest you have a look on how you can change the settings of a theme. Or you could create a custom theme with the new colors.
TextView.setTextColor() takes an int representing the color (eg. 0xFFF5DC49) not the resource id from the xml file. In an activity, you can do something like:
textView1.setTextColor(getResources().getColor(R.color.mycolor))
outside of an activity you'll need a Context eg.
textView1.setTextColor(context.getResources().getColor(R.color.mycolor))
For more refer this