Как увеличить зону действия кнопки Android без масштабирования фона?
У меня есть кнопка с настраиваемой возможностью.
<Button
android:layout_width="22dip"
android:layout_height="23dip"
android:background="@drawable/triangle" />
Выбираемый треугольник с прозрачным фоном.
|\
| \
|__\
Я нахожу эту кнопку трудно нажатой. Во-первых, он относительно небольшой. Во-вторых, прозрачные пиксели не поддаются отображению. Я хотел бы сохранить выталкиваемый одинаковый размер, но сделать область попадания квадратной фигурой в два раза большим размером треугольника.
_____________
| |
| |\ |
| | \ |
| |__\ |
|____________|
Ответы
Ответ 1
вы можете использовать API TouchDelegate.
final View parent = (View) button.getParent(); // button: the view you want to enlarge hit area
parent.post( new Runnable() {
public void run() {
final Rect rect = new Rect();
button.getHitRect(rect);
rect.top -= 100; // increase top hit area
rect.left -= 100; // increase left hit area
rect.bottom += 100; // increase bottom hit area
rect.right += 100; // increase right hit area
parent.setTouchDelegate( new TouchDelegate( rect , button));
}
});
Ответ 2
Вы хотите "заполнение". Оно помещает пространство внутри представления. Маржа выведет пространство снаружи, что не увеличит область попадания.
<Button
android:layout_width="22dip"
android:layout_height="23dip"
android:background="@drawable/triangle"
android:padding="10dp" />
Ответ 3
Вам нужно использовать TouchDelegate
, который определен в документах API как "класс-помощник" для обработки ситуаций, когда вы хотите, чтобы представление имело большую область касания, чем его фактические границы представлений "
http://developer.android.com/reference/android/view/TouchDelegate.html
Ответ 4
Я предпочитаю это решение:
Просто добавьте положительное отступы и отрицательное маржирование внутри файла ресурсов макета:
<some.View
..
android:padding="12dp"
android:margin="-12dp"
.. />
Это очень небольшое изменение по сравнению с использованием TouchDelegates. Я также не хочу запускать Runnable для добавления области, в которую можно щелкнуть, внутри моего кода Java.
Одна вещь, которую вы могли бы рассмотреть, если представление должно быть идеальным для пикселя: заполнение не всегда может равняться марже. Прокладка всегда должна быть точно такой, как указано. Маржа зависит от окружающих представлений и будет компенсирована значениями полей других видов.
Ответ 5
просто добавив дополнение к кнопке
<Button
android:layout_width="wrap_contant"
android:layout_height="wrap_contant"
android:background="@drawable/triangle"
android:padding="20dp" />
Таким образом, сделав это, ваша кнопка примет высоту и ширину изображения треугольника и добавит 20dp дополнение к кнопке без растягивания самого изображения. и если вы хотите минимальную ширину или некоторую высоту высот, вы можете использовать теги minWidth
и minHeight
Ответ 6
Основываясь на ответе, я создал функцию расширения kotlin, чтобы помочь с этим.
/**
* Increase the click area of this view
*/
fun View.increaseHitArea(dp: Float) {
// increase the hit area
val increasedArea = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics).toInt()
val parent = parent as View
parent.post {
val rect = Rect()
getHitRect(rect)
rect.top -= increasedArea
rect.left -= increasedArea
rect.bottom += increasedArea
rect.right += increasedArea
parent.touchDelegate = TouchDelegate(rect, this)
}
}
Ответ 7
Я не знаю точно, что вы подразумеваете под "без увеличения фонового рисунка". Если вы имеете в виду, что вы просто не хотите, чтобы ваши растяжимые растягивались, то один вариант, который у вас есть, - это взять ваш фоновый png и добавить к нему дополнительную прозрачную рамку. Это увеличило бы вашу зону удара, но не растянуло бы ваше изображение.
Если, однако, вы имеете в виду, что вы не хотите вообще изменять этот чертеж, я думаю, что ваш единственный вариант - использовать большие жестко кодированные значения для высоты и ширины.
Ответ 8
попробуйте с этим
<Button
android:id="@+id/btn_profile"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:background="@android:color/transparent"
android:drawableBottom="@drawable/moreoptionicon"
android:onClick="click"
android:paddingBottom="15dp"
android:visibility="visible" />
Ответ 9
См. Можно ли программным образом увеличить число кнопок на панели?. Это похоже на самый простой способ для меня. Даже включает в себя немного анимации только реального объекта, который можно щелкнуть, позволяя фону получать клики. Я скоро приложу это к своему собственному коду.
Ответ 10
Это сработало для меня:
public void getHitRect(Rect outRect) {
outRect.set(getLeft(), getTop(), getRight(), getBottom() + 30);
}
Хотя на самом деле вы должны преобразовать 30 в dip или сделать процент от высоты кнопки.
Ответ 11
Мне просто нужно было то же самое: область с кликсом больше, чем изображение кнопки. Я обернул его в FrameLayout размером больше, чем фон, и изменил внутренний тег Button на TextView. Затем я направил обработчик кликов для работы с этим FrameLayout, а не с внутренним TextView. Все работает хорошо!
Ответ 12
Вы можете использовать прозрачную кнопку, подобную этой...
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@android:color/transparent" />
вы можете увеличить или уменьшить размер кнопки в качестве вашего требования и использовать кнопку enter code here
ImageView вверх по кнопке....
<ImageView
android:layout_width="22dip"
android:layout_height="23dip"
android:background="@drawable/triangle" />
Ответ 13
Я создал функцию верхнего уровня для этого в kotlin:
fun increaseTouchArea(view: View, increaseBy: Int) {
val rect = Rect()
view.getHitRect(rect)
rect.top -= increaseBy // increase top hit area
rect.left -= increaseBy // increase left hit area
rect.bottom += increaseBy // increase bottom hit area
rect.right += increaseBy // increase right hit area
view.touchDelegate = TouchDelegate(rect, view)
}
Ответ 14
Для этого я использовал ImageButton.
В xml defenition вы увидите эти два атрибута:
- андроид: фон. Выбирается для использования в качестве фона.
- android: scr. Устанавливает возможность рисования в качестве содержимого этого ImageView.
Итак, у нас есть две возможности: фон один и источник.
В вашем примере источник будет триагле (drawable/trianlge):
|\
| \
|__\
И фон квадратный (drawable/square):
_____________
| |
| |
| |
| |
|____________|
Вот пример ImageButton xml:
<ImageButton
...
android:src="@drawable/triangle"
android:background="@drawable/square">
Результат:
_____________
| |
| |\ |
| | \ |
| |__\ |
|____________|
Кроме того, квадратная вытягиваемая, может иметь несколько разных состояний (нажата, сфокусирована). И вы можете увеличить размер вырезаемого backgroud с помощью paddings.
На всякий случай, вот пример для фона, извлекаемого из панели действий Android Android:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
<item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/abc_list_selector_disabled_holo_dark" />
<item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/abc_list_selector_disabled_holo_dark" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/abc_list_selector_background_transition_holo_dark" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/abc_list_selector_background_transition_holo_dark" />
<item android:state_focused="true" android:drawable="@drawable/abc_list_focused_holo" />
<item android:drawable="@android:color/transparent" />
</selector>
Ответ 15
Вы можете установить дополнение к виду, то есть к вашей кнопке.
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@android:color/transparent"
android:padding="15dp" />
Надеюсь, это сработает для вас.
Ответ 16
Таким образом, правильный ответ, добавьте отступы к сенсорной области, увеличьте И измените изображение с фона на srcCompact.
<Button
android:layout_width="22dip"
android:layout_height="23dip"
android:padding="6dp"
app:srcCompat="@drawable/triangle"/>
Чтобы использовать app: scrCompat, вам нужно добавить xmlns:app="http://schemas.android.com/apk/res-auto"
в основной/родительский элемент в xml.
пример завершен:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/height_btn_bottom_touch_area"
android:background="@color/bg_white"
android:clipToPadding="false"
android:elevation="7dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stateListAnimator="@animator/selected_raise"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<ImageView
android:id="@+id/bottom_button_bg"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription=
"@string/service_request_background_contentDescription"
android:elevation="1dp"
android:padding="6dp"
app:srcCompat="@drawable/btn_round_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
</ImageView>
<TextView
android:id="@+id/bottom_button_text"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="1dp"
android:gravity="center"
android:text="@string/str_continue_save"
android:textColor="@color/text_white"
android:textSize="@dimen/size_text_title"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
Ответ 17
Просто добавление отступов заставляло мой флажок не центрироваться. Следующее сработало для меня, однако я установил фиксированный размер для флажка (согласно моей спецификации пользовательского интерфейса). Идея заключалась в том, чтобы добавить отступ слева, а не справа. Я также добавил отступы сверху и снизу, чтобы увеличить цель касания и сохранить флажок по центру.
<CheckBox
android:id="@+id/checkbox"
android:layout_width="30dp"
android:layout_height="45dp"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:button="@drawable/checkbox"
android:checked="false"
android:gravity="center"
/>
Ответ 18
Я думаю, что правильный ответ должен использовать ImageButton вместо Button. Установите нарисованный треугольник как "src" ImageButton, и установите размер (layout_width & layout_height) так, как вы хотите для более легкого касания, и установите ScaleType в центр, чтобы сохранить размер треугольника.
Ответ 19
Честно говоря, я думаю, что самый простой способ это: -
Скажите, что размер вашего изображения составляет 26dp * 26dp, и вы хотите, чтобы область попадания составляла 30dp * 30dp, просто добавьте отступ 2dp к кнопке ImageButton/Button И установите размер 30dp * 30dp
Оригинал
<ImageButton
android:layout_width="26dp"
android:layout_height="26dp"
android:src="@drawable/icon"/>
Большая зона удара
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:padding="2dp"
android:src="@drawable/icon_transcript"/>
Ответ 20
В случае, если вы используете привязку данных. Вы можете использовать обязательный адаптер.
@BindingAdapter("increaseTouch")
fun increaseTouch(view: View, value: Float) {
val parent = view.parent
(parent as View).post({
val rect = Rect()
view.getHitRect(rect)
val intValue = value.toInt()
rect.top -= intValue // increase top hit area
rect.left -= intValue // increase left hit area
rect.bottom += intValue // increase bottom hit area
rect.right += intValue // increase right hit area
parent.setTouchDelegate(TouchDelegate(rect, view));
});
}
а затем вы можете использовать атрибут в представлениях, подобных этому
increaseTouch="@{8dp}"
Ответ 21
<Button
android:layout_width="32dp"
android:layout_height="36dp"
android:layout_margin="5dp"
android:background="@drawable/foo"
/>
Размер фона по-прежнему равен 22x26dp. Просто добавьте margin.