Android Selectors Text Color - android

I've been over way too many StackOverflow questions and still can't get it working.
I dynamically (programmatically) create a number of buttons on my activity. I need to use selectors to change the background and text color depending on if the button is pressed or not.
I've got the background to change from black to white when its pressed, but I can't seem to get the text color to change (or set it for that matter ) - it just defaults to black.
Here's what I've got.
Java file:
monthButtons[i].setBackgroundResource(R.drawable.button_background);
monthButtons[i].setTextColor(R.color.text_color);
button_background.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#color/white"/>
<item android:drawable="#color/black"/>
</selector>
text_color.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:textColor="#color/black" />
<item
android:textColor="#color/white" />
</selector>
Can someone point me to a method to change the text color when the button is pressed? Please bear in mind I don't have anything defined in a layout file for these buttons.
Thanks

Why don't you just use one background xml? Like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#color/white"
android:textColor="#color/black" />
<item android:drawable="#color/black"
android:textColor="#color/white"/>
</selector>//Untested
And set it to be background for the button. If it doesn't work you can always do it programmatically. Hope this helps.
How about this:
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN )
{
button.setBackground("#000");
edittext.setTextColor("#dedede");
return true;
}
else
{
button.setBackground("#dedede");
edittext.setTextColor("#000");
return true;
}
return false;
})); // Untested. Sorry i'm away from pc :(

You can use Color State List Resource to change the text color dynamically:
https://developer.android.com/guide/topics/resources/color-list-resource.html

Related

How to flip between background image and grey color on touch and release of imagebutton?

I am currently working on developing an app with Android. I am new to the game so I could use a little help. I have a page filled with ImageButtons with a few different images. When they get pressed I want the background of the button to go grey and switch back to the original picture when the user is no longer clicking the button.
Thanks for the help!
Check this answer. I think this is related to your question.
For your example, you can have a drawable in your drawable folder. Call it anything. I am calling it button_states.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#drawable/cancel" /> <!-- This can be your image -->
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#color/grey" /> <!-- This can be the color you want to show when the button is pressed. Define this in colors.xml -->
<item
android:state_enabled="true"
android:drawable="#drawable/cancel" /> <!-- Use the same image here -->
</selector>
Finally add this drawable as background of your ImageButton. Like this:
<ImageButton
android:id="#+id/imageButtonSelector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_states" />
You could do something like this:
final ImageButton imgButton = (ImageButton)view.findViewById(R.id.button);
imageButton.setImageResource(R.drawable.imageIdle);
imgButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
imageButton.setImageResource(R.drawable.imagePressed);
return true;
case MotionEvent.ACTION_UP:
imageButton.setImageResource(R.drawable.imageIdle);
return true;
default:
return false;
}
}
});
Hope it helps!

Android. How do I keep a button displayed as PRESSED until the action created by that button is finished? Activated/Selected not usable

I want to keep a ImageButton with a state-list drawable in a "Wait-for-Action-Finished" state as long the action was not done.
I've seen the other topics around this problem. But in my case the other solutions are not working for me because:
I'm using the layout (which contains the buttons) in a RemoteView too (but not only there)
I'm using the same layout in a recyclerview with Multi-Selection capabilities. Therefore the activated/selected state is used by the multi-selector implementation and not possible for the state-list drawable except it was not propagated from selected-item to child views => my butotns
using custom state not working with RemoteViews
Using ToogleButton not possible, because setEnabled is not available for Buttons/ToggleButtons/CompoundButtons in RemoteViews
It's not important that the "Wait-for-Action-Finished" drawable was shown in the RemoteView (but it would be nice...), but I don't want to duplicate the layout. It's okay if the Wait-State was shown in the RecyclerView items only.
But there it should work along with the Multiselector function.
I'm using an ImageButton because it can be disabled in a RemoteView (in opposite to Button/ToggleButton/CompoundButton in general).
any hints how I could solve this?
You will have to manually set the state of the button and keep it there. This solution will give you some insight link
After reading out your question The thing what I understand the solution will be like below.
First set the button.xml as below.Use it as drawable for that button.Each of the state btn_disabled or the btn_pressed is the drawable state of your button which is defined by you.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/btn_disabled" android:state_enabled="false"/>
<item android:drawable="#drawable/btn_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/btn_pressed" android:state_selected="true"/>
<item android:drawable="#drawable/btn_default"/>
</selector>
Next use the code snippet below.
boolean checkActionOpen = false;
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if(!checkActionOpen) {
checkActionOpen = true;
button.setSelected(true);
}
}
});
Then again where the work will go on after the finish you will set checkActionOpen as false and do the button.setSelected(false); action.
I've got it working by combining the selected and activated states.
My button looks like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/progress_small" android:state_activated="true" android:state_selected="true"/>
<item android:drawable="#drawable/btn_bookmark_add_pressed" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="#drawable/btn_bookmark_add_pressed" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="#drawable/btn_bookmark_add_pressed" android:state_focused="true" />
<item android:drawable="#drawable/btn_bookmark_add_normal" android:state_focused="false" android:state_pressed="false" />
</selector>
And my button.onClicklistener looks like this:
public void onClick(View v) {
if (v.isActivated() && v.isSelected()) {
return;
}
v.setActivated(true);
v.setSelected(true);
AppController.getJobManager().addJob(new Job()));
}
This way it won't collide neither with "click the itemView", where selected state will be propagated to all child views (inclusive my buttons) nor with activate the "multi-selection" feature where the activated state will be propagated to all child views.
After the job is finished it will notify (EventBus) the RecyclerView where the ViewHolder can reset both activated and selected state back to false.

Change button background to clicked

When you press on a button in Android it changes color. I want it to stay like that. I mean i want something like this:
Button btn = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
btn.setBackGroundColor(R.drawable.clicked /*clicked style*/ );
}
});
example:
This is a pressed on button. I want it to stay like that after i stop pressing it. Is there a easy way like that:
android.R.drawable.btn_default //this is the default button style, i want the pressed one :D
In your java code write button.setPressed(true);.It will set button in pressed mode. You can change the parameter to true and false when you want to set it pressed and unpressed...
Try using selector:
Define selector.xml in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_pressed_yellow"
android:state_pressed="true" />
<item android:drawable="#drawable/button_normal_green" />
</selector>
and set background of the button to android:background="#drawable/selector" then in the code on the click event of the button set btn.setpressed(true);
So you want it to start non-pressed and then stay pressed after being clicked one?
Try using an OnTouchListener instead adding btn.setPressed(true);:
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
btn.setPressed(true);
}
return true;
}
Take a look of the StateSelector images
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
You can set diferent resources for the diferent states of your button/view. This example set different colors:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/branded_content_pressed_color" android:state_enabled="true" android:state_pressed="true"/>
<item android:drawable="#color/branded_content_pressed_color" android:state_enabled="true" android:state_focused="true"/>
<item android:drawable="#color/branded_content_background_color"/>
</selector>
Then you can set the selector normally
button.setBackgroundResource(R.drawable.selector);
You can try this way either put image as dark when press or color
drawable/selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true" android:drawable="#drawable/buttondark"/>
<item android:state_pressed="true" android:drawable="#drawable/buttondark" />
<item android:drawable="#drawable/button" />
</selector>
inside on-create method write
btn.setBackgroundResource(R.drawable.selector);

Disabled seekBar without dimming

I need to prevent seekbar from user inputs in special cases. If I use setEnabled(false) it becomes gray instead of white.
Is there any method to disable seekbar without dimming or set another drawable for progress in disabled seekbar ?
Yes. It is possible! But you need to override SeekBar's drawableStateChanged function, with something like this:
#Override
protected void drawableStateChanged() {
super.drawableStateChanged();
final Drawable progressDrawable = getProgressDrawable();
if(isEnabled() == false && progressDrawable != null) progressDrawable.setAlpha(255);
}
Actually I was very angry, when I saw hardcoded alpha value in AbsSeekBar:
mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
Because there is no function, which will turn off, or even change disabled alpha value for SeekBar. Just take a look at those lines of code in drawableStateChanged function:
if (progressDrawable != null) {
progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
}
I'm not sure why you'd want to change this, and I don't believe it's good practice to override the visual queue for a user that something is disabled. If it looks active, but doesn't interact, I'm going to be mad at your app.
Regardless, to answer your question, you should look at StateListDrawable this question outlines it specifically for seek bars.
Better solution here....
seekBar.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
You can use setEnabled(false) and set the Theme_disabledAlpha attribute as #Ilya Pikin mentioned above like this:
<item name="android:disabledAlpha">1.0</item>
Android changes alpha value of color to 127 from 255 in disabled state. Just make sure you set it back to 255 after disabling seekbar.
seekBar.post(new Runnable(){
#Override
public void run()
{
seekBar.getProgressDrawable().setAlpha(255);
}
});
view.post is required only if you are unsure that seekbar is rendered yet or not, otherwise just
seekBar.getProgressDrawable().setAlpha(255);
is enough.
I´m a bit late to the party, but here is a solution to solve your question.
First of all I recommand to use com.google.android.material.slider.Slider nowadays. It is much more flexible than the old seekbar was. To do so, use the following import in your gradle file
implementation 'com.google.android.material:material:1.6.0' //1.4.0 or newer
Now create your layout file, let´s it call layout_slider
e.g.:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<com.google.android.material.slider.Slider
android:id="#+id/sbSize"
style="#style/sliderTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:value="25"
android:valueFrom="0.0"
android:valueTo="100.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now open your styles.xml file and create the sliderTheme. It should look like this:
<style name="sliderTheme" parent="Widget.MaterialComponents.Slider">
<item name="trackColorInactive">#color/slider_track_inactive</item>
<item name="thumbColor">#color/slider_thumb_color</item>
<item name="trackColorActive">#color/slider_track_active</item>
</style>
The next step we need to do is create a new Resource Directory named color inside the res folder. (Resource type is color)
Now create a file to change the trackColor for active and inactive state. Let´s name it slider_track_inactive.xml
Copy the following content inside that file:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.24" android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>
the first value is for the active and the second is for the inactive color. Change alpha and color to a value to want. All my sample values are the Google default values.
Now create a file called slider_thumb_color.xml inside the color folder. It should look like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.38" android:color="?attr/colorOnSurface"/>
</selector>
Again, change these values as you want.
Last, create a file called slider_track_active.xml inside the color folder. It should look like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.32" android:color="?attr/colorOnSurface"/>
</selector>
Now you have customized all colors for the disabled slider. There are much more values you can customize with the same technique. All default keys you can customize inside your styles.xml file are:
<item name="haloColor">#color/material_slider_halo_color</item>
<item name="haloRadius">#dimen/mtrl_slider_halo_radius</item>
<item name="labelStyle">#style/Widget.MaterialComponents.Tooltip</item>
<item name="thumbColor">#color/material_slider_thumb_color</item>
<item name="thumbElevation">#dimen/mtrl_slider_thumb_elevation</item>
<item name="thumbRadius">#dimen/mtrl_slider_thumb_radius</item>
<item name="tickColorActive">#color/material_slider_active_tick_marks_color</item>
<item name="tickColorInactive">#color/material_slider_inactive_tick_marks_color</item>
<item name="trackColorActive">#color/material_slider_active_track_color</item>
<item name="trackColorInactive">#color/material_slider_inactive_track_color</item>
<item name="trackHeight">#dimen/mtrl_slider_track_height</item>
<item name="minSeparation">0dp</item>

OnClick change tablerow background color

So I'm trying to find an easy way to get the background color or a table row to change when its clicked on. I've been trying to find a way to call what the background color is and check it but I haven't found a way to call the color. Here is what I have right now.
RowName = (TableRow) findViewById(R.id.RowName);
RowName.setBackgroundColor(Color.TRANSPARENT);
RowName.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (RowName.equals(Color.TRANSPARENT))
RowName.setBackgroundColor(Color.YELLOW);
else if (RowName.equals(Color.YELLOW))
RowName.setBackgroundColor(Color.TRANSPARENT);
}
});
I know that its wrong. Hopefully you can see what I'm trying to accomplish. If not, what I want to do is have the table row start of transparent. When someone clicks on the table row I want it to change to yellow. Then, if they click it again, I want it to change back to transparent. Thanks.
You need to set the background color of your row to a state list drawable (that handles select, pressed, active, non-active).
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
The XML should look something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Active state -->
<item android:state_selected="true" android:state_focused="false"
android:state_pressed="false" android:drawable="#android:color/transparent" />
<!-- Inactive state-->
<item android:state_selected="false" android:state_focused="false"
android:state_pressed="false" android:drawable="#android:color/transparent" />
<!-- Pressed state-->
<item android:state_pressed="true" android:drawable="#android:color/yellow" />
<!-- Selected state (using d-pad) -->
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="false" android:drawable="#android:color/yellow" />
</selector>
So here is what wound up working. Make sure you have your TableRows named. Before my on create I have
private TableRow RowName;
I also have
int state = 0;
. I then add the code
public void RowName(View view) {
switch (state) {
case 0:
RowName.setBackgroundColor(Color.YELLOW);
state = 1;
break;
case 1:
RowName.setBackgroundColor(Color.TRANSPARENT);
state = 0;
break;
}
}
To get it to work, go into your xml and in the OnClick property add RowName or the name of the public void that you are working with.
Enjoy.

Categories

Resources