Ich habe einen Knopf mit einem benutzerdefinierten Zeichen.
<Button
android:layout_width="22dip"
android:layout_height="23dip"
android:background="@drawable/triangle" />
Das Zeichenbare ist ein Dreieck mit transparentem Hintergrund.
|\
| \
|__\
Ich finde es schwierig, auf diese Schaltfläche zu tippen. Erstens ist es relativ klein. Zweitens sind die transparenten Pixel nicht tippbar. Ich möchte die Zeichenfläche gleich groß halten, aber die Trefferfläche quadratisch machen, doppelt so groß wie das Dreieck.
_____________
| |
| |\ |
| | \ |
| |__\ |
|____________|
Antworten:
Sie können die TouchDelegate-API verwenden.
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)); } });
quelle
rect
wird als Parameter übergeben.Sie möchten "Polsterung". Dadurch wird der Raum in der Ansicht platziert. Durch den Rand wird der Raum nach außen verschoben, wodurch die Trefferfläche nicht vergrößert wird.
<Button android:layout_width="22dip" android:layout_height="23dip" android:background="@drawable/triangle" android:padding="10dp" />
quelle
Sie müssen a verwenden
TouchDelegate
, das in den API-Dokumenten als "Hilfsklasse" definiert ist, um Situationen zu behandeln, in denen eine Ansicht einen größeren Berührungsbereich als die tatsächlichen Ansichtsgrenzen haben soll.http://developer.android.com/reference/android/view/TouchDelegate.html
quelle
TouchDelegate
und ein Snippet-Code: developer.android.com/training/gestures/viewgroup.html#delegateIch bevorzuge diese Lösung:
Fügen Sie einfach einen positiven Abstand und einen negativen Rand in die Layout-Ressourcendatei ein:
<some.View .. android:padding="12dp" android:margin="-12dp" .. />
Dies ist eine sehr kleine Änderung im Vergleich zur Verwendung von TouchDelegates. Ich möchte auch kein Runnable ausführen, um den anklickbaren Bereich in meinem Java-Code hinzuzufügen.
Eine Sache, die Sie in Betracht ziehen könnten, wenn die Ansicht pixelgenau sein sollte: Das Auffüllen kann nicht immer dem Rand entsprechen . Die Polsterung sollte immer genau wie angegeben vorhanden sein. Der Rand hängt von den umgebenden Ansichten ab und wird mit den Randwerten anderer Ansichten versetzt.
quelle
TextView
) in eineLinearLayout
sollte nicht erforderlich sein. Haben Sie trotzdem versucht, diese beiden Zeilen in Ihre einzufügenLinearLayout
? Wie bereits erwähnt, hängt der Rand von den umgebenden Ansichten ab.Basierend auf der Antwort habe ich eine Kotlin-Erweiterungsfunktion erstellt, um dabei zu helfen.
/** * 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) } }
quelle
einfach durch Hinzufügen von Polstern zur Schaltfläche
<Button android:layout_width="wrap_contant" android:layout_height="wrap_contant" android:background="@drawable/triangle" android:padding="20dp" />
Auf diese Weise nimmt Ihre Schaltfläche die Höhe und Breite des Dreiecksbilds an und fügt der Schaltfläche die 20-dp-Polsterung hinzu, ohne das Bild selbst zu dehnen. und wenn Sie eine minimale Breite oder eine minimale Höhe wünschen, können Sie die Tags
minWidth
und verwendenminHeight
quelle
Falls Sie die Datenbindung verwenden. Sie können einen Bindungsadapter verwenden.
@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)); }); }
und dann können Sie Attribute für solche Ansichten verwenden
increaseTouch="@{8dp}"
quelle
Ich weiß nicht genau, was Sie unter "ohne auch den Hintergrund zu vergrößern" verstehen. Wenn Sie meinen, dass Sie nicht möchten, dass Ihr Zeichen gedehnt wird, können Sie auch Ihr Hintergrund-PNG verwenden und einen zusätzlichen transparenten Pixelrand hinzufügen. Das würde Ihre Trefferzone erhöhen, aber Ihr Bild nicht dehnen.
Wenn Sie jedoch meinen, dass Sie dieses Zeichen überhaupt nicht ändern möchten, besteht Ihre einzige Option darin, größere fest codierte Werte für Höhe und Breite zu verwenden.
quelle
versuche es damit
<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" />
quelle
Siehe Kann ich eine Schaltfläche im Klickbereich programmgesteuert vergrößern? . Dies scheint mir der einfachste Weg zu sein. Enthält sogar ein wenig zum Animieren nur des tatsächlich anklickbaren Objekts, während der Hintergrund Klicks erhalten kann. Ich werde dies bald auf meinen eigenen Code anwenden.
quelle
Das hat bei mir funktioniert:
public void getHitRect(Rect outRect) { outRect.set(getLeft(), getTop(), getRight(), getBottom() + 30); }
Eigentlich sollten Sie die 30 in Dip umwandeln oder einen Prozentsatz der Tastenhöhe machen.
quelle
Ich brauchte nur das gleiche: klickbarer Bereich größer als das Bild der Schaltfläche. Ich habe es in FrameLayout eingewickelt, das größer als der Hintergrund ist, und das innere Button-Tag in TextView geändert. Dann habe ich einen Klick-Handler angewiesen, mit diesem FrameLayout zu arbeiten, nicht mit der inneren Textansicht. Alles funktioniert gut!
quelle
Sie können eine transparente Schaltfläche wie diese verwenden ...
<Button android:layout_width="50dp" android:layout_height="50dp" android:background="@android:color/transparent" />
Sie können die Größe der Schaltfläche nach Bedarf erhöhen oder verringern und eine
enter code here
ImageView auf der Schaltfläche verwenden.<ImageView android:layout_width="22dip" android:layout_height="23dip" android:background="@drawable/triangle" />
quelle
Ich habe die Top-Level-Funktion dafür in Kotlin erstellt:
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) }
quelle
View
stattdessen eine Erweiterungsfunktion fürZu diesem Zweck habe ich ImageButton verwendet. In der XML-Verteidigung sehen Sie diese beiden Attribute:
Wir haben also zwei Drawables: Hintergrund eins und Quelle. In Ihrem Beispiel ist die Quelle triagle (drawable / trianlge):
|\ | \ |__\
Und der Hintergrund ist quadratisch (zeichnbar / quadratisch):
_____________ | | | | | | | | |____________|
Hier ist ein Beispiel für ImageButton xml:
<ImageButton ... android:src="@drawable/triangle" android:background="@drawable/square">
Ergebnis:
_____________ | | | |\ | | | \ | | |__\ | |____________|
Auch quadratisch zeichnbar, kann mehrere verschiedene Zustände haben (gedrückt, fokussiert). Und Sie können die Größe des Hintergrunds mit Hilfe von Polstern erweitern.
Nur für den Fall, hier ist ein Beispiel für einen Hintergrund, der über die Android Compat Actionbar gezeichnet werden kann:
<?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>
quelle
Sie können die Auffüllung auf die Ansicht einstellen, dh auf Ihre Schaltfläche.
<Button android:layout_width="50dp" android:layout_height="50dp" android:background="@android:color/transparent" android:padding="15dp" />
Hoffe das funktioniert bei dir.
quelle
Wenn Sie also die richtige Antwort haben, fügen Sie dem berührbaren Bereich Polster hinzu, und vergrößern Sie Ihr Bild vom Hintergrund in srcCompact .
<Button android:layout_width="22dip" android:layout_height="23dip" android:padding="6dp" app:srcCompat="@drawable/triangle"/>
Um app: scrCompat zu verwenden, müssen Sie
xmlns:app="http://schemas.android.com/apk/res-auto"
Ihrem Haupt- / Elternelement in der XML hinzufügen .Beispiel vollständig:
<?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>
quelle
Das Hinzufügen von Polstern führte dazu, dass mein Kontrollkästchen nicht zentriert wurde. Das Folgende hat bei mir funktioniert, ich habe jedoch eine feste Größe für das Kontrollkästchen angegeben (gemäß meiner UI-Spezifikation). Die Idee war, links und nicht rechts Polsterung hinzuzufügen. Ich habe oben und unten Polster hinzugefügt, um das Touch-Ziel größer zu machen und das Kontrollkästchen weiterhin zentriert zu halten.
<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" />
quelle
Ich denke, die richtige Antwort sollte ImageButton anstelle von Button verwenden. Stellen Sie das zu zeichnende Dreieck als "src" des ImageButton ein und stellen Sie die gewünschte Größe (layout_width & layout_height) ein, um die Berührung zu vereinfachen, und setzen Sie den ScaleType auf center, um die Dreiecksgröße beizubehalten.
quelle
Ich denke ehrlich, der einfachste Weg ist folgender:
Angenommen, Ihre Bildgröße ist 26dp * 26dp und Sie möchten eine Trefferfläche von 30dp * 30dp. Fügen Sie Ihrem ImageButton / Button einfach einen Abstand von 2dp hinzu und stellen Sie die Dimension auf 30dp * 30dp ein
Original
<ImageButton android:layout_width="26dp" android:layout_height="26dp" android:src="@drawable/icon"/>
Größerer Trefferbereich
<ImageButton android:layout_width="30dp" android:layout_height="30dp" android:padding="2dp" android:src="@drawable/icon_transcript"/>
quelle
Die einfachste Lösung wäre, die Anzahl
width and height
Ihrer Artikel (z. B. Bild, Schaltfläche usw.) zu erhöhen und hinzuzufügenpadding
. Der anklickbare Bereich ist also größer, sieht aber in der Originalgröße aus.Beispiel:
<Button android:layout_width="40dp" android:layout_height="40dp" android:padding="8dp" android:background="@drawable/triangle" />
Herzlichen Glückwunsch, Sie haben die gleiche Tastengröße erreicht, aber die doppelte anklickbare Größe!
_____________ | | | |\ | | | \ | | |__\ | |____________|
quelle
<Button android:layout_width="32dp" android:layout_height="36dp" android:layout_margin="5dp" android:background="@drawable/foo" />
Die Größe des Hintergrunds beträgt immer noch 22x26dp. Fügen Sie einfach den Rand hinzu.
quelle