2013-05-13 170 views
14

有什麼方法可以更改RadioButton的佈局,並且仍然讓RadioGroup識別它嗎?RadioButton的自定義佈局

我需要的是,佈局將包括幾個EditText字段,以便當用戶選擇該按鈕時,這些字段變爲活動狀態。 我知道我可以構建一個基於LinearLayout的自定義零件,並使用以下代碼設置我自己的佈局: (LinearLayout)LayoutInflater.from(context).inflate(R.layout.my_layout,this,true) 但無法弄清楚用單選按鈕做同樣的事情。

我已經嘗試過在RadioGroup之外添加額外字段並將它們與按鈕排列在一起的選項,但它根本無法使用。 它似乎太依賴於設備。

這是原來的佈局是什麼樣子:

<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" 
    /> 

注意,按鈕沒有任何文字,它是在一個TextView補充,使我們可以有它在左邊。 發生了什麼事是文本是「爬行」。

所以,我改成了這個樣子:

<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> 

它仍然是不完美的,當然,它不承認它作爲一個RadioGroup中。

我想去擴展RadioButton的方向,但不知道如何改變佈局。

+2

任何示例代碼,你試過了什麼? – donfede 2013-05-13 06:14:34

+0

@donfede見附件 – theblitz 2013-05-13 09:23:24

回答

3

你必須創建擴展RadioGroup中一類,並重寫addViewPassThroughHierarchyChangeListener,才能夠使用自定義佈局進行單選按鈕。默認情況下,RadioGroup中假定其子單選按鈕,請參見下面的代碼從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

我寫了一個叫RadioGroupPlus它會遍歷它的孩子,找到RadioButton定製RadioGroup不管RadioButton有多深嵌套,它將鏈接所有發現在一起的RadioButton

您可以在這裏找到回購:https://github.com/worker8/RadioGroupPlus

回購的README介紹瞭如何使用它,以及它的實際工作,就像你如何想象,例如:

<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> 

會給你是這樣的:

在你的情況,因爲你已經有X ml佈局文件,請嘗試通過以下guide here下載RadioGroupPlus

將此添加到頂級構建中。gradle產出:在你的XML

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

然後,更改RadioGroupworker8.com.github.radiogroupplus.RadioGroupPlus

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

添加此之下的依賴。現在你所有的RadioButton s都在RadioGroupPlus之間都應該鏈接在一起。

希望它能幫助!