[android] 배경을 조정하지 않고 Android 버튼의 히트 영역을 늘리는 방법은 무엇입니까?

커스텀 드로어 블이있는 버튼이 있습니다.

<Button
    android:layout_width="22dip"
    android:layout_height="23dip"
    android:background="@drawable/triangle" />

드로어 블은 배경이 투명한 삼각형입니다.

|\
| \
|__\

이 버튼을 누르기가 어렵습니다. 첫째, 상대적으로 작습니다. 둘째, 투명 픽셀은 탭할 수 없습니다. 드로어 블을 같은 크기로 유지하고 싶지만 히트 영역을 삼각형 크기의 두 배로 정사각형 모양으로 만듭니다.

_____________
|            |
|    |\      |
|    | \     |
|    |__\    |
|____________|



답변

TouchDelegate API를 사용할 수 있습니다.

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));
    }
});


답변

당신은 “패딩”을 원합니다. 그것은 뷰 내부에 공간을 둘 것입니다. 여백은 공간을 외부에 두어 히트 영역을 늘리지 않습니다.

 <Button
    android:layout_width="22dip"
    android:layout_height="23dip"
    android:background="@drawable/triangle"
    android:padding="10dp" />


답변

당신은 사용할 필요가 TouchDelegate“실제 뷰 범위보다 더 큰 터치 영역을 가지고 당신이보기를 원하는 핸들 상황에 도우미 클래스”로 API 문서에 정의 된을,

http://developer.android.com/reference/android/view/TouchDelegate.html


답변

이 솔루션을 선호합니다.

레이아웃 리소스 파일에 양수 여백과 음수 여백을 추가하기 만하면됩니다.

<some.View
  ..
  android:padding="12dp"
  android:margin="-12dp"
  .. />

이것은 TouchDelegates 사용에 비해 매우 작은 변화입니다. 또한 Java 코드 내부에 클릭 가능한 영역을 추가하기 위해 Runnable을 실행하고 싶지 않습니다.

뷰가 픽셀 완벽해야하는 경우 고려할 수있는 한 가지 : 패딩 이 항상 margin 과 같을 수는 없습니다 . 패딩 지정된 항상 정확히이 있어야합니다. 마진 주변 뷰에 의존하여 오프셋 될 마진 다른보기의 값.


답변

답변을 바탕으로 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)
    }
}


답변

버튼에 패딩을 추가하기 만하면

 <Button
android:layout_width="wrap_contant"
android:layout_height="wrap_contant"
android:background="@drawable/triangle"
android:padding="20dp" />

이렇게하면 버튼이 삼각형 이미지의 높이와 너비를 가져와 이미지 자체를 늘리지 않고 버튼에 20dp 패딩을 추가합니다. 최소 너비 또는 최소 높이를 원하면 minWidthminHeight태그를 사용할 수 있습니다.


답변

데이터 바인딩을 사용하는 경우. 바인딩 어댑터를 사용할 수 있습니다.

@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}"