Android 给双ListView组织数据源

需求:现有这样一套原始数据{“A”,"B","C","D","B","A","B","C","A","B","D","D"}.

要求将此数据组织成为双列表形式显示,即将元素相同的数据分为一组,即{["A","A","A"],["B","B","B","B"],["C","C"],["D","D","D"]}并将分组后的数据显示在ListView界面上。(外部ListView显示每一组,内部ListView显示每一组中的组成员)

以下是需求效果展示图:

第一步:组织数据源(这一步也是我认为的最重要的一部,剩下的都是数据显示的问题,相信大家都会的,呵呵)

  1.过滤数据(筛选出不重复数据)

  2.将重复数据分别放入不同的集合中(小集合)

  3.将重复数据集合放到大集合中(用于存放小集合)

  4.代码展示:

  

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 组织双列表的数据源
 * @author yw-tony
 *
 */
public class TwoListViewDataTools {
    private TwoListViewDataTools(){}
    private static TwoListViewDataTools instance;
    public static TwoListViewDataTools getInstance(){
        synchronized (TwoListViewDataTools.class) {
            if(instance == null){
                instance = new TwoListViewDataTools();
            }
        }
        return instance;
    }
    /**
     * 根据分组标记找出每一种元素在集合中的个数,并组织成为一个个的集合,然后存入共同的大集合中
     * @param data原始数据
     * @return
     */
    public List<List<String>> listToGroup(List<String> data){
        //最终集合的展现形式
        List<List<String>> largeGroup = new ArrayList<List<String>>();
        //筛选后的集合,此集合中存放的是原始集合中的不重复元素
        List<String> diff = getListDifferentElement(data);
        for(int i=0;i<diff.size();i++){//筛选后的集合
            List<String> littleGroup = new ArrayList<String>();
            for(int j= 0;j<data.size();j++){//原始集合
                //如果遇到相同元素就存入元素集合中
                if(diff.get(i).equals(data.get(j))){
                    littleGroup.add(data.get(j));
                }
            }
            largeGroup.add(littleGroup);
        }
        return largeGroup;
    }
    /**
     * 获取一个集合中不同元素的集合
     * @param data 演示数据
     */
    private List<String> getListDifferentElement(List<String> data){
        //使用set集合可以过滤掉集合中的重复元素
        Set<String> sets = new HashSet<String>();
        List<String> diff = new ArrayList<String>();
        for(int i=0;i<data.size();i++){
            sets.add(data.get(i));
        }
        for(String s : sets){
            diff.add(s);
        }
        return diff;
    }
}

第二部:给列表填充数据(仅作代码展示,主要功能都加上了注释)

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.yw.myapiupdate.R;

/**
 * 显示数据的主Activity类
 * @author yw-tony
 *
 */
public class ListViewTwoActivity extends Activity{
    //分组后的集合
    private List<List<String>> group = new ArrayList<List<String>>();
    //原始数据集合
    private List<String> datas = new ArrayList<String>();
    private ListView lv_main;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lv_two_main);
        /*初始化数据源*/
        TwoListData.getInstance().addData(datas);
        //给集合列表赋值
        group = TwoListViewDataTools.getInstance().listToGroup(datas);
        /*填充数据源*/
        lv_main = (ListView)findViewById(R.id.lv_two_main_lv);
        MainBaseAdapter adapter = new MainBaseAdapter(this);
        adapter.setList(group);
        lv_main.setAdapter(adapter);
        //动态的计算列表的高度
        setListViewHeightBasedOnChildren(lv_main);
    }
    /**
     * 外层baseadapter
     * @author yw-tony
     *
     */
    class MainBaseAdapter extends BaseAdapter{
        private Context context;
        private LayoutInflater inflater;
        private List<List<String>> baseGroup = new ArrayList<List<String>>();
        public MainBaseAdapter(Context context){
            this.context = context;
            this.inflater = LayoutInflater.from(context);
        }
        public void setList(List<List<String>> baseGroup){
            this.baseGroup = baseGroup;
        }
        @Override
        public int getCount() {
            return baseGroup.size();
        }
    
        @Override
        public Object getItem(int arg0) {
            return baseGroup.get(arg0);
        }
    
        @Override
        public long getItemId(int arg0) {
            return arg0;
        }
    
        @Override
        public View getView(int arg0, View view, ViewGroup arg2) {
            if(view == null){
                view = inflater.inflate(R.layout.lv_two_main_item, null);
            }
            ListView lv_item = (ListView)view.findViewById(R.id.lv_two_main_item);
            List<String> items = baseGroup.get(arg0);
            //设置子listview的数据源,并显示出来
            ItemBaseAdapter itemAdapter = new ItemBaseAdapter(ListViewTwoActivity.this);
            itemAdapter.setList(items);
            lv_item.setAdapter(itemAdapter);
            //设置内层数据列表的高度
            setListViewHeightBasedOnChildren(lv_item);
            return view;
        }
    
    }
    /**
     * 子(内层)listview的数据源
     * @author yw-tony
     *
     */
    class ItemBaseAdapter extends BaseAdapter{
        private Context context;
        private LayoutInflater inflater;
        private List<String> items = new ArrayList<String>();
        public ItemBaseAdapter(Context context){
            this.context = context;
            this.inflater = LayoutInflater.from(context);
        }
        public void setList(List<String> items){
            this.items = items;
        }
        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public Object getItem(int position) {
            return items.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if(convertView == null){
                convertView = inflater.inflate(R.layout.lv_two_item_item, null);
            }
            TextView tv = (TextView)convertView.findViewById(R.id.lv_two_item_item_tv);
            tv.setText(items.get(position));
            return convertView;
        }
        
    }
    /**动态改变listView的高度*/
    public void setListViewHeightBasedOnChildren(ListView listView) {
          ListAdapter listAdapter = listView.getAdapter();
          if (listAdapter == null) {
           return;
          }
          int totalHeight = 0;
         for (int i = 0; i < listAdapter.getCount(); i++) {
           View listItem = listAdapter.getView(i, null, listView);
           listItem.measure(0, 0);
           totalHeight += listItem.getMeasuredHeight();
//           totalHeight += 80;
          }
          ViewGroup.LayoutParams params = listView.getLayoutParams();
//          params.height = 80 * (listAdapter.getCount() - 1);
//          params.height = 80 * (listAdapter.getCount());
          params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
          ((MarginLayoutParams) params).setMargins(0, 0, 0, 0);
          listView.setLayoutParams(params);
          
         }
}

下面提出数据源(元数据)

import java.util.List;
/**
 * 模拟从网络上获取到的数据源
 * @author yw-tony
 *
 */
public class TwoListData {
    private TwoListData(){}
    private static TwoListData instance;
    public static TwoListData getInstance(){
        synchronized (TwoListData.class) {
            if(instance == null){
                instance = new TwoListData();
            }
        }
        return instance;
    }
    /**
     * 添加模拟数据
     */
    public void addData(List<String> data){
        data.add("A");
        data.add("B");
        data.add("C");
        data.add("B");
        data.add("A");
        data.add("C");
        data.add("A");
        data.add("B");
        data.add("A");
    }
    
}

以下给出配置文件信息

1.主文件:

<?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:background="#ff0000"
    android:orientation="vertical" >
    <ListView 
        android:id="@+id/lv_two_main_lv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        ></ListView>

</LinearLayout>

2.主文件的item

<?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="fill_parent"
        android:layout_height="wrap_content"
        android:background="#00ffff"
        android:gravity="center"
        >
        <ListView 
            android:id="@+id/lv_two_main_item"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            ></ListView>
    </LinearLayout>

</LinearLayout>

3.item的item

<?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/lv_two_item_item_tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="测试"
        android:textSize="25sp"
        android:background="#33ffcc"/>

</LinearLayout>

 运行后的展示效果图:

原文地址:https://www.cnblogs.com/tony-yang-flutter/p/3347064.html