android 单选题 listview嵌套 listview。

我有个做选择题的需求,界面样式如下图
clipboard.png

我通过listview嵌套listview来实现,子listview的item是一个实现

我的父listview的item如下,设置了listview的android:choiceMode="singleChoice"

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

    <TextView
        android:id="@+id/tv_parent_name"
        style="@style/tv_little_gray"
        android:layout_marginStart="@dimen/x40"
        android:textSize="14sp"
        android:textStyle="bold" />

    <ListView
        android:id="@+id/lv_inner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="@color/transparent"
        android:choiceMode="singleChoice"
        android:divider="@color/transparent"
        android:listSelector="@color/transparent"
        android:scrollbars="none"/>
</LinearLayout>

子listview的item如下,其中CheckableLinearLayout是实现重写Linearlayout实现Checkable接口的自定义View
xml:

<?xml version="1.0" encoding="utf-8"?>
<com.xxx.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llyt_child"
    style="@style/spinnerListItemLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:gravity="center_vertical">

    <CheckBox
        android:id="@+id/cb_child"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:button="@drawable/checkbox_cycle_select"
        android:clickable="false"
        android:focusable="false" />

    <TextView
        android:id="@+id/tv_child_name"
        style="@style/tv_little_gray"
        android:singleLine="false"
        android:layout_weight="1"
        android:layout_marginEnd="@dimen/x60"
        android:layout_marginStart="@dimen/x20"
        android:textSize="14sp" />

    <TextView
        android:id="@+id/tv_child_score"
        style="@style/tv_little_gray"
        android:layout_marginEnd="@dimen/x60"
        android:textSize="14sp" />
</com.xxx.CheckableLinearLayout>

CheckableLinearLayout:

public class CheckableLinearLayout extends LinearLayout implements Checkable{
    public boolean mChecked = false;
    public CheckableLinearLayout(Context context, AttributeSet attrs,
                                int defStyle) {
        super(context, attrs, defStyle);
    }

    public CheckableLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CheckableLinearLayout(Context context) {
        super(context);
    }

    @Override
    public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
            for (int i = 0, len = getChildCount(); i < len; i++) {
                View child = getChildAt(i);
                if(child instanceof Checkable){
                    ((Checkable) child).setChecked(checked);
                }
            }
        }
    }

    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }
}

父Adapter:

  @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.assess_parent_list_item, parent, false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvParentName.setText(key.get(position));
        //innerlistview 的adapter
        List<RatingList> ratingLists = map.get(key.get(position));
        AssessChildAdapter adapter = new AssessChildAdapter(ratingLists, mContext);
        holder.lvInner.setAdapter(adapter);
        int pos=holder.lvInner.getCheckedItemPosition();
        MLog.e(pos);
        if(pos==-1){
            holder.lvInner.setItemChecked(0, true);
        }else{
            holder.lvInner.setItemChecked(holder.lvInner.getCheckedItemPosition(),true);
        }

        int selectedPos=holder.lvInner.getCheckedItemPosition();
        setSelected(selectedPos,ratingLists.get(selectedPos));

        //根据innerlistview的高度机损parentlistview item的高度
        setListViewHeightBasedOnChildren(holder.lvInner);

        return convertView;
    }
    

子Adapter:

 @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.assess_child_list_item, parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.tvChildName.setText(ratingLists.get(position).getDescription());
        viewHolder.tvChildScore.setText(ratingLists.get(position).getScore() + "");

        return convertView;
    }
        

希望有人帮忙看下,万分感谢

阅读 4k
4 个回答

根据你的布局来看, 我建议你用ExpandListView来做. 比较方便吧!

很多人可能并不懂得ListView是为了解决什么问题,并不是有列表就要用 ListView。

ListView的目标是长列表,即列表的item数量众多,阵列起来有可能是五屏、十屏、二十屏。ListView的基本原理就是只加载当前可视的item,这样就保证了性能(试想想一次性加载上千个item)。

对于你这样的需求,只需要一个ListView,里面的每一个item的 选项部分 用 LinearLayout 然后和 ListView 一样动态加载数据就可以了,因为选项不太可能有成百上千条。

ExpandListView就是listview嵌套listview的啊,而且已经封装好父和子Listview

@大尾巴狼 说的那个方法比较适合有折叠场景的应用, 看题主截图, 应该直接用ListView就可以实现: 重写BaseAdapter中的两个接口:

  • [1] int getViewTypeCount()

  • [2] int getItemViewType(int position)

[1] 告诉ListView有多少个视图类型, 以便ListView重用子视图, [2]告诉ListView当前position位置使用哪个子视图.

可以直接查百度查谷歌获得更多实例.

p.s. 当然也可以不用上述接口来实现, 直接控制视图的显示隐藏更方便

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题