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();
}
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 know it has already been asked and answered here and here. I have tried both, but none of them is working right for me.
I have a favorite button, If it is pressed I set the item to favorite in database and replace the image of the toggle button, and vice versa. Here is how I am doing it:
<ToggleButton
android:id="#+id/btnFavorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn=""
android:textOff=""
android:layout_marginRight="5dp"
android:background="#drawable/favorite_btn_style" />
Here is my favorite_btn_style.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/favourit_blue_btn" android:state_checked="true"/>
<!-- pressed -->
<item android:drawable="#drawable/favourit_dark_btn"/>
<!-- default/unchecked -->
</selector>
In oncreate I check if the item is already set to favorite, then setchecked to true:
if (movieObj.getIsFav().intValue() == 1) {
btnFav.setChecked(true);
}
Here is my onclicklistener on the button:
btnFav.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (!btnFav.isChecked()) {
btnFav.setChecked(true);
// set favorite
dbHelper.updateMovieFavorite(movieObj.getId().intValue(), 1);
} else {
btnFav.setChecked(false);
// set favorite
dbHelper.updateMovieFavorite(movieObj.getId().intValue(), 0);
}
}
});
Function gets called, and executed fine, but no change in image.. What I am doing wrong?
Delete both btnFav.setChecked(true) and btnFav.setChecked(false) in your OnClick method. It is a togglebutton which toggles the setChecked on its own by every click and you reset it to the old value. So in your case it always has the same value(the start value).
I would suggest you rather use setOnCheckedChangeListener instead of onClickListener.
Create a file button_toggle.xml in your res/drawable folder
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="false"
android:drawable="#drawable/ic_slide_switch_off" />
<item
android:state_checked="true"
android:drawable="#drawable/ic_slide_switch_on" />
</selector>
Try to use android:button="#drawable/favorite_btn_style" and android:background="#android:color/transparent" combination. To customize the checkbox, radio and toggle button you should use android:button instead of android:background.
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
}
});
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.