2013-05-13 38 views
14

Có cách nào tôi có thể thay đổi bố cục cho RadioButton và vẫn có RadioGroup nhận ra nó không?Bố trí tùy chỉnh cho RadioButton

những gì tôi cần là bố cục sẽ bao gồm một vài trường EditText để khi người dùng chọn nút đó, các trường đó sẽ hoạt động. Tôi biết tôi có thể xây dựng một phần tùy chỉnh dựa trên LinearLayout và đặt bố cục của riêng tôi bằng cách sử dụng: (LinearLayout) LayoutInflater.from (context) .inflate (R.layout.my_layout, this, true) nhưng không thể tìm ra cách để làm điều tương tự với nút radio.

Tôi đã thử tùy chọn có các trường bổ sung bên ngoài RadioGroup và xếp chúng bằng nút nhưng nó không hoạt động. Có vẻ như quá phụ thuộc vào thiết bị.

Đây là những gì bố trí ban đầu trông giống như:

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

Lưu ý rằng nút không có bất kỳ văn bản và nó được thêm vào trong một TextView để chúng tôi có thể có nó ở bên trái. Điều đang xảy ra là văn bản đã "leo lên".

Vì vậy, tôi đã thay đổi nó trông như thế này:

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

Nó vẫn là không hoàn hảo và, tất nhiên, nó không nhận ra nó như là một RadioGroup.

Tôi muốn đi theo hướng mở rộng RadioButton nhưng không biết cách thay đổi bố cục tại đó.

+2

bất kỳ mã mẫu nào, với những gì bạn đã thử? – donfede

+0

@donfede xem phần bổ sung – theblitz

Trả lời

3

Bạn sẽ phải tạo một lớp mà kéo dài RadioGroup, và ghi đè addViewPassThroughHierarchyChangeListener, để có thể sử dụng bố trí tùy chỉnh cho nút radio của bạn. Theo mặc định, RadioGroup giả định rằng trẻ em của nó là nút radio, xem code dưới đây từ lớp 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

Tôi đã viết một tùy chỉnh RadioGroup gọi RadioGroupPlus nơi mà nó sẽ đi qua thông qua con của nó và tìm RadioButton bất kể sâu như thế nào RadioButton là lồng nhau, sau đó nó sẽ liên kết tất cả các RadioButton được tìm thấy với nhau.

Bạn có thể tìm repo ở đây: https://github.com/worker8/RadioGroupPlus

Các README của repo này hướng dẫn cách sử dụng nó, và nó thực sự hoạt động giống như cách bạn tưởng tượng nó, ví dụ:

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

Sẽ cung cấp bạn một cái gì đó như thế này:

Trong trường hợp của bạn, vì bạn đã có x tệp bố cục ml, hãy thử tải xuống RadioGroupPlus bằng cách làm theo guide here:

Thêm phần này vào bản dựng cấp cao nhất.gradle:

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

Thêm này theo phụ thuộc:

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

Sau đó, trong xml của bạn, thay đổi RadioGroup-worker8.com.github.radiogroupplus.RadioGroupPlus. Bây giờ tất cả các RadioButton s của bạn dưới RadioGroupPlus tất cả nên được liên kết với nhau.

Hy vọng điều đó sẽ hữu ích!