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>
运行后的展示效果图: