Drawable селектор теряет состояние при наведении мыши
Я создал настраиваемое рисование (основано на селекторе рисования) для обычного Button
и я решил протестировать свое приложение с помощью физической мыши и клавиатуры.
Именно тогда я заметил, что каждый раз, когда я нажимаю кнопку с физической мышью, он теряет hovered
состояние в течение очень короткого момента и только через несколько миллисекунд он приобретает pressed
государство.
Хотя это происходит только в течение очень короткого момента, оно вызывает раздражающее и очень заметное "моргание".
Я не знаю, дал ли я ясно понять, поэтому я воспроизведу шаги:
1 - кнопка находится в режиме ожидания, а указатель мыши не находится над кнопкой: кнопка отображается нормально с состоянием по умолчанию
2 - я перемещаю курсор мыши на кнопку и оставляю мышь неподвижной: кнопка отображается с состоянием наведения
3 - Я нажимаю левую кнопку мыши: кнопка визуализируется с состоянием по умолчанию (не наведено) на короткое время, а затем визуализируется с нажатым состоянием, вызывая визуальное мигание
Это странное поведение можно легко воспроизвести / проверить, заменив кнопку пользовательским Button
переопределение класса drawableStateChanged ():
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
final int[] states = getDrawableState();
StringBuilder builder = new StringBuilder("@@@ ");
if (states != null) {
for (int i = states.length - 1; i >= 0; i--) {
switch (states[i]) {
case android.R.attr.state_pressed:
builder.append("p");
break;
case android.R.attr.state_focused:
builder.append("f");
break;
case android.R.attr.state_hovered:
builder.append("h");
break;
}
}
}
System.out.println(builder.toString());
}
Logcat показывает:
@@@ [the button is in the default state]
@@@ h [the button is in the hovered state]
[I physically click the left mouse button]
@@@ [the button goes back to the default state even though it *is* hovered and pressed]
@@@ p [after a visual blink, the button goes to its pressed state]
...
Я перепробовал почти все: переопределение onHoverChanged()
, setHovered()
и так далее... Я даже пытался позвонить isHovered()
в drawableStateChanged()
чтобы увидеть, если есть разница... ничего!!!! Android активно меняет состояние рисования и hovered
атрибут false до установки нажатого состояния. Это специально!
Я смотрел везде в Интернете, и даже здесь, на SO. Ничего! Как будто никто еще не заметил этого, или я должен забыть что-то действительно простое...
К вашему сведению: я не использую никаких библиотек (например, AppCompat и т. Д. И т. Д.). Это простая кнопка, помещенная в простую активность. Протестировано на Samsung A5 2017 (с USB-мышью) и на Asus Chromebook Flip C100 (с использованием трекпада).
К вашему сведению 2: стиль в действительности v21/styles.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="AppBaseTheme" parent="@android:style/Theme.Material.Light.NoActionBar">
<item name="android:colorPrimary">#ff3344bb</item>
<item name="android:colorAccent">#ff3344bb</item>
<item name="android:colorControlNormal">#ff6d6d6d</item>
</style>
</resources>
К вашему сведению 3: я также пытался переопределить onGenericMotionEvent()
, Опять же, как только я нажимаю кнопку logcat показывает @@@ HEXIT
, Вскоре после этого logcat показывает @@@ HENTER
... но я даже не сдвинул курсор мыши на один пиксель... не говоря уже о том, чтобы переместить его за пределы кнопки!
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_ENTER:
System.out.println("@@@ HENTER");
break;
case MotionEvent.ACTION_HOVER_EXIT:
System.out.println("@@@ HEXIT");
break;
}
return super.onGenericMotionEvent(event);
}
Как я могу избавиться от этого поведения? Кто-нибудь знает флаг или хак, чтобы отключить этот миг?
Важный: я не хочу использовать единственный обходной путь, который я до сих пор придумал: создать частные флаги, чтобы вручную управлять состоянием зависания, игнорируя состояние зависания Android и используя таймеры / запланированные задержки / и т.д.