本文主要实现了两个listview联动的效果,类似于美团点菜和城市选择效果,区别于网上很多的不同是右边的listview滑动时左边的listview也会跟着一起滑动。在布局的左侧使用了平常的listview,在右侧用到了stickyheaderlistview,这是实现该效果的一个关键组件。
activyt布局
模拟两边的数据,需要注意的是左边listview数据中的id要和右边listview数据中的id产生一对多的关系,否则无法实现联动效果
/**
* 模拟右边adapter的数据
*
* @return
*/
private List initDishData() {
List dishBeanList = new ArrayList();
for (int i = 0; i < 100; i++) {
DishBean dishBean = new DishBean();
long id = i / 10;
dishBean.id = id;
dishBean.content = "content" + i;
dishBeanList.add(dishBean);
}
return dishBeanList;
}
/**
* 模拟左边adapter数据
*
* @return
*/
private List initCateData() {
List categoryBeanList = new ArrayList();
for (int i = 0; i < 10; i++) {
CategoryBean categoryBean = new CategoryBean();
if (i == 0) {
categoryBean.isSelected = true;
} else {
categoryBean.isSelected = false;
}
categoryBean.id = i;
categoryBean.name = "cate" + i;
categoryBeanList.add(categoryBean);
}
return categoryBeanList;
}
设置左边listview的点击事件让右边的listview滚动到相应的位置,这算是完成了一半的任务。(根据CategoryBean 中的id值查找右边lsitview相对应的item,然后记录下位置进行setSelection操作)
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
// 点击类别item,右侧菜品跳转到相应的位置
CategoryBean categoryBean = cateList.get(position);
for (int i = 0; i < dishList.size(); i++) {
DishBean dishBean = dishList.get(i);
if (categoryBean.id == dishBean.id) {
lv_right.setSelection(i);
break;
}
}
}
下面是右侧对左侧的联动效果实现。首先在activity中实现StickyListHeadersListView.OnStickyHeaderChangedListener接口(该接口来源于StickyListHeadersListView类),相对应的会实现onStickyHeaderChanged方法。
该方法会在header改变时调用(header的改变意味着一组新的类别数据出现在屏幕上),这时相对应的也需要改变左侧listview的选中状态
@Override public void onStickyHeaderChanged(StickyListHeadersListView l, View header, int itemPosition, long headerId) { DishBean dishBean = dishList.get(itemPosition); long id = dishBean.id; int position = getCateId(id); if (position != -1) { lv_left.setSelection(position);
//更新左侧listview选中状态
notifyLeftAdapter(position);
}
}
/**
* 获取dishbean id对应的类别所在position
*
* @param id
* dishbean id
* @return
*/
private int getCateId(long id) {
int position = 0;
for (int i = 0; i < cateList.size(); i++) {
position = i;
if (id == cateList.get(i).id) {
return position;
}
}
return -1;
}
到这里效果差不多就实现了,但是细心的同志可能会发现在lsitview滑动到最后一个item的时候有一大片空白,该空白是一个footerview,之所以这样做是因为在最后一组数据
较少的情况下可能会出现header不能置顶得到情况,这时相对应的onStickyHeaderChanged方法不能得到调用,结果就是右侧的listview即便是滑动到底左侧的listview也不能
跳转到相对应的item。当然了这个footerview的高度需要进行动态的计算,这个地方比较偷懒只是粗略的计算了一下。有兴趣的同学可以在代码中细看。
(当然了,这不是最理想的解决方法,如果你有更好的解决方案欢迎提出)
源码下载