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



大体思路

本文主要实现了两个listview联动的效果,类似于美团点菜和城市选择效果,区别于网上很多的不同是右边的listview滑动时左边的listview也会跟着一起滑动。在布局的左侧使用了平常的listview,在右侧用到了stickyheaderlistview,这是实现该效果的一个关键组件。

activyt布局

<span style="font-size:14px;"><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <ListView
            android:id="@+id/lv_left"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:cacheColorHint="#00000000" >
        </ListView>

        <se.emilsjolander.stickylistheaders.StickyListHeadersListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cacheColorHint="#00000000"
            android:clipToPadding="false"
            android:footerDividersEnabled="false"
            android:drawSelectorOnTop="true"
            android:fastScrollEnabled="true"
            android:padding="16dp"
            android:scrollbarStyle="outsideOverlay" />
    </LinearLayout>

    <TextView
        android:id="@+id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="@string/empty"
        android:textSize="30sp"
        android:visibility="gone" />

</FrameLayout></span>

模拟数据

模拟两边的数据,需要注意的是左边listview数据中的id要和右边listview数据中的id产生一对多的关系,否则无法实现联动效果

/**
	 * 模拟右边adapter的数据
	 * 
	 * @return
	 */
	private List<DishBean> initDishData() {
		List<DishBean> dishBeanList = new ArrayList<DishBean>();
		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<CategoryBean> initCateData() {
		List<CategoryBean> categoryBeanList = new ArrayList<CategoryBean>();
		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的选中状态

</pre><pre name="code" class="java">@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);
<span style="white-space:pre">			</span>//更新左侧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的高度需要进行动态的计算,这个地方比较偷懒只是粗略的计算了一下。有兴趣的同学可以在代码中细看。

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


源码下载


猜你喜欢

转载自blog.csdn.net/u013894711/article/details/50948065