Android 特定单选按钮-为第一个/最后一个按钮设置不同样式的最简单方法

Android 特定单选按钮-为第一个/最后一个按钮设置不同样式的最简单方法,android,android-layout,custom-controls,radio-button,xml-drawable,Android,Android Layout,Custom Controls,Radio Button,Xml Drawable,我希望在我的布局中实现这种特定类型的单选按钮: =第一项、中间项和最后一项具有不同圆角的不同图形。我可以想象用3种不同样式的按钮(使用自定义样式、有状态的绘图)来实现这一点 我使用自定义切换按钮来实现这一点。我想利用drawable selector为第一个和最后一个项目使用不同的drawable,因此我使用: <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item an

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

=第一项、中间项和最后一项具有不同圆角的不同图形。我可以想象用3种不同样式的按钮(使用自定义样式、有状态的绘图)来实现这一点

我使用自定义切换按钮来实现这一点。我想利用drawable selector为第一个和最后一个项目使用不同的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\u first
state\u last
不是在我的
线性布局中自动设置的,因此每次单击按钮时我都必须手动设置它们。是否有某种方式,某种布局,可以自动设置这些状态?感谢您的帮助。

您应该查看Wordpress Android项目。它们使用一个“切换按钮”,提供类似的功能。对于.xml外观。要下载完整的源代码,请转到

它不会和你想要的一样,因为它们只有切换按钮,但这很可能适合你需要的单选按钮样式(如果它还没有内置的话)


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

没有发现什么特别之处,因此这里有一个“默认”解决方案,带有自定义切换按钮。第一个按钮、中间按钮和最后一个按钮有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>

9dp
9dp
包装内容
0dp
1.
@可拉拔/无线电头
@可拉拔/无线电中置
@可拉拔/无线电
以及用于处理切换按钮事件的活动的简短代码,因此在同一时间仅选中1个按钮,并且禁用选中按钮:

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);
        }
    };
}
公共类AktivityActivity扩展活动
{
ArrayList切换按钮;
创建时的公共void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.aktivity);
initToggleButtons();
}
私有void initToggleButtons()
{
切换按钮=新建ArrayList();
切换按钮。添加((切换按钮)findViewById(R.id.toggle_1));
切换按钮。添加((切换按钮)findViewById(R.id.toggle_2));
切换按钮。添加((切换按钮)findViewById(R.id.toggle_3));
//收听所有切换按钮
用于(切换按钮切换按钮:切换按钮)
切换\u按钮。setOnCheckedChangeListener(检查\u listener);
//检查第一个切换按钮
updateToggleButtons(切换按钮.get(0));
}
//只能选中一个切换,并且必须禁用“选中”按钮
私有void updateToggleButtons(切换按钮选中_按钮)
{
用于(切换按钮切换按钮:切换按钮)
{
切换按钮。设置选中(切换按钮==选中按钮);
切换按钮。设置启用(切换按钮!=选中按钮);
}
}
//切换按钮更改侦听器
OnCheckedChangeListener检查\u listener=new OnCheckedChangeListener()
{
检查更改后的公共无效(复合按钮视图,布尔值已检查)
{
如果(已检查)
更新切换按钮((切换按钮)按钮视图);
}
};
}
也许它对某些人有用…

我发现最简单的方法是:

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文件)


4) 将样式设置为按钮:

4.1)以编程方式向现有组添加一些RoundedButton:

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));
RoundedButton newRadioButton=newroundedbutton(this.getActivity());
if(android.os.Build.VERSION.SDK\u INT
4.2)Xml:


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>
#FFF
#222
#5393c5
#6facd5
#f9f9f9
#eee
#2373a5
#aaa
以及:

10dp
0.7dp

谢谢你的提示。我现在正在检查这些代码,但我不确定是否看到与我的案例类似的东西。我认为他们只使用了一种类型的切换按钮。但是我同意有很多很好的工作风格,如果没有好的“现成的解决方案”,我将不得不自己做。
<RoundedButton
    android:id="@+id/bt_id_1"
    android:background="@drawable/rbtn_selector"
    android:textColor="@drawable/rbtn_textcolor_selector" />
<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>