Достичь пункт меню панели инструментов нажмите ripple effect
Я пытаюсь использовать padding для увеличения сенсорной области кнопки. Я использую
<ImageButton
android:paddingRight="32dp"
android:paddingEnd="32dp"
android:id="@+id/confirm_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="?selectableItemBackgroundBorderless"
android:src="?attr/confirmIcon" />
область щелчка увеличивается. Но,selectableItemBackgroundBorderless нажмите эффект больше не отображается как идеальный круг.
Я пытаюсь использовать duplicateParentState техника для преодоления.
<FrameLayout
android:clickable="true"
android:paddingRight="32dp"
android:paddingEnd="32dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true">
<ImageButton
android:duplicateParentState="true"
android:id="@+id/confirm_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:src="?attr/confirmIcon" />
</FrameLayout>
теперь
- область щелчка увеличена.
- на
selectableItemBackgroundBorderlessкруг эффект-идеальный круг.
однако, похоже, у него какое-то странное поведение. Когда я нажимаю на фактическую площадь ImageButton, эффект нажатия круга не отображается.
Примечание, я стараюсь избегать использования TouchDelegate техника, если я буду вынужден, как это делает наш код более сложный.
дополнительная информация
следующее правильное поведение, показанное кнопкой для Toolbar.
эффект пульсации отображается, когда область щелчка находится вне кнопки
эффект проявляется при щелчке в районе кнопки
тем не менее, я понятия не имею как они реализуют такое поведение.
4 ответов
потратив некоторое время, я, наконец, нашел, как "панели инструментов тайна" строительство. Это ActionMenuItemView, который отображается на панели инструментов. И вы можете видеть, что внутри xml-файл это style="?attr/actionButtonStyle" приложенный к нему. ?attr/actionButtonStyle соответствует Widget.Material.ActionButton и в этом стиле мы видим <item name="background">?attr/actionBarItemBackground</item>.
если вы хотите применить тот же эффект к ImageButton, то все что вам нужно сделать, это применить android:background="?attr/actionBarItemBackground" к нему. Таким образом, имея следующий xml макет:
<ImageButton
android:id="@+id/confirm_image_button"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="?attr/actionBarItemBackground"
android:src="@drawable/ic_check_black_24dp" />
вы получите этот вывод:
включен "показать границы макета", так что фактические границы ImageButton видны
если вам интересно, что ?attr/actionBarItemBackground на самом деле представляет, вот это:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight"
android:radius="20dp" />
таким образом, вы можете создать свой холст и применить его в качестве фона для ImageButton.
рябь на Android 5.0 начинается в центре каждого представления. Соответственно к правилам материального дизайна, пульсации должны начать где касание событие происходит, поэтому они, кажется, вытекают наружу из пальца. это был обратился в Android 5.1, но была ошибка в Android 5.0
чтобы исправить это, вам нужно использовать
setHotspot()метод, добавленный к Drawable в API уровня 21.setHotspot()предоставляет в папке drawable в "горячая точка", иRippleDrawableпо-видимому, использует это как точку эманации для эффекта пульсации.setHotspot()займет пару значения float, предположительно с прицелом на использованиеsetHotspot()внутриOnTouchListener, какMotionEventотчетыX/Yпозиции события touch со значениями float.
благодаря путеводителю занятого Кодера
вы можете использовать этот код для исправления ошибки ряби:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
btn.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouch(View v, MotionEvent event) {
v.getBackground()
.setHotspot(event.getX(), event.getY());
return(false);
}
});
}
другое решение:
как добиться анимация пульсаций с помощью библиотеки поддержки?
другое решение:
С первой попытки:
я пытаюсь использовать прокладку для увеличения сенсорной области кнопки.
вы можете использовать этот код, чтобы поместить центр пульсация в центре ImageButton:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
btn.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onTouch(View v, MotionEvent event) {
v.getBackground()
.setHotspot(v.getWidth()/2f, v.getHeight()/2f);//setting hot spot at center of ImageButton
return(false);
}
});
}
возможно другое решение, когда FrameLayout обертывания ImageButton:
как вы говорите:
однако, похоже, у него какое-то странное поведение. Когда я нажимаю на фактическая площадь ImageButton, эффект кругового нажатия не отображается.
обойти эту проблему можно, чтобы добавить frameLayout.performClick() на onClick() метод ImageButton
или вы можете имитировать прикосновение frameLayout такой код ImageButton кнопки:
// Obtain MotionEvent object
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis() + 100;
float x = 0.0f;// or x = frameLayout.getWidth()/2f
float y = 0.0f;// or y = frameLayout.getHeight()/2f
// List of meta states found here: developer.android.com/reference/android/view/KeyEvent.html#getMetaState()
int metaState = 0;
MotionEvent motionEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_UP,
x,
y,
metaState
);
// Dispatch touch event to view
frameLayout.dispatchTouchEvent(motionEvent);
если вы используете android:duplicateParentState="true", просто набор android:clickable="false" на ImageButton сделает ваш Button выделяем жмем на него и его родителей
<ImageButton
...
android:duplicateParentState="true"
android:clickable="false"
/>
объяснение
С документ
для дублирования включена, такая точка зрения государственного выигрышного от своих родителей, а не от собственных внутренних свойств
=> просмотр базы изменения состояния в Родительском состоянии.
Значение по умолчанию clickable of ImageButton is true => при нажатии кнопки ImageButton, состояние родителя не изменяется => ImageButton не выделить
= > Set clickable=false решит проблему
ЗАМЕТКИ
1) Не забудьте установить clickable=true по его родителя
2) для TextView, ImageView (или некоторые представления, которые имеют clickable=false по умолчанию), вам не нужно устанавливать clickable=false
3) будьте осторожны при использовании setOnClickListener
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
при использовании setOnClickListener он также setClickable(true) в этом случае вы только установить setOnClickListener для родительского макета
Я подозреваю, что ваша проблема заключается в том, что у вас есть ImageButton и ImageView. Стиль по умолчанию для ImageButton - это:
<style name="Widget.ImageButton">
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:scaleType">center</item>
<item name="android:background">@android:drawable/btn_default</item>
</style>
заменен был фон, но вы все равно оставили элемент кликабельным и фокусируемым. В вашем примере реальным активным элементом является контейнер, поэтому вы можете использовать обычный ImageView, или установите элемент, чтобы быть не кликабельным и фокусируемым вручную. Также важно установить прослушиватель кликов на контейнере,не в сама кнопка / изображение, потому что она станет кликабельной.
это один из вариантов:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="48dp"
android:focusable="true"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
<ImageButton
android:duplicateParentState="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:duplicateParentState="true"
android:src="@drawable/ic_check_black_24dp"
android:clickable="false"
android:focusable="false"
/>
</FrameLayout>
другой такой же, за исключением вида внутри FrameLayout - это:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:duplicateParentState="true"
android:src="@drawable/ic_check_black_24dp"
/>
вот визуальное доказательство:
это было захвачено на эмуляторе под управлением Android 5.0.2. Я попробовал это на своем телефоне 8.0, также работает.






