联动Listview(实现真正的联动效果)



大体思路

本文主要实现了两个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的高度需要进行动态的计算,这个地方比较偷懒只是粗略的计算了一下。有兴趣的同学可以在代码中细看。

(当然了,这不是最理想的解决方法,如果你有更好的解决方案欢迎提出)


源码下载


你可能感兴趣的:(联动Listview(实现真正的联动效果))