Come aumentare colpito la zona di Android pulsante, senza scala di sfondo?

Ho un pulsante con un costume drawable.

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

Drawable è un triangolo con sfondo trasparente.

|\
| \
|__\

Trovo questo pulsante difficili da toccare. Prima di tutto, è relativamente piccolo. Secondo, i pixel trasparenti non sono tappable. Vorrei mantenere l’immagine della stessa dimensione, ma rendono l’area colpita una forma quadrata di due volte la dimensione del triangolo.

_____________
|            |
|    |\      |
|    | \     |
|    |__\    |
|____________|
  • Hai provato aggiunta di margine?
  • Il margine di non aumentare l’hit della zona.
InformationsquelleAutor JoJo | 2011-11-17

 

20 Replies
  1. 55

    è possibile utilizzare 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)); 
        } 
    }); 
    • Come fa un valore mai ottenere impostato per rect qui? il pulsante.getHitRect(rect) non restituisce alcun valore!
    • viene passato come parametro.
    • ehi, il valore 100 uso, dovrebbe essere un dp valore mi da la cartella dimensioni ? sarà il valore sorta di cambiamento a seconda della densità di destra ?
    • Che è di destra. È inoltre possibile calcolare essa stackoverflow.com/a/8399445/2523667
    • Perché questo bisogno di essere fatto in un post() ?
  2. 45

    Vuoi “imbottitura” lo spazio all’interno della vista. Margine di mettere lo spazio esterno, che non aumenterà l’area colpita.

     <Button
        android:layout_width="22dip"
        android:layout_height="23dip"
        android:background="@drawable/triangle"
        android:padding="10dp" />
    • ho provato qui sul dispositivo e di un emulatore, non funziona. hai provato questa?
    • L’imbottitura è aggiunto all’interno di layout_width/android: layout_height i, non al di fuori. Quindi, questo Pulsante è ancora 22 x 23 di grandi dimensioni. Quindi questo non aiuta.
    • Questo funziona alla grande. L’imbottitura in espanso il tappable desiderato della zona e a sinistra la mia immagine con le stesse dimensioni, che come JoJo (l’autore originale) ha chiesto.
    • Perché questa risposta sono arrivati tanti upvotes, è chiaro che imbottitura pastiglie contenuto all’interno di confini, non all’esterno?!
    • Credo che si dovrebbe anche aumentare la dimensione della visualizzazione per farlo funzionare. come: layout_width=”42dp” android: layout_height i=”43dp” padding=”10dp”
    • Di seguito il mio commento precedente, credo che questo sarà anche ingrandire lo sfondo. Se è così, forse si può mettere lo sfondo all’interno di un “inserto” disegnabile. PS. Io preferisco questa di TouchDelegate, perché TouchDelegate ha bisogno di pasticciare con l’antenato e diventa più complicato se il bambino vista è in movimento…
    • che non è possibile in base a ciò che l’imbottitura si dovrebbe fare. L’imbottitura è applicato all’interno dato height/width non per il lato esterno. Probabilmente hai cambiato height/width per wrap_content

  3. 24

    È necessario utilizzare un TouchDelegate, che è definito nell’API docs come “classe di supporto per gestire le situazioni in cui si desidera visualizzare per avere una maggiore area touch rispetto al suo effettivo vista limiti”

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

    • Non riesco a vedere niente nel tuo commento, che renderebbe questa risposta non valida o “sbagliato”.
    • Devo rendere in modo sbagliato, se si è già sbagliato?
    • Una spiegazione TouchDelegate e un frammento di codice: developer.android.com/training/gestures/viewgroup.html#delegate
    • Questo tocco delegato di merda non funziona mai.
  4. 16

    Io preferisco questa soluzione:

    Semplicemente aggiungere un positivo imbottitura e un negativo marging all’interno del layout di file di risorse:

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

    Questo è un piccolo cambiamento rispetto all’utilizzo di TouchDelegates. Anche io non voglio per eseguire un Eseguibile per l’aggiunta di area cliccabile all’interno del mio codice Java.

    Una cosa che si potrebbe prendere in considerazione se la vista deve essere perfetta in ogni pixel: imbottitura non è sempre uguale a margine. Il imbottitura deve essere sempre lì, esattamente come specificato. Il margine dipende dal panorama circostante e sarà compensato con il margine valori di altri punti di vista.

    • amato questo 😀
    • Non riuscivo a ottenere questo lavoro. Ho due testi, uno accanto all’altro in un LinearLayout e vuole la mano destra per avere una tangibile zona un po ‘ più grande rispetto al testo stesso…ma usando questi 2 linee extra rende il mio testo sia offset che non è l’aspetto sto andando per
    • L’inserimento di una vista unica (qui TextView) in un LinearLayout non dovrebbe essere necessario. Comunque, hai provato ad aggiungere queste due righe nel tuo LinearLayout? Come detto prima, il margine dipende dal panorama circostante.
    • Grazie @TimoBähr ma (inizialmente) non voglio che tutto il LinearLayout essere cliccabile, poiché il testo a sinistra non si doveva clickablr…alla fine ho solo jave e mad tutto il LinearLayout Cliccabile e, naturalmente, che funziona.
  5. 5

    semplicemente con l’aggiunta di imbottitura per il pulsante

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

    Così facendo questo.. il tuo pulsante l’altezza e la larghezza del triangolo immagine e aggiungere il 20dp imbottitura al pulsante senza allungamento dell’immagine stessa . e se volete un po ‘ la larghezza minima o qualche hinimum altezza è possibile utilizzare il minWidth e minHeight tag

  6. 2

    Non so con certezza cosa si intende per “senza aumento anche l’immagine di sfondo.” Se vuoi dire che tu non vuoi la tua immagine per ottenere allungato quindi una possibilità che hai è di prendere il vostro sfondo png e aggiungere un extra di pixel trasparente bordo su di esso. Che vorresti aumentare la tua zona colpita, ma non allungare la vostra immagine.

    Se invece vuoi dire che non vuoi cambiare che drawable, allora credo che la tua unica opzione è quella di utilizzare più grandi sono codificati i valori di altezza e larghezza.

    • Quello che voglio dire è che ho bisogno il pulsante grafico di apparire X da Y, ma hanno colpito il territorio X+10 Y+10. Non credo che i pixel trasparenti aggiungere all’area colpita. Il mio grafico è di forma triangolare. Quando mi toccare le aree trasparenti, onClick non attiva.
    • So per certo che i pixel trasparenti in background img aggiungerà alla zona colpita. Io l’ho usato prima di fare un pulsante invisibile. Forse non è l’aggiunta di dimensioni perché hai hardcoded l’altezza e la larghezza? Magari prova wrap_content per coloro.
    • È strano. Ho fatto saltare in aria il pulsante per riempire la mia schermo intero solo per il testing. Quando si toccano i pixel opachi, LogCat stampa il mio onClick registro. Quando mi toccare le aree trasparenti, non registrare.
    • Inoltre, se si mette un sacco di pressione sullo schermo in modo che il dito la superficie è maggiore di quella del pulsante, il onClick non attiva. Devo cautamente toccare il pulsante per attivare onClick. C’è qualche proprietà che regola questo “fat finger sindrome”?
  7. 2

    prova con questo

      <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" />
    • Piaciuto questo ideia.. pulito.. semplice.. si può lavorare con imbottitura e drawable per soddisfare al centro.. bello..
  8. 1

    Questo ha funzionato per me:

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

    Anche se in realtà si dovrebbe convertire il 30 a tuffo o fare una percentuale dell’altezza del pulsante.

    • Necessita di spiegazione. OP ha postato un frammento di layout xml, per un Pulsante (che sarebbe la parte di alcune vista del layout xml). Ma presumo che il metodo di cui sopra deve essere associato con il Pulsante, non con la vista di classe che contiene il pulsante? Come fare per associare il metodo di cui sopra con il pulsante?
  9. 1

    Ho solo bisogno lo stesso: area cliccabile più grande del pulsante immagine. Ho avvolto in FrameLayout di dimensioni più grandi rispetto a sfondo drawable e cambiato interiore Pulsante tag TextView. Che ho diretto un clic su gestore di lavorare con questo FrameLayout, non con l’interno in una TextView. Tutto funziona bene!

    • Nonostante sia orribile, questa è la soluzione migliore Android offre.
  10. 1

    È possibile utilizzare il pulsante trasparente come questo…

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

    è possibile aumentare o diminuire le dimensioni del pulsante come il vostro requisito e utilizzare unenter code here ImageView il pulsante….

    <ImageView
        android:layout_width="22dip"
        android:layout_height="23dip"
        android:background="@drawable/triangle" />
  11. 1

    In base alla risposta che ho creato un kotlin funzione di estensione per aiutare con esso.

    /**
     * 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)
        }
    }
    
  12. 0

    Per questo scopo ho utilizzato ImageButton.
    In xml defenition potrete vedere questi due attributi:

    • android:background – Una immagine da utilizzare come sfondo.
    • android:scr – Imposta un drawable come il contenuto di questo ImageView.

    Quindi abbiamo due drawables: sfondo uno e l’origine.
    In te la sorgente di esempio sarà triagle(drawable/trianlge):

    |\
    | \
    |__\

    E lo sfondo è quadrato(drawable/piazza):

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

    Qui è un esempio di ImageButton xml:

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

    Risultato:

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

    Anche piazza drawable, potrebbe avere diversi stati(premuto, messa a fuoco). E si potrebbe ampliare il backgroud drawable dimensioni con imbottiture.

    Solo nel caso, qui è un esempio per sfondo drawable da 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>
    • Per qualche motivo il mio src non è utilizzato, anche, mentre lo sfondo è solo trasparente.
    • È difficile risolvere il tuo problema senza informazioni…
  13. 0

    È possibile impostare il padding per la vista e cioè il pulsante.

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

    Spero che questo funziona per voi.

  14. 0

    Quindi la risposta giusta, aggiungere imbottitura per il tangibile area di ottenere più grande E cambiare la vostra immagine di sfondo per srcCompact.

    <Button
        android:layout_width="22dip"
        android:layout_height="23dip"
        android:padding="6dp"
        app:srcCompat="@drawable/triangle"/>

    Da usare app:scrCompat è necessario aggiungere xmlns:app="http://schemas.android.com/apk/res-auto" principale/genitore elemento xml.

    esempio completo:

    <?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>
  15. 0

    Solo l’aggiunta di imbottitura è stata la causa della mia casella di controllo per non essere centrato. I seguenti lavorato per me, però ho specificato una dimensione fissa per la casella di controllo (come per la mia UI spec). L’idea era di aggiungere un contorno a sinistra e non a destra. Ho aggiunto imbottitura in alto e in basso anche rendendo l’obiettivo di tocco più grandi e ancora mantenere la casella di controllo al centro.

    <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"
           />
  16. 0

    Penso che la risposta corretta dovrebbe essere utilizzando ImageButton invece di un Pulsante.
    Impostare il triangolo drawable come il “src” di ImageButton, e impostare le dimensioni (layout_width & android: layout_height i) come si desidera per una più facile toccare e impostare il ScaleType al centro per mantenere il triangolo formato.

  17. 0

    Ho creato la funzione di primo livello per questo 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)
    }
  18. 0

    Sinceramente ritengo che il modo più semplice è questo:-

    Dire la dimensione dell’immagine è 26dp*26dp e volete un colpo area di 30dp*30dp, basta aggiungere un riempimento di 2dp al tuo ImageButton/Pulsante E impostare la dimensione di 30dp*30dp


    Originale

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

    Più grande area colpita

    <ImageButton
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:padding="2dp"
        android:src="@drawable/icon_transcript"/>
  19. -1
    <Button
        android:layout_width="32dp"
        android:layout_height="36dp"
        android:layout_margin="5dp"
        android:background="@drawable/foo" 
    />

    La dimensione del fondo è ancora 22x26dp. Basta aggiungere il margine di.

    • forse padding?

Lascia un commento