2012-11-16 11 views
18

Ho un CheckBox che desidero centrare entro i suoi limiti, non spinto a lato. Probabilmente più facile ha dimostrato che ha spiegato:Center CheckBox disegnabile all'interno di sé

enter image description here

Nota che non è centrata. Attualmente definito come:

<CheckBox 
    android:id="@+id/checkbox_star" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:button="@drawable/btn_favorite" 

    android:layout_gravity="center" 
    android:minWidth="48dp" /> 

Non importa il pulsante personalizzato disegnabile. Si comporta allo stesso modo con una vaniglia CheckBox (la piccola casella di controllo si comporta allo stesso modo).

risposta

25

Credo che il problema sia che il widget Casella di controllo utilizza un normale TextView con l'attributo drawableLeft, perché si aspetta che venga mostrato anche il testo. (Questo è il motivo per cui lo vedi centrato verticalmente, ma leggermente spostato a sinistra.)

Se desideri semplicemente un pulsante immagine con più stati, ti suggerisco di usare uno ToggleButton con le tue immagini personalizzate in un state list selector. O potresti creare una classe personalizzata che estende ImageView e implementa Checkable.

+0

Bingo! Oh wow, grazie mille ... semplice e semplice ... non pensavo a ToggleButton! – davidcesarino

+11

Come 'ToggleButton' può essere d'aiuto con il centraggio dell'immagine, se le dimensioni dei pulsanti sono maggiori delle dimensioni dell'immagine? –

+0

Come hai risolto @YShinkarev? – Sunkas

8

È possibile utilizzare un layout genitore per raggiungere questo obiettivo:

<LinearLayout 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center"> 

    <CheckBox 
     android:id="@+id/checkbox_star" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:text="Check box text" /> 
</LinearLayout> 
+2

Grazie per la tua risposta, ma questo è esattamente il motivo per cui ho detto "centro [...] in sé" e non "centro [...] in qualcos'altro" ;-), altrimenti penso che l'avrei già fatto. Questo problema è molto rilevante quando si considera l'area di selezione del widget. – davidcesarino

+0

Quindi, separa il pulsante di spunta e il testo della casella di controllo come due controlli se l'area di selezione è il problema. Usa la casella di controllo insieme a una vista testuale affiancata. –

+2

Non ho (o voglio) alcun testo, né risolve il problema.Si tratta di creare un 'CheckBox' più grande del suo drawable mentre si posiziona detto drawable al centro e non a sinistra dei confini del widget. Quello che hai detto non lo fa. – davidcesarino

2

Ciò funzionerà correttamente come bisogno necessario. Solo piccole modifiche agli attributi di sfondo e pulsante. Questo snippet di codice è stato testato correttamente. Spero che questo aiuti.

<CheckBox 
android:id="@+id/checkbox_star" 
android:layout_width="wrap_content" 
android:layout_height="match_parent" 
android:background="@drawable/btn_favorite" 
android:button="@color/transparent" 
android:layout_gravity="center" 
android:minWidth="48dp" /> 
2

Se volete ImageView che controllabili, potete vedere il mio succo qui https://gist.github.com/hendrawd/661824a721c22b3244667379e9358b5f

o vedere il codice completo sotto

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.Checkable; 
import android.widget.ImageView; 

/** 
* @author hendrawd on 6/23/16 
*/ 
public class CheckableImageView extends ImageView implements Checkable { 

    public CheckableImageView(Context context) { 
     super(context); 
    } 

    public CheckableImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    private boolean mChecked = false; 

    private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked}; 

    @Override 
    public int[] onCreateDrawableState(final int extraSpace) { 
     final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
     if (isChecked()) 
      mergeDrawableStates(drawableState, CHECKED_STATE_SET); 
     return drawableState; 
    } 

    @Override 
    public void setChecked(boolean checked) { 
     if (mChecked != checked) { 
      mChecked = checked; 
      refreshDrawableState(); 
     } 
    } 

    @Override 
    public boolean isChecked() { 
     return mChecked; 
    } 

    @Override 
    public void toggle() { 
     setChecked(!mChecked); 
    } 

    @Override 
    public void setOnClickListener(final OnClickListener l) { 
     View.OnClickListener onClickListener = new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       toggle(); 
       l.onClick(v); 
      } 
     }; 
     super.setOnClickListener(onClickListener); 
    } 
} 

Basta impostare il selettore posto sulla tag src del vostro XML e la Seguirà lo stato di controllo drawable. Questo risolverà il problema di allineamento di CheckBox e avrà altri attributi ImageView.

Esempio di utilizzo:

<your.package.name.CheckableImageView 
    android:id="@+id/some_id" 
    android:layout_width="48dp" 
    android:layout_height="48dp" 
    android:src="@drawable/drawable_selector_of_your_choice" 
    android:padding="14dp" 
    android:gravity="center" /> 
0

Non utilizzare questo codice per bypass casella bug con il centro di allineamento per> SDK23, se avete intenzione di utilizzare le caselle di controllo in recyclerview.

<CheckBox 
android:button="@null" 
android:drawableLeft="@drawable/checkbox_selector" 
android:drawableStart="@drawable/checkbox_selector" 
/> 

caselle di controllo non sarà possibile ottenere il check-in onBindViewHolder fino al prossimo aggiornamento se RV (ad esempio: scorrere, ..).

4
android:button="@null" 
android:foreground="@drawable/btn_favorite" 
android:foregroundGravity="center" 
+0

Questo funziona perfettamente per il mio caso d'uso. Accoppiato con un selettore di stato estraibile per 'android: background, si ottiene una casella di controllo completamente personalizzata. – jhauberg