47

我想要一组按钮,用户可以在其中选择其中一个作为选项。它必须是类似行为的单选按钮组,但我不希望单选圈出现。我只希望用户只能切换其中一个按钮。

我想我需要一个类似切换组的东西。

Android中是否存在类似的东西?

4

11 回答 11

90

我只是重复使用这样的RadioGroup:(请注意onClick属性,即单击按钮将触发您的活动onToggle(View)方法。

<RadioGroup android:id="@+id/toggleGroup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:orientation="horizontal"
        >

    <ToggleButton android:id="@+id/btn_Letter"
                  android:layout_height="wrap_content"
                  android:layout_width="fill_parent"
                  android:layout_weight="1"
                  android:textSize="14sp"
                  android:textOn="Letter"
                  android:textOff="Letter"
                  android:onClick="onToggle"
                  android:checked="true"
            />
    <ToggleButton android:id="@+id/btn_A4"
                  android:layout_height="wrap_content"
                  android:layout_width="fill_parent"
                  android:layout_weight="1"
                  android:textSize="14sp"
                  android:textOn="A4"
                  android:textOff="A4"
                  android:onClick="onToggle"
            />
</RadioGroup>

在您的活动或其他地方,您可以定义一个侦听器,例如

static final RadioGroup.OnCheckedChangeListener ToggleListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(final RadioGroup radioGroup, final int i) {
            for (int j = 0; j < radioGroup.getChildCount(); j++) {
                final ToggleButton view = (ToggleButton) radioGroup.getChildAt(j);
                view.setChecked(view.getId() == i);
            }
        }
    };

并注册它,例如onCreate()

@Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     this.setContentView(R.layout.scan_settings);

     ((RadioGroup) findViewById(R.id.toggleGroup)).setOnCheckedChangeListener(ToggleListener);    
 }

最后onToggle(View),你会做任何需要发生的事情,具体到你的应用程序。并使用切换视图的 ID调用 RadioGroup 的检查方法。像这样:

public void onToggle(View view) {
    ((RadioGroup)view.getParent()).check(view.getId());
    // app specific stuff ..
}
于 2011-04-29T22:12:53.657 回答
13

您可以使用常规单选按钮并将图像用作 RadioButton 背景,并且不指定文本字符串:

<RadioButton 
android:id="@+id/custom_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
    android:button="@null"
    android:background="@drawable/button_custom"
    />

对于背景,请使用任何可绘制对象,但很可能您希望使用选择器来为不同的状态提供不同的图像。最简单的版本只使用两个图像:

<item android:state_checked="true" android:state_pressed="true"
      android:drawable="@drawable/custom_selected" />
<item android:state_checked="false" android:state_pressed="true"
      android:drawable="@drawable/custom_normal" />

<item android:state_checked="true" android:state_focused="true"
      android:drawable="@drawable/custom_selected" />
<item android:state_checked="false" android:state_focused="true"
      android:drawable="@drawable/custom_normal" />

<item android:state_checked="false" android:drawable="@drawable/custom_normal" />
<item android:state_checked="true" android:drawable="@drawable/custom_selected" />

有了这个,单选按钮看起来像一个普通按钮(或者更确切地说,看起来像你提供的任何可绘制对象)并且表现得像一个单选按钮组中的单选按钮。

于 2010-09-03T17:28:18.070 回答
3

这是我设法做到的(不RadioGroup涉及):

private CompoundButton.OnCheckedChangeListener toggleListener = new CompoundButton.OnCheckedChangeListener()
{
    boolean avoidRecursions = false;

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
    {
        if(avoidRecursions) return;
        avoidRecursions = true;

        // don't allow the un-checking
        if(!isChecked)
        {
            buttonView.setChecked(true);
            avoidRecursions = false;
            return;
        }

        // un-check the previous checked button
        if(buttonView != toggleButton1 && toggleButton1.isChecked()) toggleButton1.setChecked(false);
        else if(buttonView != toggleButton2 && toggleButton2.isChecked()) toggleButton2.setChecked(false);
        else if(buttonView != toggleButton3 && toggleButton3.isChecked()) toggleButton3.setChecked(false);
        else if(buttonView != toggleButton4 && toggleButton4.isChecked()) toggleButton4.setChecked(false);

        avoidRecursions = false;
    }
};

// ...

toggleButton1.setOnCheckedChangeListener(toggleListener);
toggleButton2.setOnCheckedChangeListener(toggleListener);
toggleButton3.setOnCheckedChangeListener(toggleListener);
toggleButton4.setOnCheckedChangeListener(toggleListener);
于 2015-04-08T23:12:53.780 回答
3

我尝试了上面列出的所有方法,但没有一个真正奏效。

试图破解一个单选按钮看起来像一个真正的按钮看起来很糟糕。

最终,我只使用了 RadioGroup 源代码并将其修改为接受 ToggleButton 而不是 RadioButton。效果很好!

这是 Github 上的来源:ToggleGroup

用法:

    <com.rapsacnz.ToggleGroup
    android:id="@+id/deal_detail_toolbar"
    android:layout_width="fill_parent"
    android:layout_height="60dip"
    android:layout_alignParentBottom="true"
    android:background="@drawable/bgnd_toggle_button">
    <ToggleButton
        android:id="@+id/b1"
        android:textOn="@string/tab_1_label"
        android:textOff="@string/tab_1_label"
        android:textSize="10sp"
        android:textColor="@color/tab_button_color"
        android:checked="true"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_weight="1"
        android:drawableTop="@drawable/toggle_spotlight"
        android:drawablePadding="-5dp "
        android:gravity="bottom|center"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="@drawable/bgnd_transparent" />
    <ToggleButton
        android:id="@+id/b2"
        android:textOn="@string/tab_2_label"
        android:textOff="@string/tab_2_label"
        android:textSize="10sp"
        android:textColor="@color/tab_button_color"
        android:checked="false"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_weight="1"
        android:drawableTop="@drawable/toggle_browse"
        android:gravity="bottom|center"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="@drawable/bgnd_transparent" />

    <ToggleButton
        android:id="@+id/b3"
        android:textOn="@string/tab_3_label"
        android:textOff="@string/tab_3_label"
        android:textSize="10sp"
        android:textColor="@color/tab_button_color"
        android:checked="false"
        android:layout_width="fill_parent"
        android:layout_height="60dp"
        android:layout_weight="1"
        android:drawableTop="@drawable/toggle_purchased"
        android:gravity="bottom|center"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="@drawable/bgnd_transparent" />
</com.rapsacnz.ToggleGroup>

希望这可以帮助

于 2011-03-22T23:20:17.180 回答
3

我正在使用 Kotlin,我尝试了 Wolf Paulus 的答案,但对我来说效果不佳。我玩弄了它,并能够通过以下方式使其工作:首先,我从 xml 中删除了“onClick”:

    <RadioGroup android:id="@+id/toggleGroup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:orientation="horizontal"
        >

    <ToggleButton android:id="@+id/btn_Letter"
                  android:layout_height="wrap_content"
                  android:layout_width="fill_parent"
                  android:layout_weight="1"
                  android:textSize="14sp"
                  android:textOn="Letter"
                  android:textOff="Letter"
                  android:checked="true"
            />
    <ToggleButton android:id="@+id/btn_A4"
                  android:layout_height="wrap_content"
                  android:layout_width="fill_parent"
                  android:layout_weight="1"
                  android:textSize="14sp"
                  android:textOn="A4"
                  android:textOff="A4"
            />
</RadioGroup>

我没有使用ToggleListener,而是在里面onCreate()听了ToggleButton我拥有的每个 s:

    btn_Letter.setOnClickListener { it -> onToggle(it) }
    btn_A4.setOnClickListener { it -> onToggle(it) }

而最重要的部分,onToggle(btn: View)

private fun onToggle(btn: View) {
    val radioGroup = (btn.parent as RadioGroup)
    for (index in 0 until radioGroup.childCount) {
        val child = radioGroup.getChildAt(index) as ToggleButton
        child.isChecked = child.id == btn.id
       // do what ever else you need to do
    }
}

就是这个。我希望这有帮助。

于 2019-01-10T16:09:33.940 回答
1

我的解决方案实现了相同的效果,但不使用单选按钮。

对于 xml,首先在“@drawable/myselectorfile”中取消“选择器”:

   <?xml version="1.0" encoding="UTF-8"?>
      <selector
           xmlns:android="http://schemas.android.com/apk/res/android">
       <item android:state_checked="false"
        android:drawable="@drawable/icon_off" />
       <item android:state_checked="true"
        android:drawable="@drawable/icon_on" />
   </selector>

我的列表视图项目的联合国文件:

   <?xml version="1.0" encoding="utf-8"?>
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:orientation="horizontal" >

    <TextView
        android:id="@+id/txtInfo"
        android:layout_width="140dp"
        android:layout_height="wrap_content"
        android:paddingTop="15dip" />

   <ToggleButton
       android:id="@+id/BtnToggle"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentRight="true"
       android:layout_alignParentTop="true"
       android:layout_marginRight="14dp"
       android:background="@drawable/toggle_style"
       android:padding="10dip"
       android:textOff=""
       android:textOn="" 
       android:focusable="false"/>  

   </LinearLayout>

和我的列表视图:

   <?xml version="1.0" encoding="utf-8"?>
      <ListView xmlns:android="http://schemas.android.com/apk/res/android"
       android:id="@+id/lv_lista"
       android:layout_width="match_parent"
       android:layout_height="match_parent" >
    </ListView> 

在 oncreate 方法中:

     lista.setOnItemClickListener(new OnItemClickListener() { 
        @SuppressWarnings("deprecation")
        @Override
        public void onItemClick(AdapterView<?> pariente, View view, int    posicion, long id) {
        @SuppressWarnings("unused")
        ListEntity elegido = (ListEntity) pariente.getItemAtPosition(posicion); 

        varToggle = (ToggleButton) view.findViewById(R.id.BtnToggle);
        varToggle.setChecked(true);

                    // showDialog(0); // dialog optional

                   //restart btn's
                  reStart(posicion);
        }
        });

在活动类中:

         @Override
         protected Dialog onCreateDialog(int id){
            Dialog dialogo = crearDialogoConfirmacion(); 
            return dialogo; 
         }

         public void reStart(int posicion){ 

         for(int j=0;j<lista.getCount();j++)
             {
               View vista = lista.getChildAt(j);
               ToggleButton varToggle2 = (ToggleButton) vista.findViewById(R.id.BtnToggle);
               if(j != posicion){ varToggle2.setChecked(false); }              
              } 
          }
于 2013-06-20T08:22:49.047 回答
1

我使用 ButterKnife 使用 LinearLayout 而不是 RadioGroup 来做到这一点:

@BindViews({R.id.one, R.id.two, R.id.three})
List<ToggleButton> toggleGroup;

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    ButterKnife.bind(this, view);
}

@OnClick({R.id.one, R.id.two, R.id.three})
public void toggle(ToggleButton selected) {
    if (selected.isChecked()) {
        // Deselect other buttons
        for (ToggleButton button : toggleGroup) {
            if (button.getId() != selected.getId()) {
                button.setChecked(false);
            }
        }
    } else {
        // Disallow deselecting the current button
        selected.toggle();
    }
}
于 2017-03-17T14:24:16.450 回答
0

所以你想要一次只能选择一个按钮?如果您不显示单选按钮,用户如何知道她选择了什么?

您可以使用 RadioButton 和 RadioGroup 但我不知道您是否可以轻松地生成一个看起来更适合您的应用的自定义单选按钮。但是,如果您可以扩展 radiobutton 本身并覆盖 draw 方法,或者查看可以将哪些孩子的按钮集成到radiogroup中,那么它应该是可能的。也许您可以为您的视图实现一个特殊的界面,然后将您的一些自定义按钮连接到一个单选组中。

于 2010-03-04T16:09:57.173 回答
0

使用任何容器ViewGroup添加您的CompoundButtons(CheckBox、RadioButton、Switch、SwitchCompat、ToggleButton),然后在您的onCheckedChanged 中 调用一个实用程序函数来清除其他按钮。

       <LinearLayout
            android:id="@+id/toggle_group"
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <ToggleButton
                android:id="@+id/toggle_btn1"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:textOff="Off1"
                android:textOn="On1" />

            <View
                android:layout_width="2dp"
                android:layout_height="match_parent"
                android:layout_margin ="8dp"
                android:background="#ffff" />

            <ToggleButton
                android:id="@+id/toggle_btn2"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:textOff="Off2"
                android:textOn="On2" />
        </LinearLayout>

在您的onCheckedChanged中,处理状态更改并调用实用程序方法来清除其他子项。以下支持从ViewGroup派生的所有视图容器组,并允许您在容器中混合非CompoundButton对象。由于您通常已经有一个onCheckedChanged回调,因此只有新代码是调用实用程序函数。

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    int id = buttonView.getId();
    switch (id) {
        case R.id.toggle_btn1:
            if (isChecked) {
                doBtn1Action();
                doRadioGroupChange((ViewGroup)buttonView.getParent(), id);
            }
            break;
        case R.id.toggle_btn2:
            if (isChecked) {
                doBtn2Action();;
                doRadioGroupChange((ViewGroup)buttonView.getParent(), id);
            }
            break;

这是清除孩子的实用功能。

/**
 * Emulate radioGroup and clear buttons which don't match checkedId.
 * @param viewGroup
 * @param checkedId
 */
private static void doRadioGroupChange(final ViewGroup viewGroup, final int checkedId) {
    for (int rgIdx = 0; rgIdx < viewGroup.getChildCount(); rgIdx++) {
        View child = viewGroup.getChildAt(rgIdx);
        if (child instanceof  CompoundButton) {
            final CompoundButton view = (CompoundButton) viewGroup.getChildAt(rgIdx);
            view.setChecked(view.getId() == checkedId);
        }
    }
}
于 2017-05-04T21:42:54.370 回答
0

科特林版本:

for(index in 0..(radioGroup.childCount-1))
                (radioGroup.getChildAt(index) as ToggleButton).isChecked = false
于 2018-08-14T07:42:33.110 回答
0
public void OnTabSelected(View v){
        RadioGroup radioGroup = (RadioGroup)v.getParent();
        for (int j = 0; j < radioGroup.getChildCount(); j++) {
            ToggleButton toggleButton = (ToggleButton) radioGroup.getChildAt(j);
            toggleButton.setChecked(v.getId() == toggleButton.getId());
        }
    }
于 2018-02-19T09:48:23.113 回答