IT TIP

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

itqueen 2020. 10. 31. 10:22
반응형

배경 크기를 조정하지 않고 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 과 같을 수는 없습니다 . 패딩 지정된 항상 정확히이 있어야합니다. 마진 주변 뷰에 의존하여 오프셋 될 마진 다른보기의 값.


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

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

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


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


"배경 드로어 블을 늘리지 않고"의 의미를 잘 모르겠습니다. 드로어 블이 늘어나는 것을 원하지 않는 경우, 한 가지 옵션은 배경 png를 가져와 여기에 투명 픽셀 테두리를 추가하는 것입니다. 그러면 히트 영역이 증가하지만 이미지가 늘어나지는 않습니다.

그러나 드로어 블을 전혀 변경하지 않으려는 경우 유일한 옵션은 높이와 너비에 더 큰 하드 코드 값을 사용하는 것입니다.


이것으로 시도

  <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" />

프로그래밍 방식으로 클릭 영역의 버튼을 늘릴 수 있습니까?를 참조하십시오 . . 이것은 확실히 나에게 가장 쉬운 방법처럼 보입니다. 배경이 클릭을받을 수 있도록 허용하면서 실제 클릭 가능한 개체 만 애니메이션하는 방법도 포함합니다. 곧 내 코드에 적용 할 것입니다.


이것은 나를 위해 일했습니다.

public void getHitRect(Rect outRect) {
    outRect.set(getLeft(), getTop(), getRight(), getBottom() + 30);
}

실제로 30을 딥으로 변환하거나 버튼 높이의 백분율을 수행해야합니다.


버튼 이미지보다 더 큰 클릭 가능한 영역이 필요했습니다. 배경 드로어 블보다 큰 FrameLayout으로 감싸고 내부 Button 태그를 TextView로 변경했습니다. 클릭 핸들러가 내부 TextView가 아닌이 FrameLayout과 함께 작동하도록 지시 한 것보다. 모두 잘 작동합니다!


이렇게 투명한 버튼을 사용할 수 있습니다.

<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" />

이를 위해 ImageButton을 사용했습니다. xml 방어에서 다음 두 가지 속성을 볼 수 있습니다.

  • android : background-배경 으로 사용할 드로어 블입니다.
  • android : scr- 드로어 블을이 ImageView의 콘텐츠로 설정합니다.

그래서 우리는 두 개의 드로어 블을 가지고 있습니다 : 배경 1과 소스. 예제 소스는 triagle (drawable / trianlge)입니다.

|\
| \
|__\

그리고 배경은 정사각형 (드로어 블 / 정사각형)입니다.

_____________
|            |
|            |
|            |
|            |
|____________|

다음은 ImageButton xml의 예입니다.

<ImageButton
   ...
   android:src="@drawable/triangle"
   android:background="@drawable/square">

결과:

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

또한 사각형 드로어 블은 여러 다른 상태 (눌림, 초점)를 가질 수 있습니다. 패딩을 사용하여 배경 드로어 블 크기를 확장 할 수 있습니다.

경우에 따라 Android Compat Actionbar에서 배경 드로어 블의 예는 다음과 같습니다.

<?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>

패딩을 뷰 즉 버튼으로 설정할 수 있습니다.

<Button
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@android:color/transparent"
        android:padding="15dp" />

이것이 당신을 위해 작동하기를 바랍니다.


따라서 정답 은 터치 가능한 영역 패딩추가 하면 커지고 사진을 배경에서 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>

Just adding padding was causing my checkbox to not be centered. The following worked for me, however I specified a fixed size for the checkbox (as per my UI spec). The idea was to add padding to the left and not to the right. I added padding to the top and bottom too making the touch target larger and still keeping the checkbox centered.

<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"
       />

I think the correct answer should be using ImageButton instead of Button. Set the triangle drawable as the "src" of the ImageButton, and set the size (layout_width & layout_height) as you want for easier touch and set the ScaleType to center to retain the triangle size.


I created the top-level function for this in 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)
}

I honestly think the easiest way is this:-

Say your image size is 26dp*26dp and you want a hit area of 30dp*30dp, just add a padding of 2dp to your ImageButton/Button AND set the dimension to 30dp*30dp


Original

<ImageButton
    android:layout_width="26dp"
    android:layout_height="26dp"
    android:src="@drawable/icon"/>

Bigger hit area

<ImageButton
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="2dp"
    android:src="@drawable/icon_transcript"/>

<Button
    android:layout_width="32dp"
    android:layout_height="36dp"
    android:layout_margin="5dp"
    android:background="@drawable/foo" 
/>

The size of the background is still 22x26dp. Just add margin.

참고URL : https://stackoverflow.com/questions/8176105/how-to-increase-hit-area-of-android-button-without-scaling-background

반응형