#android #button #state
#Android #кнопка #состояние
Вопрос:
вчера я заметил возможность интегрировать фрагменты на более старых уровнях API через пакет совместимости, но это не очень важно для вопроса. 🙂
У меня есть кнопка с OnClickListener
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
button.setPressed(true);
}
});
Из-за фактического нажатия она отображается как нажатая, а после отпускания кнопки состояние кнопки не нажато и остается таким.
Есть ли простой способ сохранить нажатой состояние кнопки после отпускания? Первое, о чем я могу подумать, это какой-то таймер, но это кажется неразумным.
Комментарии:
1. использовать
setSelected(boolean state)
2. Привет, стрем — не могли бы вы, пожалуйста, перечислить, как именно вы это исправили? Вы имеете в виду, что хотите, чтобы кнопка отображалась нажатой в течение установленного времени, пока событие не завершится? Или сбросить нажатую кнопку? В любом случае, пожалуйста, покажите свое решение, потому что решение, которое вы выбрали ниже, было неправильным..
Ответ №1:
Просто отметим, что это связано с тем, что Android изменяет setPressed
как до, так и после вашего onClickEvent
, поэтому изменение его самостоятельно не имеет никакого эффекта. Другой способ обойти это — использовать 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;
}
});
Комментарии:
1. Мартин, мне очень нравится твой ответ. Однако, когда я нажимаю в области уведомлений или в меню параметров, нажатое состояние исчезает. У вас есть какое-либо представление о том, что происходит?
Ответ №2:
Используйте ToggleButton
вместо 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>
Ответ №3:
Вы можете сохранить состояния кнопки в XML-файле в папке drawable, а затем использовать в качестве фона для кнопки. Например:
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>
Комментарии:
1. не совсем то, на что я надеялся, но тем не менее спасибо! теперь она работает с помощью button.setSelected (true) и определяет возможность рисования для этого состояния
2. не то, что просил пользователь, не решает проблему. Этот ответ действительно не должен быть одобрен.
3. Я согласен с Чаком стремом — пожалуйста, опубликуйте пример того, как вы это сделали с помощью setSelected (true), если вам удалось добиться этого таким образом. Возвращается ли кнопка в нормальное состояние после завершения действия?
4. @strem проверьте мое решение ниже
Ответ №4:
Лучшее решение:
В XML-файле:
<?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>
И в Java:
@Override
public void onClick(View v) {
v.setActivated(!v.isActivated());
}
Комментарии:
1. Ха-ха. Слишком много строк для простой задачи:
v.setActivated(!v.isActivated())
Но все равно спасибо2. если это логика, то вам не нужен селектор, чтобы .. просто настраивать вещи самостоятельно. плохое решение’
Ответ №5:
Вы можете использовать класс android.os.Handler. Некрасивая, но тоже работает:
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);
}
});
}
});
Ответ №6:
Другим решением является расширение Button
и переопределение setPressed(boolean pressed)
метода, чтобы вы могли обрабатывать вызовы платформы из onClickEvent
, используя флаг, например, изменяя логический нажатый параметр в зависимости от ваших потребностей.
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);
}
}
Ответ №7:
Это решение, которое я использовал, оно также работает на Android 7.0 на данный момент.
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
Этот селектор выбирает фон кнопки. Я использую нажатую как активированную.
<?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
Здесь я устанавливаю цвет текста. В моем случае мне нужно выбрать цвет текста черным при нажатии.
<?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>