【问题标题】:Specific radio buttons - the most simple way to set different styles for first/last buttons特定单选按钮 - 为第一个/最后一个按钮设置不同样式的最简单方法
【发布时间】:2011-09-16 20:40:17
【问题描述】:

我想在我的布局中实现这种特定类型的单选按钮:

= 第一项、中间项和最后一项的不同图形,具有不同的圆角。我可以想象为 3 种类型的按钮使用不同的样式(使用自定义样式、有状态的可绘制对象)。

我正在使用自定义切换按钮来实现这一点。我想利用drawable选择器为第一个和最后一个项目使用不同的drawable,所以我使用:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_checked="true" android:state_first="true" 
        android:drawable="@drawable/radio_left_act"/> 

    <item android:state_checked="true" android:state_last="true" 
        android:drawable="@drawable/radio_right_act"/> 

    <item android:state_checked="true" 
        android:drawable="@drawable/radio_middle_act"/> 

    <item android:state_checked="false" android:state_first="true" 
        android:drawable="@drawable/radio_left_inact"/> 

    <item android:state_checked="false" android:state_last="true" 
        android:drawable="@drawable/radio_right_inact"/> 

    <item android:state_checked="false" 
        android:drawable="@drawable/radio_middle_inact"/> 

</selector>

但现在我有一个问题,state_firststate_last 没有在我的LinearLayout 中自动设置,所以每次单击按钮时我都必须手动设置它们。是否有某种方式,某种布局,这些状态是自动设置的?感谢您的帮助。

【问题讨论】:

    标签: android android-layout custom-controls radio-button xml-drawable


    【解决方案1】:

    没有什么特别之处,所以这里有一个“默认”解决方案,带有自定义切换按钮。以下是第一个、中间和最后一个按钮的 3 种不同样式(放入 styles.xml):

    <!-- Toggle button styles -->
    
    <style name="CustomToggle">
        <item name="android:paddingTop">9dp</item>
        <item name="android:paddingBottom">9dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_weight">1</item>
    </style>            
    
    <style name="FirstToggle" parent="@style/CustomToggle">
        <item name="android:background">@drawable/radio_first</item>
    </style>            
    
    <style name="MiddleToggle" parent="@style/CustomToggle">
        <item name="android:background">@drawable/radio_middle</item>
    </style>            
    
    <style name="LastToggle" parent="@style/CustomToggle">
        <item name="android:background">@drawable/radio_last</item>
    </style>
    

    还有一个用于处理切换按钮事件的活动的短代码,因此同时只选中了一个按钮,并且禁用了选中的按钮:

    public class AktivityActivity extends Activity 
    {
        ArrayList<ToggleButton> toggle_buttons;
    
        public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.aktivity);
    
            initToggleButtons();
        }
    
        private void initToggleButtons() 
        {
            toggle_buttons = new ArrayList<ToggleButton>();
            toggle_buttons.add((ToggleButton) findViewById(R.id.toggle_1));
            toggle_buttons.add((ToggleButton) findViewById(R.id.toggle_2));
            toggle_buttons.add((ToggleButton) findViewById(R.id.toggle_3));
    
            // Listen on all toggle buttons
            for (ToggleButton toggle_button : toggle_buttons)
                toggle_button.setOnCheckedChangeListener(check_listener);
    
            // Check first toggle button
            updateToggleButtons(toggle_buttons.get(0));
        }
    
        // Only one toggle can be checked, and checked button must be disabled
        private void updateToggleButtons(ToggleButton checked_button)
        {
            for (ToggleButton toggle_button : toggle_buttons)
            {
                toggle_button.setChecked(toggle_button == checked_button);
                toggle_button.setEnabled(toggle_button != checked_button);
            }
        }
    
        // Toggle buttons change listener
        OnCheckedChangeListener check_listener = new OnCheckedChangeListener() 
        {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
            {
                if (isChecked)
                    updateToggleButtons((ToggleButton) buttonView);
            }
        };
    }
    

    也许它对某人有用......

    【讨论】:

      【解决方案2】:

      您应该查看 Wordpress Android 项目。他们使用提供类似功能的“ToggleButton”。对于 .xml,请查看 here。要下载完整的源代码,请转到here

      它与您想要的不同,因为它们只有切换按钮,但很可能会根据您需要的单选按钮样式进行调整(如果尚未内置)。

      Wordpress Android 项目帮助我学到了很多东西。从主题、自定义按钮、自定义布局、切换按钮、xmlrpc 等一切。

      【讨论】:

      • 感谢您的提示。我现在正在检查这些代码,但我不确定是否看到与我的情况相似的东西。我认为他们在那里只使用一种样式的切换按钮。但我同意样式有很多不错的工作,如果没有好的“现成解决方案”,我将不得不自己做。
      【解决方案3】:

      我找到的最简单的方法是:

      1) 扩展 RadioButton 类如下:

      import android.content.Context;
      import android.view.ViewGroup;
      import android.widget.RadioButton;
      
      public class RoundedButton extends RadioButton {
      
          private static final int[] STATE_ONLY_ONE = new int[] {
                  android.R.attr.state_first,
                  android.R.attr.state_last,
          };
      
          private static final int[] STATE_FIRST = new int[] {
                  android.R.attr.state_first
          };
      
          private static final int[] STATE_LAST = new int[] {
                  android.R.attr.state_last
          };
      
          public RoundedButton(Context context) {
              super(context);
          }
      
          @Override
          protected int[] onCreateDrawableState(int extraSpace) {
              ViewGroup parent = (ViewGroup) getParent();
              if (parent == null) {
                  return super.onCreateDrawableState(extraSpace);
              }
      
              final int size = parent.getChildCount();
              final boolean isFirst = (parent.getChildAt(0) == this);
              final boolean isLast = (parent.getChildAt(size-1) == this);
      
              int[] states = super.onCreateDrawableState(extraSpace + 2);
              if (isFirst && isLast) {
                  mergeDrawableStates(states, STATE_ONLY_ONE);
              } else if (isFirst) {
                  mergeDrawableStates(states, STATE_FIRST);
              } else if (isLast) {
                  mergeDrawableStates(states, STATE_LAST);
              }
      
              return states;
          }
      
      }
      

      2) 在“res/drawable/rbtn_selector.xml”中创建一个 XML 文件,在下面添加单选按钮背景的 XML 代码。

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <!-- First Checked -->
          <item android:state_first="true" android:state_checked="true">
              <shape>
                  <gradient
                      android:angle="90"
                      android:startColor="@color/radio_button_selected_start"
                      android:endColor="@color/radio_button_selected_end"
                      android:type="linear" />
                  <!--<solid android:color="@android:color/holo_blue_dark" />-->
                  <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
                  <stroke android:width="@dimen/radio_button_border" android:color="@color/radio_button_border_selected" />
              </shape>
          </item>
      
          <!-- First Unchecked -->
          <item android:state_first="true" android:state_checked="false">
              <shape>
                  <gradient
                      android:angle="90"
                      android:startColor="@color/radio_button_unselected_start"
                      android:endColor="@color/radio_button_unselected_end"
                      android:type="linear" />
                  <!--<solid android:color="@android:color/holo_purple"/>-->
                  <corners android:topLeftRadius="10dp" android:topRightRadius="@dimen/radio_button_radius"/>
                  <stroke android:width="@dimen/radio_button_border" android:color="@color/radio_button_border_unselected" />
              </shape>
          </item>
      
          <!-- Last Checked -->
          <item android:state_last="true" android:state_checked="true">
              <shape>
                  <gradient
                      android:angle="90"
                      android:startColor="@color/radio_button_selected_start"
                      android:endColor="@color/radio_button_selected_end"
                      android:type="linear" />
                  <!--<solid android:color="@android:color/holo_green_dark" />-->
                  <corners android:bottomLeftRadius="@dimen/radio_button_radius" android:bottomRightRadius="@dimen/radio_button_radius"/>
                  <stroke android:width="@dimen/radio_button_border" android:color="@color/radio_button_border_selected" />
              </shape>
          </item>
      
          <!-- Last Unchecked -->
          <item android:state_last="true" android:state_checked="false">
              <shape>
                  <gradient
                      android:angle="90"
                      android:startColor="@color/radio_button_unselected_start"
                      android:endColor="@color/radio_button_unselected_end"
                      android:type="linear" />
                  <!--<solid android:color="@android:color/holo_red_dark"/>-->
                  <corners android:bottomLeftRadius="@dimen/radio_button_radius" android:bottomRightRadius="@dimen/radio_button_radius"/>
                  <stroke android:width="@dimen/radio_button_border" android:color="@color/radio_button_border_unselected" />
              </shape>
          </item>
      
      
      
          <!-- Default Checked -->
          <item android:state_checked="true">
              <shape>
                  <gradient
                      android:angle="90"
                      android:startColor="@color/radio_button_selected_start"
                      android:endColor="@color/radio_button_selected_end"
                      android:type="linear" />
                  <stroke android:width="@dimen/radio_button_border" android:color="@color/radio_button_border_selected" />
                  <!--<solid android:color="@android:color/holo_orange_dark" />-->
              </shape>
          </item>
      
          <!-- Default Unchecked -->
          <item android:state_checked="false">
              <shape>
                  <gradient
                      android:angle="90"
                      android:startColor="@color/radio_button_unselected_start"
                      android:endColor="@color/radio_button_unselected_end"
                      android:type="linear" />
                  <stroke android:width="@dimen/radio_button_border" android:color="@color/radio_button_border_unselected" />
                  <!--<solid android:color="@android:color/holo_green_light"/>-->
              </shape>
          </item>
      </selector>
      

      3) 在“res/drawable/rbtn_textcolor_selector.xml”中创建一个 XML 文件,在下面添加单选按钮文本选择器颜色的 XML 代码。(文本颜色选择器 xml 文件)

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:state_checked="true" android:color="@color/radio_text_selected"/>
          <item android:color="@color/radio_text_unselected"/>
      </selector>
      

      4) 为按钮设置样式:

      4.1) 以编程方式将一些 RoundedButton 添加到现有的 RadioGroup:

      RoundedButton newRadioButton = new RoundedButton(this.getActivity());
      
      if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
          newRadioButton.setBackgroundDrawable(this.getActivity().getResources().getDrawable(R.drawable.rbtn_selector));
      } else {
          newRadioButton.setBackground(this.getActivity().getResources().getDrawable(R.drawable.rbtn_selector));
      }
      newRadioButton.setTextColor(this.getActivity().getResources().getColorStateList(R.color.rbtn_textcolor_selector));
      

      4.2) Xml:

      <RoundedButton
          android:id="@+id/bt_id_1"
          android:background="@drawable/rbtn_selector"
          android:textColor="@drawable/rbtn_textcolor_selector" />
      

      5) 选择您自己的颜色和尺寸,我在示例中使用的是:

      <color name="radio_text_selected">#FFF</color>
      <color name="radio_text_unselected">#222</color>
      
      <color name="radio_button_selected_start">#5393c5</color>
      <color name="radio_button_selected_end">#6facd5</color>
      
      <color name="radio_button_unselected_start">#f9f9f9</color>
      <color name="radio_button_unselected_end">#eee</color>
      
      <color name="radio_button_border_selected">#2373a5</color>
      <color name="radio_button_border_unselected">#aaa</color>
      

      和:

      <dimen name="radio_button_radius">10dp</dimen>
      <dimen name="radio_button_border">0.7dp</dimen>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-11
        • 2021-10-04
        • 2017-08-29
        • 2022-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多