2010-11-22 70 views
25

我有一个列表查看,这是在singleChoice模式。我只需要在旁边显示一个RadioButton,当点击突出显示它被选中时,以及当点击另一个时,一个回到未选择状态,并且新的状态被选中。为什么这么难?这不应该是这么复杂。我花了DAYS寻找一个适当的答案,我什么也没找到,所以我希望以清晰和简洁的方式问。单选按钮模式和自定义行布局的Android ListView与RadioButton

我的布局为ListView (R.layout.view_orders)

<?xml version="1.0" encoding="utf-8"?> 
<ListView 
     android:choiceMode="singleChoice" 
     android:id="@android:id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:divider="@drawable/list_divider" 
     android:dividerHeight="1px" 
     android:focusable="false" 
     android:focusableInTouchMode="false" 
     android:cacheColorHint="#00000000"> 
</ListView> 

我的自定义行(R.layout.orders_row)

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout 
    xmlns:app="http://schemas.android.com/apk/res/com.xxx.xxxxxx" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:padding="6dip"> 

    <com.xxx.xxxxxx.VerticalLabelView 
     app:text="SHORT" 
     app:textColor="#666" 
     app:textSize="14sp" 
     android:id="@+id/state" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_centerVertical="true" /> 

    <TextView 
     android:id="@+id/quantity" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_toRightOf="@id/state" 
     android:layout_centerVertical="true" 
     android:gravity="center" 
     android:textSize="40sp" 
     android:layout_margin="2dip" 
     android:minWidth="30dip" 
     android:textColor="#555" /> 


    <RelativeLayout 
     android:layout_toRightOf="@id/quantity" 
     android:layout_centerVertical="true" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 

     <TextView 
      android:id="@+id/instrument" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:textSize="20sp" 
      android:textColor="#333" 
      android:layout_marginLeft="2dip" 
      android:layout_marginRight="2dip" 
      /> 


     <TextView 
      android:id="@+id/deets" 
      android:layout_below="@id/instrument" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:textSize="16sp" 
      android:textColor="#888" 
      android:layout_marginLeft="2dip" 
      android:layout_marginRight="2dip" 
      /> 

    </RelativeLayout> 

     <RadioButton 
      android:id="@+id/selector" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentRight="true" 
      android:layout_centerVertical="true" 
      /> 

</RelativeLayout> 

的onCreate( )方法:

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.view_orders); 
    client = new Client(handler); 
    ola = new OrdersAdapter(this, R.layout.orders_row, Orders); 
    setListAdapter(ola); 
    final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading); 
    panel = (PositionsPanel) findViewById(R.id.panel); 
    Utility.showProgressBar(loading); 
    client.Connect("orders"); 
} 

现在一切工作如预期,你点击一个单选按钮,并通过它的标签,我可以适当地从列表中选择该项目,并操纵它如何我想要的。但是,当第一个单选按钮被点击时,最后一个将被选中。再次点击相同的单选按钮,现在它也被选中。再次单击它并没有任何反应,最后一个和第一个都被选中。现在,我单击列表中的任何其他人,它将按照预期进行选择。单击所选单选按钮中的任何一个,但什么也没有发生,单选按钮保持选中状态

我曾尝试使用下面的的onCreate()尝试:

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.view_orders); 
    client = new Client(handler); 
    ola = new OrdersAdapter(this, android.R.layout.simple_list_item_single_choice, Orders); 
    setListAdapter(ola); 
    final RelativeLayout loading = (RelativeLayout) findViewById(R.id.loading); 
    panel = (PositionsPanel) findViewById(R.id.panel); 
    Utility.showProgressBar(loading); 
    client.Connect("orders"); 
} 

而且只是没有显示出单选按钮都没有。 真棒

现在可能(阅读:最有可能),我只是密集,并不能解决这个问题,但我看到这个问题很多问了没有真正的答案。很多对其他教程或Commonsware人的书的参考。然而,评论现在已经老了,他的存储库已经发生了很大的变化,这些都不再是正确的答案。

那么,有没有人有任何想法如何获得预期的功能呢?否则,只需将我沿GMail应用程序的源代码传递给我即可。 :)

回答

8

请记住,在ListView行项目RECYCLED。这很可能解释了为什么一行中的行为会影响另一行。在马克的书中挖掘一下,你会发现这一点。

如果您使用带有列表的适配器,则可以在适配器上使用getView()为创建/循环使用的每一行添加单击处理程序,并确保状态正确管理为行项目被创建和回收。

我的方法是将状态存储在我自己的数据结构中,然后在用户滚动ListView时使用getView()在UI中对其进行镜像。可能有更好的解决方案,但这对我很有用。

+0

所以这正是发生了什么。我不知道为什么其他答案不只是陈述这个简单的事实。在意识到我正在使用convertView并将其回收后,它非常明显。一两分钟内使用Google,我知道如何解决这个问题。我看了马克的书,第9章,“喜欢用列表”,他的RateList例子在那里详细说明,这很清楚地解释了它。任何有此问题的人都可以通过Mark Murphy查看Beginning Android的章节。 – 2010-11-22 23:37:05

+0

Android中的这些怪癖使其成为一个陡峭的学习曲线,但一旦明白我们确实获得了回收的性能优势。 – 2010-11-23 15:12:43

+0

因此,这并没有结束工作,我经历了它,而回收利用肯定是我看到的背后的原因,马克的书没有详细说明如何解决我遇到的具体问题。 – 2010-11-23 18:57:18

2

我刚刚有一个类似的问题。它似乎与意见回收相关。但我在任何地方都添加了Log,并注意到回收处理很好。 问题是RadioButtons处理。我用:

if(answer == DBAdapter.YES){ 
    rbYes.setChecked(true); 
    rbNo.setChecked(false);      
} 
else if(answer == DBAdapter.NO){ 
    rbYes.setChecked(false); 
    rbNo.setChecked(true); 
} 
else{ 
    rbYes.setChecked(false); 
    rbNo.setChecked(false); 
}     

而且做起来的正确的方法是:

if(answer == DBAdapter.YES){ 
    rbYes.setChecked(true); 
} 
else if(answer == DBAdapter.NO){ 
    rbNo.setChecked(true); 
} 
else{ 
    RadioGroup rg = (RadioGroup)(holder.answerView); 
    rg.clearCheck(); 
}     
3

我的名字是Gourab辛哈。我解决了这个问题。我已编写此代码来解决它。我希望这可以帮助你。谢谢。我需要3个小时。

public void add_option_to_list(View v){ 


    LinearLayout ll = (LinearLayout)v.getParent(); 
    LinearLayout ll_helper = null; 
    LinearLayout ll2 = (LinearLayout)ll.getParent(); 
    LinearLayout ll3 = (LinearLayout)ll2.getParent(); 

    ListView ll4 = (ListView)ll3.getParent(); 
    //RadioButton rb1= (RadioButton)ll.getChildAt(1); 
    Toast.makeText(getApplicationContext(), ", "+ll4.getChildCount(), Toast.LENGTH_LONG).show();  
    //ll.findViewById(R.id.radio_option_button) 
    for(int k=0;k<ll4.getChildCount();k++){ 

     ll3 = (LinearLayout)ll4.getChildAt(k); 
     ll2 = (LinearLayout)ll3.getChildAt(0); 
     ll_helper = (LinearLayout)ll2.getChildAt(0); 
     RadioButton rb1 = (RadioButton)ll_helper.getChildAt(1); 
     if(rb1.isChecked()) 
     rb1.setChecked(false); 


    } 
    RadioButton rb1 = (RadioButton)ll.getChildAt(1); 
    rb1.setChecked(true); 
    //Toast.makeText(getApplicationContext(), ""+((TextView)ll.getChildAt(4)).getText().toString(), Toast.LENGTH_LONG).show(); 


    } 

的XML:在活动

<RadioButton 
    ... 
    android:onClick="onClickRadioButton" 
    ... 
/> 

然后:

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

    <LinearLayout 

     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" > 


     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal" > 

      <TextView 
       android:id="@+id/id" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="Category Name" 
       android:textAppearance="?android:attr/textAppearanceMedium" 
       android:visibility="gone" /> 

      <RadioButton 
       android:id="@+id/radio_option_button" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:onClick="add_option_to_list" 
       android:text="" /> 

      <TextView 
       android:id="@+id/option_name" 
       android:layout_width="wrap_content" 
       android:layout_height="fill_parent" 
       android:layout_marginLeft="3dp" 
       android:layout_weight="5.35" 
       android:text="Category Name" 
       android:textAppearance="?android:attr/textAppearanceMedium" /> 



      <TextView 
       android:id="@+id/option_price" 
       android:layout_width="76dp" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="10dp" 
       android:gravity="right" 
       android:text="$0.00" 
       android:textAppearance="?android:attr/textAppearanceMedium" /> 

      <TextView 
       android:id="@+id/option_unit_price" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="5dp" 
       android:gravity="right" 
       android:text="$0.00" 
       android:textAppearance="?android:attr/textAppearanceMedium" 
       android:visibility="gone" /> 
     </LinearLayout> 

    </LinearLayout> 

</LinearLayout> 
7

我已经测试了一个简单的解决方案:

加入这一行的XML文件的单选按钮类使用ListView,添加以下内容:

private RadioButton listRadioButton = null; 
    int listIndex = -1; 

    public void onClickRadioButton(View v) { 
     View vMain = ((View) v.getParent()); 
     // getParent() must be added 'n' times, 
     // where 'n' is the number of RadioButtons' nested parents 
     // in your case is one. 

     // uncheck previous checked button. 
     if (listRadioButton != null) listRadioButton.setChecked(false); 
     // assign to the variable the new one 
     listRadioButton = (RadioButton) v; 
     // find if the new one is checked or not, and set "listIndex" 
     if (listRadioButton.isChecked) { 
      listIndex = ((ViewGroup) vMain.getParent()).indexOfChild(vMain); 
     } else { 
      listRadioButton = null; 
      listIndex = -1 
     } 
    } 

有了这个简单的代码,只有一个RadioButton被选中。 如果您触摸已经选中的那个,那么它将返回到未选中模式。

“listIndex”正在跟踪选中的项目,如果没有则为-1。

如果你想保持总是一个检查,然后在onClickRadioButton代码应该是:

public void onClickRadioButton(View v) { 
     View vMain = ((View) v.getParent()); 
     int newIntex = ((ViewGroup) vMain.getParent()).indexOfChild(vMain); 
     if (listIndex == newIndex) return; 

     if (listRadioButton != null) { 
       listRadioButton.setChecked(false); 
     } 
     listRadioButton = (RadioButton) v; 
     listIndex = newIndex; 
    } 
-1

在您的适配器:

public void setChecked(View v, int position) { 

    ViewGroup parent = ((ViewGroup) v.getParent()); // linear layout 

    for (int x = 0; x < parent.getChildCount() ; x++) { 

     View cv = parent.getChildAt(x); 
     ((RadioButton)cv.findViewById(R.id.checkbox)).setChecked(false); // your checkbox/radiobtt id 
    } 

    RadioButton radio = (RadioButton)v.findViewById(R.id.checkbox); 
    radio.setChecked(true); 
} 

您的活动/片段:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      ((ModelNameAdapter)adapter).setChecked(view, position); 

     } 
    }); 
1

您可以实现更简单,遵循此。它在棉花糖

1试过)有一个CheckedTextView

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:checkMark="?android:attr/listChoiceIndicatorSingle" 
    android:padding="10dp" 
    android:textAppearance="?android:attr/textAppearanceMedium"> 

  • ListChoiceIndicatorSingle将显示RadioButton

  • ListChoiceIndicatorMultiple将显示CheckBox

不要忘了choiceMode:SingleListView

0

在适配器内部

viewHolder.radioBtn.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        Log.e("called", "called"); 
        if(position != mSelectedPosition && mSelectedRB != null){ 
         mSelectedRB.setChecked(false); 
        } 



        mSelectedPosition = position; 
        mSelectedRB = (RadioButton)v; 
       } 
      }); 

      viewHolder.radioBtn.setText(mList[position]); 
      if(mSelectedPosition != position){ 
       viewHolder.radioBtn.setChecked(false); 

      }else{ 
       viewHolder.radioBtn.setChecked(true); 

       if(mSelectedRB != null && viewHolder.radioBtn != mSelectedRB){ 
        mSelectedRB = viewHolder.radioBtn; 
       } 
      } 

添加样式的单选按钮

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:drawable="@drawable/tick" android:state_checked="true"/> 
    <item android:drawable="@drawable/untick" android:state_checked="false"/> 

</selector> 

,并在XML使用单选按钮样式

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

    <RadioButton 
     android:id="@+id/radioBtn" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:button="@null" 
     android:checked="true" 
     android:drawablePadding="30dp" 
     android:drawableRight="@drawable/checkmark" 
     android:text="first" /> 

</RelativeLayout>