Mam przycisk z niestandardowym rysunkiem.
<Button
android:layout_width="22dip"
android:layout_height="23dip"
android:background="@drawable/triangle" />
Element do rysowania to trójkąt z przezroczystym tłem.
|\
| \
|__\
Trudno mi dotknąć tego przycisku. Po pierwsze, jest stosunkowo mały. Po drugie, przezroczyste piksele nie są dostępne. Chciałbym zachować ten sam rozmiar do rysowania, ale nadać obszarowi uderzenia kwadratowy kształt dwa razy większy niż trójkąt.
_____________
| |
| |\ |
| | \ |
| |__\ |
|____________|
Odpowiedzi:
możesz użyć 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)); } });
źródło
rect
jest przekazywany jako parametr.Chcesz "dopełnienia". Spowoduje to umieszczenie przestrzeni wewnątrz widoku. Margines wyprowadzi przestrzeń na zewnątrz, co nie zwiększy obszaru trafienia.
<Button android:layout_width="22dip" android:layout_height="23dip" android:background="@drawable/triangle" android:padding="10dp" />
źródło
Musisz użyć klasy
TouchDelegate
, która jest zdefiniowana w dokumentach interfejsu API jako „Klasa pomocnicza do obsługi sytuacji, w których chcesz, aby widok miał większy obszar dotykowy niż jego rzeczywiste granice widoku”http://developer.android.com/reference/android/view/TouchDelegate.html
źródło
TouchDelegate
i fragment kodu: developer.android.com/training/gestures/viewgroup.html#delegateWolę takie rozwiązanie:
Po prostu dodaj dodatnie dopełnienie i ujemne marginesy wewnątrz pliku zasobów układu:
<some.View .. android:padding="12dp" android:margin="-12dp" .. />
Jest to bardzo mała zmiana w porównaniu z wykorzystaniem TouchDelegates. Nie chcę też uruchamiać Runnable do dodawania klikalnego obszaru wewnątrz mojego kodu Java.
Jedna rzecz, którą możesz rozważyć, jeśli widok powinien być doskonały w pikselach: wypełnienie nie zawsze może być równe marginesowi . Wyściółka powinien zawsze być tam dokładnie określone. Marża zależy od okolicznych widoków i zostaną przesunięte z marginesu wartości innych poglądów.
źródło
TextView
) do plikuLinearLayout
nie powinno być potrzebne. Niemniej jednak, czy próbowałeś dodać te dwie linie do swojegoLinearLayout
? Jak stwierdzono wcześniej, margines zależy od otaczających widoków.Na podstawie odpowiedzi utworzyłem funkcję rozszerzenia kotlin, aby pomóc w tym.
/** * 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) } }
źródło
po prostu dodając wypełnienie do przycisku
<Button android:layout_width="wrap_contant" android:layout_height="wrap_contant" android:background="@drawable/triangle" android:padding="20dp" />
W ten sposób ... twój przycisk weźmie wysokość i szerokość obrazu trójkąta i doda wypełnienie o 20 dp do przycisku bez rozciągania samego obrazu. a jeśli chcesz mieć minimalną szerokość lub minimalną wysokość, możesz użyć tagów
minWidth
iminHeight
źródło
W przypadku korzystania z powiązania danych. Możesz użyć adaptera do wiązania.
@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)); }); }
a następnie możesz użyć atrybutu w widokach takich jak ten
increaseTouch="@{8dp}"
źródło
Nie wiem na pewno, co masz na myśli, mówiąc „bez zwiększania tła do rysowania”. Jeśli masz na myśli, że po prostu nie chcesz, aby twoje rysowanie się rozciągało, jedną z dostępnych opcji jest wzięcie tła png i dodanie do niego dodatkowej przezroczystej ramki pikselowej. To zwiększyłoby twoją strefę uderzenia, ale nie rozciągnęłoby twojego obrazu.
Jeśli jednak masz na myśli, że nie chcesz w ogóle zmieniać tego do rysowania, myślę, że jedyną opcją jest użycie większych, zakodowanych na stałe wartości wysokości i szerokości.
źródło
spróbuj z tym
<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" />
źródło
Zobacz: Czy mogę programowo zwiększyć liczbę przycisków w obszarze kliknięcia? . Na pewno wygląda to na najłatwiejszą drogę. Zawiera nawet trochę animacji tylko rzeczywistego obiektu, który można kliknąć, jednocześnie pozwalając na otrzymywanie kliknięć w tle. Wkrótce zastosuję to do mojego własnego kodu.
źródło
To zadziałało dla mnie:
public void getHitRect(Rect outRect) { outRect.set(getLeft(), getTop(), getRight(), getBottom() + 30); }
Chociaż naprawdę powinieneś przekonwertować 30, aby zanurzyć lub zrobić procent wysokości przycisku.
źródło
Potrzebowałem tylko tego samego: klikalny obszar większy niż obraz przycisku. Zawijałem go do FrameLayout o rozmiarze większym niż tło do rysowania i zmieniłem wewnętrzny znacznik Button na TextView. Następnie skierowałem moduł obsługi kliknięć do pracy z tym FrameLayout, a nie z wewnętrznym TextView. Wszystko działa dobrze!
źródło
Możesz użyć przezroczystego przycisku w ten sposób ...
<Button android:layout_width="50dp" android:layout_height="50dp" android:background="@android:color/transparent" />
możesz zwiększyć lub zmniejszyć rozmiar przycisku zgodnie z wymaganiami i użyć
enter code here
ImageView w górę przycisku ....<ImageView android:layout_width="22dip" android:layout_height="23dip" android:background="@drawable/triangle" />
źródło
Utworzyłem w tym celu funkcję najwyższego poziomu w 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) }
źródło
View
zamiastDo tego celu użyłem ImageButton. W definicji XML zobaczysz te dwa atrybuty:
Mamy więc dwie rysunki: tło i źródło. W twoim przykładzie źródłem będzie triagle (drawable / trianlge):
Tło jest kwadratowe (do rysowania / kwadratowe):
_____________ | | | | | | | | |____________|
Oto przykład ImageButton xml:
<ImageButton ... android:src="@drawable/triangle" android:background="@drawable/square">
Wynik:
_____________ | | | |\ | | | \ | | |__\ | |____________|
Również do rysowania jako kwadrat, może mieć kilka różnych stanów (wciśnięty, zogniskowany). I możesz zwiększyć rozmiar do rysowania tła za pomocą wyściółek.
Na wszelki wypadek, oto przykład tła, które można wyciągnąć z paska akcji Android Compat:
<?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>
źródło
Możesz ustawić dopełnienie dla widoku, czyli swojego przycisku.
<Button android:layout_width="50dp" android:layout_height="50dp" android:background="@android:color/transparent" android:padding="15dp" />
Mam nadzieję, że to działa dla Ciebie.
źródło
Więc właściwa odpowiedź, dodaj wypełnienie do obszaru dotykowego, powiększ go ORAZ zmień obraz z tła na srcCompact .
<Button android:layout_width="22dip" android:layout_height="23dip" android:padding="6dp" app:srcCompat="@drawable/triangle"/>
Aby użyć app: scrCompat, musisz dodać
xmlns:app="http://schemas.android.com/apk/res-auto"
do głównego / nadrzędnego elementu w xml.przykład kompletny:
<?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>
źródło
Samo dodanie dopełnienia powodowało, że moje pole wyboru nie było wyśrodkowane. Poniższe działały dla mnie, jednak określiłem stały rozmiar pola wyboru (zgodnie ze specyfikacją mojego interfejsu użytkownika). Pomysł polegał na dodaniu wypełnienia po lewej, a nie po prawej stronie. Dodałem również wyściółkę na górze i na dole, zwiększając cel dotykowy i nadal utrzymując pole wyboru wyśrodkowane.
<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" />
źródło
Myślę, że poprawną odpowiedzią powinno być użycie ImageButton zamiast Button. Ustaw trójkąt do rysowania jako „src” ImageButton i ustaw rozmiar (layout_width i layout_height), jak chcesz, aby ułatwić dotyk, i ustaw ScaleType na środek, aby zachować rozmiar trójkąta.
źródło
Szczerze myślę, że najłatwiej jest to zrobić: -
Powiedzmy, że rozmiar obrazu to 26dp * 26dp i chcesz, aby obszar działania wynosił 30dp * 30dp, po prostu dodaj wypełnienie 2dp do swojego ImageButton / Button ORAZ ustaw wymiar na 30dp * 30dp
Oryginalny
<ImageButton android:layout_width="26dp" android:layout_height="26dp" android:src="@drawable/icon"/>
Większy obszar trafienia
<ImageButton android:layout_width="30dp" android:layout_height="30dp" android:padding="2dp" android:src="@drawable/icon_transcript"/>
źródło
Najprostszym rozwiązaniem byłoby zwiększenie
width and height
pozycji (np. Obrazu, przycisku itp.) I dodaniepadding
; Więc klikalny obszar jest większy, ale wygląda w oryginalnym rozmiarze.Przykład:
<Button android:layout_width="40dp" android:layout_height="40dp" android:padding="8dp" android:background="@drawable/triangle" />
Gratulacje, udało Ci się osiągnąć ten sam rozmiar przycisku, ale dwukrotnie większy, który można kliknąć!
_____________ | | | |\ | | | \ | | |__\ | |____________|
źródło
<Button android:layout_width="32dp" android:layout_height="36dp" android:layout_margin="5dp" android:background="@drawable/foo" />
Rozmiar tła to nadal 22x26dp. Po prostu dodaj margines.
źródło