android button setPressed after onClick
yesterday I noticed the possibility to integrate Fragments in older API Levels through the Compatibility package, but thats not really essential for the question. :)
I have a Button with an OnClickListener
Button button = (Button) f开发者_JAVA技巧indViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
button.setPressed(true);
}
});
Because of the actual clicking, it is shown as pressed and after releasing the click, the button state is not pressed and stays that way.
Is there a simple way that keeps the button state pressed after releasing? First thing I can think of would be some sort of timer, but that seems unreasonable.
Just to note this is because Android is changing the setPressed
both before and after your onClickEvent
, so changing it yourself has no effect. Another way to get around this is to use the onTouchEvent
.
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// show interest in events resulting from ACTION_DOWN
if (event.getAction() == MotionEvent.ACTION_DOWN) return true;
// don't handle event unless its ACTION_UP so "doSomething()" only runs once.
if (event.getAction() != MotionEvent.ACTION_UP) return false;
doSomething();
button.setPressed(true);
return true;
}
});
Use ToggleButton
instead of Button
.
<ToggleButton
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/topping_selector"
android:checked="false"
android:textOff="Topping2"
android:textOn="Topping2" />
topping_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="@drawable/btn_topping_on" />
<item android:state_checked="false"
android:drawable="@drawable/btn_topping_off" />
</selector>
You can keep the button states in xml file under drawable folder, then used as background for button. For example:
android:background="@drawable/buttonstate"
buttonstate.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/back_focused" />
<item android:drawable="@drawable/back" /> <!-- default -->
</selector>
Better solution:
In xml file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_activated="true">
<bitmap android:src="@drawable/image_selected"/>
</item>
<item>
<bitmap android:src="@drawable/image_not_selected"/>
</item>
</selector>
And in java:
@Override
public void onClick(View v) {
v.setActivated(!v.isActivated());
}
You can use android.os.Handler class. Ugly, but works also:
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
new Handler().post(new Runnable() {
@Override
public void run() {
button.setPressed(true);
}
});
}
});
Another solution is to extend Button
and override setPressed(boolean pressed)
method so you can handle platform calls from the onClickEvent
using a flag, for example changing the boolean pressed parameter depending on your needs.
public class MyButton extends Button {
boolean isSelected = false; //this is your flag
@Override
public void setPressed(boolean pressed) {
if(isSelected) {
//here you change the parameter so it stays pressed
super.setPressed(true);
return;
}
super.setPressed(pressed);
}
public void setIsSelected(boolean selected) {
this.isSelected = selected;
}
public MyButton(Context context) {
super(context);
}
}
This is the solution I used, It also works on android 7.0 at the moment.
YourActivity.java
public void onStandbyStart(String message) {
startStandbyBtn.setActivated(true);
}
public void onBackOnline(String message) {
startStandbyBtn.setActivated(false);
}
YourActivityLayout
<Button
...
style="@style/generic_btn_style"
... />
values/styles.xml
<style name="generic_btn_style" parent="@android:style/Widget.Button">
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:background">@drawable/generic_btn</item>
<item name="android:textColor">@color/selector_white_black</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
</style>
drawable/generic_btn.xml This selector chooses the button background. I use the pressed as the activated.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/generic_btn_disabled" android:state_enabled="false" />
<item android:drawable="@drawable/generic_btn_pressed" android:state_enabled="true" android:state_pressed="true" />
<item android:drawable="@drawable/generic_btn_pressed" android:state_activated="true" />
<item android:drawable="@drawable/generic_btn_focused" android:state_enabled="true" android:state_focused="true" />
<item android:drawable="@drawable/generic_btn_enabled" android:state_enabled="true" />
</selector>
color/selector_black_white Here I set the text color. In my case, I need to pick the textcolor black when pressed.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#fff" android:state_pressed="true" /> <!-- pressed -->
<item android:color="#fff" android:state_activated="true" /> <!-- pressed -->
<item android:color="#000" /> <!-- default -->
</selector>
精彩评论