2013-05-13 24 views
14

C'è un modo per cambiare il layout di un RadioButton e il RadioGroup deve ancora riconoscerlo?Layout personalizzato per RadioButton

Quello che mi serve è che il layout includa un paio di campi EditText in modo che quando l'utente seleziona quel pulsante, quei campi diventano attivi. So che posso creare una parte personalizzata basata su LinearLayout e impostare il mio layout utilizzando: (LinearLayout) LayoutInflater.from (context) .inflate (R.layout.my_layout, this, true) ma non riesco a capire come fare la stessa cosa con un pulsante radio.

Ho provato l'opzione di avere i campi extra all'esterno del RadioGroup e allinearli con il pulsante, ma semplicemente non funziona. Sembra essere troppo dipendente dal dispositivo.

Questo è ciò che il layout originale sembrava:

<RadioGroup 
    android:id="@+id/time_selector_radio_group" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/time_selector_hours_prompt" 
    android:layout_below="@id/time_selector_hours_prompt" 
    android:layout_alignParentRight="true" 
    android:gravity="right" 
    android:orientation="vertical" 
    android:checkedButton="@+id/time_selector_first_radio" 
    > 

    <RadioButton 
     android:id="@+id/time_selector_first_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@drawable/radio_button_selector" 
     /> 
    <RadioButton 
     android:id="@+id/time_selector_second_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@drawable/radio_button_selector" 
     /> 
    <RadioButton 
     android:id="@+id/time_selector_third_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@drawable/radio_button_selector" 
     /> 
    <RadioButton 
     android:id="@+id/time_selector_hours_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@drawable/radio_button_selector" 
     /> 

</RadioGroup> 
<TextView 
    android:id="@+id/time_selector_all_day_prompt" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/time_selector_radio_group" 
    android:layout_below="@id/time_selector_hours_prompt" 
    android:layout_marginTop="11dip" 
    android:text="@string/time_all_day" 
    /> 
<TextView 
    android:id="@+id/time_selector_before_noon_prompt" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/time_selector_radio_group" 
    android:layout_below="@id/time_selector_all_day_prompt" 
    android:layout_marginTop="19dip" 
    android:text="@string/time_before_noon" 
    /> 
<TextView 
    android:id="@+id/time_selector_after_noon_prompt" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/time_selector_radio_group" 
    android:layout_below="@id/time_selector_before_noon_prompt" 
    android:layout_marginTop="19dip" 
    android:text="@string/time_after_noon" 
    /> 
<TextView 
    android:id="@+id/time_selector_starting_time_prompt" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignRight="@id/time_selector_starting_date_prompt" 
    android:layout_below="@id/time_selector_after_noon_prompt" 
    android:layout_marginTop="20dip" 
    android:layout_marginLeft="2dip" 
    android:text="@string/advanced_time_selector_dialog_starting_time_prompt" 
    /> 
<EditText 
    android:id="@+id/time_selector_starting_time" 
    android:layout_width="@dimen/advanced_time_selector_edit_texts_width" 
    android:layout_height="wrap_content" 
    android:layout_alignRight="@id/time_selector_starting_date" 
    android:layout_alignBaseline="@id/time_selector_starting_time_prompt" 
    android:textSize="14sp" 
    android:paddingRight="10dip" 
    android:paddingLeft="10dip" 
    android:gravity="center" 
    android:singleLine="true" 
    android:maxWidth="@dimen/advanced_time_selector_edit_texts_width" 
    android:background="@drawable/text_field_bg" 
    android:inputType="datetime" 
    /> 
<TextView 
    android:id="@+id/time_selector_ending_time_prompt" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignRight="@id/time_selector_ending_date_prompt" 
    android:layout_alignBottom="@id/time_selector_starting_time_prompt" 
    android:layout_alignBaseline="@id/time_selector_starting_time_prompt" 
    android:layout_marginRight="2dip" 
    android:layout_marginLeft="2dip" 
    android:text="@string/ending_date_prompt" 
    /> 
<EditText 
    android:id="@+id/time_selector_ending_time" 
    android:layout_width="@dimen/advanced_time_selector_edit_texts_width" 
    android:layout_height="wrap_content" 
    android:layout_alignRight="@id/time_selector_ending_date" 
    android:layout_alignBaseline="@id/time_selector_ending_time_prompt" 
    android:textSize="14sp" 
    android:paddingRight="10dip" 
    android:paddingLeft="10dip" 
    android:gravity="center" 
    android:singleLine="true" 
    android:maxWidth="@dimen/advanced_time_selector_edit_texts_width" 
    android:background="@drawable/text_field_bg" 
    android:inputType="datetime" 
    /> 

Nota che il pulsante non ha alcun testo e viene aggiunta in un TextView in modo che possiamo avere sulla sinistra. Quello che stava succedendo era che il testo stava "strisciando".

Così, ho cambiato in questo aspetto:

<RadioGroup 
    android:id="@+id/time_selector_radio_group" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/time_selector_hours_prompt" 
    android:layout_below="@id/time_selector_hours_prompt" 
    android:layout_alignParentRight="true" 
    android:layout_marginRight="30dip" 
    android:gravity="right" 
    android:orientation="vertical" 
    android:checkedButton="@+id/time_selector_first_radio" 
    > 

    <RadioButton 
     android:id="@+id/time_selector_all_day_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@null" 
     android:drawableRight="@drawable/radio_button_selector" 
     android:text="@string/time_all_day" 
     android:textColor="@color/content_text_color" 
     /> 
    <RadioButton 
     android:id="@+id/time_selector_before_noon_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@null" 
     android:drawableRight="@drawable/radio_button_selector" 
     android:text="@string/time_before_noon" 
     android:textColor="@color/content_text_color" 
     /> 

    <RadioButton 
     android:id="@+id/time_selector_after_noon_radio" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="1dip" 
     android:button="@null" 
     android:drawableRight="@drawable/radio_button_selector" 
     android:text="@string/time_after_noon" 
     android:textColor="@color/content_text_color" 
     /> 

    <RelativeLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 
     <RadioButton 
      android:id="@+id/time_selector_hours_radio" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="1dip" 
      android:button="@null" 
      android:drawableRight="@drawable/radio_button_selector" 
      android:layout_alignParentRight="true" 
      android:text="@string/advanced_time_selector_dialog_starting_time_prompt" 
      android:textColor="@color/content_text_color" 
      android:layout_marginLeft="-1dip" 
      android:paddingLeft="-1dip" 
      /> 
     <RelativeLayout 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal" 
      android:layout_toLeftOf="@id/time_selector_hours_radio" 
      android:layout_alignParentLeft="true">    
      <EditText 
       android:id="@+id/time_selector_starting_time" 
       android:layout_width="@dimen/advanced_time_selector_edit_texts_width" 
       android:layout_height="wrap_content" 
       android:textSize="14sp" 
       android:paddingRight="10dip" 
       android:paddingLeft="10dip" 
       android:gravity="center" 
       android:singleLine="true" 
       android:maxWidth="@dimen/advanced_time_selector_edit_texts_width" 
       android:background="@drawable/text_field_bg" 
       android:layout_alignParentRight="true" 
       android:layout_alignBaseline="@id/time_selector_hours_radio" 
       android:inputType="datetime" 
       /> 
      <TextView 
       android:id="@+id/time_selector_ending_time_prompt" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="2dip" 
       android:layout_marginLeft="2dip" 
       android:text="@string/ending_date_prompt" 
       android:layout_alignBaseline="@id/time_selector_hours_radio" 
       android:layout_toLeftOf="@id/time_selector_starting_time" 
       /> 
      <EditText 
       android:id="@+id/time_selector_ending_time" 
       android:layout_width="@dimen/advanced_time_selector_edit_texts_width" 
       android:layout_height="wrap_content" 
       android:textSize="14sp" 
       android:paddingRight="10dip" 
       android:paddingLeft="10dip" 
       android:gravity="center" 
       android:singleLine="true" 
       android:maxWidth="@dimen/advanced_time_selector_edit_texts_width" 
       android:layout_toLeftOf="@id/time_selector_ending_time_prompt" 
       android:layout_alignBaseline="@id/time_selector_hours_radio" 
       android:background="@drawable/text_field_bg" 
       android:inputType="datetime" 
       /> 
     </RelativeLayout> 
    </RelativeLayout> 

</RadioGroup> 

Non è ancora perfetto e, naturalmente, che non riconosce come un RadioGroup.

Volevo andare nella direzione di estendere il RadioButton ma non ho idea di come cambiare il layout lì.

+2

qualsiasi codice di esempio, con quello che hai provato? – donfede

+0

@donfede vedere le aggiunte – theblitz

risposta

3

Dovrete creare una classe che estende RadioGroup, e sovrascrivere addView e PassThroughHierarchyChangeListener, per essere in grado di utilizzare layout personalizzati per il pulsante di opzione. Per impostazione predefinita, RadioGroup presuppone che i suoi figli sono pulsanti di opzione, vedere codice di seguito dalla classe RadioGroup:

@Override 
public void addView(View child, int index, ViewGroup.LayoutParams params) { 
    if (child instanceof RadioButton) { 
     final RadioButton button = (RadioButton) child; 
     if (button.isChecked()) { 
      mProtectFromCheckedChange = true; 
      if (mCheckedId != -1) { 
       setCheckedStateForView(mCheckedId, false); 
      } 
      mProtectFromCheckedChange = false; 
      setCheckedId(button.getId()); 
     } 
    } 

    super.addView(child, index, params); 
} 

private class PassThroughHierarchyChangeListener implements 
     ViewGroup.OnHierarchyChangeListener { 
    private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener; 

    /** 
    * {@inheritDoc} 
    */ 
    public void onChildViewAdded(View parent, View child) { 
     if (parent == RadioGroup.this && child instanceof RadioButton) { 
      int id = child.getId(); 
      // generates an id if it's missing 
      if (id == View.NO_ID) { 
       id = View.generateViewId(); 
       child.setId(id); 
      } 
      ((RadioButton) child).setOnCheckedChangeWidgetListener(
        mChildOnCheckedChangeListener); 
     } 

     if (mOnHierarchyChangeListener != null) { 
      mOnHierarchyChangeListener.onChildViewAdded(parent, child); 
     } 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public void onChildViewRemoved(View parent, View child) { 
     if (parent == RadioGroup.this && child instanceof RadioButton) { 
      ((RadioButton) child).setOnCheckedChangeWidgetListener(null); 
     } 

     if (mOnHierarchyChangeListener != null) { 
      mOnHierarchyChangeListener.onChildViewRemoved(parent, child); 
     } 
    } 
} 
5

ho scritto una consuetudine RadioGroup chiamato RadioGroupPlus dove attraverserà attraverso di esso per bambini e trovare RadioButton indipendentemente da quanto è profonda la RadioButton è nidificato, collegherà quindi tutti gli RadioButton trovati insieme.

È possibile trovare il repo qui: https://github.com/worker8/RadioGroupPlus

La README del pronti contro termine copre come usarlo, e in realtà funziona proprio come come te lo immagini, ad esempio:

<worker8.com.github.radiogroupplus.RadioGroupPlus 
    android:id="@+id/radio_group_plus" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 
    <LinearLayout...> 
     <ImageView...> 
     <TextView...> 
     <RadioButton...> 
    </LinearLayout> 
    <LinearLayout...> 
     <ImageView...> 
     <TextView...> 
     <RadioButton...> 
    </LinearLayout> 
    <LinearLayout...> 
     <ImageView...> 
     <TextView...> 
     <RadioButton...> 
    </LinearLayout> 
</worker8.com.github.radiogroupplus.RadioGroupPlus> 

Darà qualcosa di simile:

Nel tuo caso, dal momento che già la x ml file di layout, prova a scaricare RadioGroupPlus seguendo il guide here:

Aggiungi questo al livello superiore di costruzione.Gradle:

allprojects { 
    repositories { 
     maven { url "https://jitpack.io" } 
    } 
} 

Aggiungi questo sotto le dipendenze:

compile 'com.github.worker8:RadioGroupPlus:v1.0.1' 

Poi, nel tuo XML, cambiare RadioGroup-worker8.com.github.radiogroupplus.RadioGroupPlus. Ora tutti i tuoi RadioButton s sotto RadioGroupPlus devono essere collegati insieme.

Spero che aiuti!

Problemi correlati