I want to implement a toggle button in the form of a spinner (or slot machine). Basically it will consist of a large rectangle with the text OFF on it and when the user clicks on it, the words ON are animated onto the rectangle instead of off. Is there an easy way to do this or do you know of a widget which can do this please
WHAT I'VE DONE SO FAR
I have two images, each one of them represent the state that the toggle button can be in (i.e. ON and OFF). I then created a drawable XML file:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/on" android:state_checked="true" android:state_pressed="true"/>
<item android:drawable="#drawable/on" android:state_checked="true" android:state_focused="false"/>
<item android:drawable="#drawable/off" android:state_checked="false" android:state_pressed="true"/>
<item android:drawable="#drawable/off" android:state_checked="false" android:state_focused="false"/>
</selector>
Then I set the background of the ToggleButton to the XML drawable:
<ToggleButton
android:id="#+id/toggleButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btntoggle_selector"
android:textColor="#android:color/white"
android:textOff="OFF"
android:textOn="ON " />
if you want change the state of button programmatically, you need use the method setChecked on the toggle button
// Declare button
private ToggleButton myButton;
...
// Initialise button
myButton = (ToggleButton) findViewById(R.id.myButton);
...
// Sets button text as "OFF" and "ON"
myButton.setText("OFF");
myButton.setText("ON");
myButton.setChecked(false);
...
// Set an on click listener
myButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick() {
myButton.setChecked(true);
// CALL WHATEVER METHOD IS SUPPOSED TO BE CALLED WHEN BUTTON IS PRESSED
}
});
Related
I have a "Like" button that the user can click to "like" something (similar to Facebook).
I need to make it so that after the user has liked something, the text color of the button changes to red.
Here's is my code now:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:color="#color/red" />
<item
android:color="#color/normal" />
</selector>
The button:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Like"
android:textColor="#drawable/like_button" />
The problem is that the text color doesn't stay red when I lift my finger, it only changes to red when I hold my finger over the button.
What should I change?
According to your code you are specifically using:
android:state_pressed="true"
This basically means it is only red when pressed hence the results you are getting
Source: https://developer.android.com/guide/topics/resources/color-list-resource.html
You need to include in your Activity (Java)
Button likeButton = (Button) findViewById(R.id.like_button);
likeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(likeButton.isSelected())
likeButton.setSelected(false);
else
likeButton.setSelected(true);
}
});
You need to include in your Layout (XML)
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/red" android:state_selected="true"/>
<item android:color="#color/red" android:state_pressed="true"/>
<item android:color="#color/normal" android:state_pressed="false"/>
<item android:color="#color/normal"/>
</selector>
<Button
android:id="#+id/like_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/like"
android:layout_gravity="center"
android:text="#string/like" />
Cheers.
In order to "save" the "state" of a "like", you have to update the data model / database behind the button with some boolean indicator that says "yes, this is now liked/unliked".
Your XML selector only says "change color when this is pressed, otherwise revert", it has no logic to say "this is now liked".
You are just stating one state for button that is state pressed.That's why,It is getting red only when you pressed on it.If you want to make the text in Red after pressing the button,Then you should add selector in drawable something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color=""#color/red" android:state_selected="true"/>
<item android:color=""#color/red" android:state_pressed="true"/>
<item android:color="#color/normal" android:state_pressed="false"/>
<item android:color="#color/normal"/>
</selector>
In your activity,put this code:
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(button.isSelected())
button.setSelected(false);
else
button.setSelected(true);
}
});
This will select the button and will change the text color to red and if the button is already selected,It will change it to normal.If you just want to keep button selected on click,You can simply add this line in OnClickListener.
button.setSelected(true);
The state_pressed is a mechanism to let you know whether the button is really pressed or not. This is similar to the case of giving a little sound when you really click a key in the virtual keyboard.
Since I do not know the whole story of your situation, I guess that maybe a MVC pattern is suitable for your case.
For example, in the back end, there is a data storing liked= true or false.
In the view, there are two buttons : likeButton and unlikeButton. When liked==false, likeButton is visible and unlikeButton is invisible. When liked==true, likebutton is invisible and unlikeButton is visible.
The OnClick listener for the likeButton and unlikeButton is to set the data liked= true or false.
Both likeButton and unlikeButton can have state_pressed to change the button color to red to let user know that the button is already pressed and being pressed. But, anyway, once the button is released after pressed, the onClick listener should start doing the jobs and finally the already pressed button should become invisible.
Hope that this example can clarify.
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.
I'm creating recording button and I need these states, but I don't know how to implement them with the xml. I've tried activated, selected, and pressed states but these are not getting the job done. I have all the drawables created already but the states are screwing me up.
States I need the recording button to do:
State 1. default Image of button (initial state)
State 2. Set drawable of button when the button is in the process of being pressed down
State 3. Set drawable of button after it has been pressed (after pressed down) and we are now in recording mode
State 4. After the button is clicked again return back to initial state
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/record_button_default_state" />
<item
android:state_selected="true"
android:drawable="#drawable/record_button_recording" />
<item
android:state_selected="false"
android:drawable="#drawable/record_button_default_state" />
<item
android:state_pressed="true"
android:drawable="#drawable/record_button_pressed_state" />
OnClickListener()
case R.id.record_button:
if (mr.getState() == ExtAudioRecorder.State.READY){
mr.start();
record_button.setSelected(true);
}
else if(mr.getState() == ExtAudioRecorder.State.RECORDING){
mr.stop();
mr.release();
record_button.setSelected(false);
setMediaPlayerPathAndPrepare();
}
break;
You need to be using the ToggleButton control.
Here's the selector code you'll need to call up:
(I've labelled the drawables to the states they correspond to, as per your post).
*tb_selector.xml*
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/state4"
android:state_checked="true"
android:state_pressed="true" />
<item
android:drawable="#drawable/state2"
android:state_pressed="true" />
<item
android:drawable="#drawable/state3"
android:state_checked="true" />
<item
android:drawable="#drawable/state1" />
</selector>
Reason for the default drawable being declared last: Android applies the first item in the state list that matches the current state of the object. So, if the first item in the list contains none of the state attributes above, then it is applied every time, which is why your default value should always be last (as demonstrated in the following example).
Sample ToggleButton XML:
<ToggleButton
android:id="#+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Vibrate on"
android:textOff="Vibrate off"
android:onClick="onToggleClicked"
android:background="#drawable/tb_selector" />
Sample ToggleButton click event:
public void onToggleClicked(View view) {
// Is the toggle on?
boolean on = ((ToggleButton) view).isChecked();
if (on) {
// Enable vibrate
} else {
// Disable vibrate
}
}
The OS handles the selected state of a button based on whether it is being pressed/clicked or not. You can't set that in code. If you want to change the button while something is happening, you must do it in code:
case R.id.record_button:
if (mr.getState() == ExtAudioRecorder.State.READY){
mr.start();
record_button.setImageResource(R.drawable.record_button_recording);
}
else if(mr.getState() == ExtAudioRecorder.State.RECORDING){
mr.stop();
mr.release();
record_button.setImageResource(R.drawable.record_button_default_state);
setMediaPlayerPathAndPrepare();
}
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);
Is it possible to create a button like radio button without using images?
Would like to have a pressed state upon selection. Then back to normal state when I click other options.
simply include the respective drawables of the radio button in different states (i.e. focused, pressed, checked, or normal). Include these in a selector.xml to specify the looks of the button for the respective states, and include that xml in the android:background attribute of your button. That should do it all...! :)
Check this link to understand the method better: Change how a CheckBox looks
(it is given for a CheckBox, but similar stuff will work for button as a radio button as well).
Edit:
Define round_button.xml as below:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:state_focused="true"
android:drawable="#drawable/roundbutton_on_background_focus_yellow" />
<item android:state_checked="false" android:state_focused="true"
android:drawable="#drawable/roundbutton_off_background_focus_yellow" />
<item android:state_checked="false"
android:drawable="#drawable/roundbutton_off_background" />
<item android:state_checked="true"
android:drawable="#drawable/roundbutton_on_background" />
</selector>
Then, wherever you need to include that button, just add the following:
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/round_button"
android:checked="true"/>
[P.S.: Don't forget to include the drawables for a round button, you'll have to search them yourself, or get from the default files (.android), which is given in the link]
Yes you can do it by using states for the button in drawable such as
(I have drawable for states you can have colors too.)
This is the file button_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#drawable/dark_silver_filled_square" />
<item android:drawable="#drawable/light_silver_filled_square"/>
</selector>
And place this drawable file as background to your button as background like this:
<Button
android:id="#+id/allBtn"
android:layout_width="#dimen/_80sdp"
android:layout_height="#dimen/_22sdp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="#drawable/button_selector"
android:text="All"
android:textAllCaps="false"
app:layout_constraintBottom_toTopOf="#+id/btnTest"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
And programmatically create an ArrayList of buttons like this in your class
private var btnList = ArrayList<Button>()
Add your buttons in XML to the list like this:
btnList.add(allBtn)
Then set OnTouchListener for maintaining the selected color in the button like this:
binding.allBtn.setOnTouchListener { v, event ->
buttonStatePreserver(allBtn)
true
}
And pass it to a method to preserve selection for that particular button and make other remaining buttons unselected:
fun buttonStatePreserver(button: Button) {
for(btn in btnList) {
if(btn == button) {
btn.isPressed = true
} else {
btn.isPressed = false
}
}
}