您的位置:首页 > 移动开发 > Android开发

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

2016-03-21 17:48 639 查看





大体思路

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

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

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android listview 联动