Android:如何使用togglebuttons获得一个radiogroup?

我想要一组button,用户可以select其中的一个作为选项。 它必须是一个类似于无线电通讯组的行为,但是我不希望广播电视圈出席。 我只想让用户只能切换其中一个button。

我想我需要像一个切换组。

在Android中是否存在这样的事情?

我只是重新使用 RadioGroup,就像这样:(请注意onClick属性,即点击button将触发您的Activity的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(查看),你会做任何需要发生的,特定于你的应用程序。 并调用RadioGroup的检查方法,切换视图的ID。 像这样:

 public void onToggle(View view) { ((RadioGroup)view.getParent()).check(view.getId()); // app specific stuff .. } 

您可以使用常规单选button,并为RadioButton背景使用图像,而不指定文本string:

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

对于背景,使用任何可绘制的,但很可能你会想要使用select器能够为不同的状态提供不同的图像。 最简单的版本只使用两个图像:

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

有了这个,单选button看起来就像一个普通的button(或者说,看起来像你提供的任何可绘制的),并且像收音机组中的单选button一样。

我尝试了上面列出的所有方法,但没有一个能够很好地工作。

试图破解一个单选button看起来像一个真正的button看起来不好。

最后,我拿了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> 

希望这可以帮助

以下是我如何做到的(不涉及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); 

我的解决scheme达到相同的效果,但不使用单选button。

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

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

un文件我的listview的项目:

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

在Activity类中:

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

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

您可以使用RadioButton和RadioGroup,但是我不知道您是否可以轻松地生成一个更适合您的应用程序的自定义单选button。 但是,如果你可以自己扩展单选button并覆盖绘制方法,或者查看一个小button可以集成到一个radiogroup中 ,那么它应该是可能的。 也许你可以为你的视图实现一个特殊的界面,然后在一个radiogroup中join一些自定义的button。

我用LinearLayout来代替RadioGroup,使用ButterKnife:

 @BindViews({R.id.one, R.id.two, R.id.three}) List<ToggleButton> mToggleGroup; @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 : mToggleGroup) { if (button.getId() != selected.getId()) { button.setChecked(false); } } } else { // Disallow deselecting the current button selected.toggle(); } } 

使用任何容器ViewGroup添加你的CompoundButtons (CheckBox,RadioButton,Switch,SwitchCompat,ToggleButton),然后在你的onCheckedChanged中调用一个实用函数清除其他button。

  <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对象。 由于你经常有一个onCheckedChangedcallback,只有新的代码是调用效用函数。

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