自定义单选 ListView

Posted

技术标签:

【中文标题】自定义单选 ListView【英文标题】:Custom Single choice ListView 【发布时间】:2012-01-10 08:27:06 【问题描述】:

我想制作一个自定义列表视图,在一行中有两个 TextView 和一个单选按钮。在 listitem 点击单选按钮状态应该是切换。我不能在这里使用简单适配器。

我已经问过这个问题Single choice ListView custom Row Layout,但没有找到任何令人满意的解决方案。

我目前正在做的是使用 simple_list_item_single_choice 并将两个 TextView 的数据放在一个由一些空格分隔的单个视图中。但这里情况变得更糟(如下图所示)。

我想要的是固定大小和价格的位置,并将列表视图作为单一选择。

列表的 XML 布局可以是这样的:

**<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_
    android:layout_
    android:gravity="center_horizontal"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tv_size"
        android:layout_
        android:layout_
        android:text="TextView"
        android:textSize="15sp"
        android: />

    <TextView
        android:id="@+id/tv_price"
        android:layout_
        android:layout_
        android:text="TextView"
        android:textSize="15sp"
        android: />

    <RadioButton
        android:id="@+id/radioButton"
        android:layout_
        android:layout_ />

</LinearLayout>**

如何为此制作自定义适配器?

【问题讨论】:

查看本教程vogella.de/articles/AndroidListView/article.html 你可以在GitHub查看这个例子 检查这个以备将来参考youtube.com/watch?v=s4JwU28VMko 【参考方案1】:

我有类似的情况,但很容易解决。试试这个:

    扩展 ListActivity 并设置您的自定义列表适配器

    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE); //if you need title to be hidden
        setContentView(R.layout.activity_add_to_cart_select_service_plan);
        setListAdapter(adapter);
    
    

    创建一个字段来存储适配器中选定的索引位置

    int selectedIndex = -1;
    

    为其提供接口

    public void setSelectedIndex(int index)
        selectedIndex = index;
    
    

    根据 getView() 中选择的索引将选中状态设置为 true 或 false

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        RadioButton rbSelect = (RadioButton) convertView
                            .findViewById(R.id.radio1);
        if(selectedIndex == position)
        rbSelect.setChecked(true);
        
        else
        rbSelect.setChecked(false);
        
    
    

    将单选按钮的可聚焦和可点击属性设置为“false”

     <RadioButton
         android:id="@+id/radio1"
         android:checked="false"
         android:focusable="false"
         android:clickable="false"
     />
    

    将 listview descendantFocusability 属性设置为 'beforeDescendants'

    <ListView
        android:id="@android:id/list"
        android:choiceMode="singleChoice"
        android:descendantFocusability="beforeDescendants"
    />
    

    覆盖 onListItemClick

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) 
        super.onListItemClick(l, v, position, id);
        adapter.setSelectedIndex(position);
        adapter.notifyDataSetChanged();
    
    

就是这样..运行并检查

【讨论】:

这应该是公认的答案。快速且易于实施。【参考方案2】:

我整个上午都在寻找这个问题的答案,到目前为止我发现的最有用的是this article。

虽然我还没有实施它建议的解决方案,但听起来它在正确的轨道上。

基本上,单选ListView 期望您为其提供的小部件实现Checkable 接口。 LinearLayout 等人不要。因此,您需要创建一个继承 LinearLayout 的自定义布局(或您想要用于项目的任何布局)并实现必要的接口。

【讨论】:

绝对是要走的路。该链接包含您需要的所有内容,只需使用该类并在您的 XML 中引用它,如图所示。 非常感谢 - 非常有帮助! 如果你想使用自己的布局,f.e.使用 RadioButtons 而不是 CheckableTextView 记得为按钮设置 android:focusable="false" android:focusableInTouchMode="false"。【参考方案3】:

使用 Hack 处理了类似的问题(不是完美的解决方案..但仍然有效..)

 listview.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 




                for (int i = 0; i < parent.getCount() ; i ++)
                

                    View v = parent.getChildAt(i);
                    RadioButton radio = (RadioButton) v.findViewById(R.id.radio);
                    radio.setChecked(false);

                

                    RadioButton radio = (RadioButton) view.findViewById(R.id.radio);
                    radio.setChecked(true);



            
        );

【讨论】:

这是最好的解决方案。不是黑客。它简单而完美。【参考方案4】:

**

<TextView
    android:id="@+id/tv_size"
    android:layout_
    android:layout_
    android:text="TextView"
    android:textSize="15sp"
    android: />

<TextView
    android:id="@+id/tv_price"
    android:layout_
    android:layout_
    android:text="TextView"
    android:textSize="15sp"
    android: />

<RadioButton
    android:id="@+id/radioButton"
    android:layout_
    android:layout_ />

**

【讨论】:

@春晖:- 我已经通读了那篇文章,但找不到想要的答案。 @Shailendra Rajawat :- 听不懂你想说的话。 android:layout_width 在您需要特定宽度时不应为 wrap_content 。如果这个替换也不能工作分享代码和问题 @ Shailendra Rajawat :- 这不是问题,我想要的是列表视图是单选并正常工作。 默认为单选。也许您没有使用高效的适配器(一个带有处理程序类的适配器),所以看到了意外的单选按钮。搜索高效适配器并使用它。

以上是关于自定义单选 ListView的主要内容,如果未能解决你的问题,请参考以下文章

Android 自定义单选列表

ArrayIndexOutOfBoundsException 与 ListView 中的多个视图的自定义 Android 适配器

ListView多选和单选模式重新整理

安卓 自定义AlertDialog对话框(加载提示框)

跨多个自定义组件使用单选按钮组功能

自定义SWT控件一之自定义单选下拉框