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

发布于 2024-12-05 01:44:48 字数 1247 浏览 2 评论 0原文

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

在此处输入图像描述

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

我正在使用自定义切换按钮来实现此功能。我想利用可绘制选择器为第一个和最后一个项目使用不同的可绘制对象,因此我使用:

<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 中不会自动设置,因此每次单击按钮时我都必须手动设置它们。是否有某种方式、某种布局可以自动设置这些状态?感谢您的帮助。

I would like to achieve this specific type of radio buttons in my layout:

enter image description here

= different graphics for the first item, middle ones, and last one, which have different rounded corners. I can imagine doing this with different styles for the 3 types of buttons (using custom styles, stateful drawables).

I'm implementing this using custom toggle buttons. I would like to take advantage of drawable selector for using different drawables for the first and the last items, so I use:

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

But now I have a problem, that states state_first, state_last are not set automatically in my LinearLayout, so I have to set them manually every time the buttons are clicked. Is there some way, some layout, where these states are set automatically? Thank you for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

八巷 2024-12-12 01:44:48

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

以及用于处理切换按钮事件的活动的简短代码,因此同一按钮中仅检查 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);
        }
    };
}

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

Found nothing special, so here is a "default" solution, with custom toggle buttons. Here are 3 different styles (put to styles.xml) for first, middle ones and last buttons:

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

And a short code for activity handling the events of toggle buttons, so only 1 button is checked in the same time, and checked button is disabled:

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);
        }
    };
}

Maybe it can be usefull for somebody...

故事与诗 2024-12-12 01:44:48

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

它不会与您想要的相同,因为它们只有切换按钮,但这很可能适合您所需的单选按钮样式(如果尚未内置)。

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

You should check out the Wordpress Android project. They use a "ToggleButton" that gives similar functionality. For the .xml look here. To download the complete source go here.

It wont be the same as what you want, as they just have toggle buttons, but that can most likely be adapted for your needed style of radio buttons (if it's not already built in).

The Wordpress Android project helped me learn a lot. Everything from theming, custom buttons, custom layouts, toggle buttons, xmlrpc, and more.

琉璃繁缕 2024-12-12 01:44:48

在此处输入图像描述

我发现执行此操作的最简单方法是:

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>

enter image description here

The simplest way I found for doing this is:

1) Extend RadioButton class as follows:

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) Create One XML file in "res/drawable/rbtn_selector.xml" add below XML code for Radio Button background.

<?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) Create One XML file in "res/drawable/rbtn_textcolor_selector.xml" add below XML code for Radio Buttons Text selector color.(Text Color Selector xml file)

<?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) Set your style to the button:

4.1) Programmatically add some RoundedButton to an exixsting 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) Choose your own colors and dimensions the one I used in the example are:

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

and:

<dimen name="radio_button_radius">10dp</dimen>
<dimen name="radio_button_border">0.7dp</dimen>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文