最近一直在看项目,进行一些UI上更改,改了几个前辈遗留的bug,看到一个页面的左右两个ListView只有单方面的联动,即左边的ListVive点击可以让右边的ListView定位到相应的位置,而右边的ListView滑动并不能改变左边的ListView,虽然产品大哥没有提这个bug,但是我有强迫症啊,我也很绝望啊,就动手改呗。
希望达到的效果呢就是普遍在外卖软件上可以看到的,左边是商品类型,右边是商品类型和具体商品的多布局,点击左边ListView,右边可以定位到对应的商品类型;右边ListView滑动时,当商品类型改变时,左边的ListView也定位到对应的商品类型。思路应该是简单的,左对右实现起来很简单, 对左边的ListView设置item点击监听,setOnItemClickListener(),找到点击的item的商品类型在右边ListView中的position,然后右边ListView调用setSelection(position)方法即可;右边对左边的联动就要对右边ListView进行滑动监听,setOnScrollListener(),重写onScroll()方法,处理方法与上面的类似,但是我遇到了一个问题,判断条件为第一个可见item是否为商品类型并找出左边对应的位置,我是这样写的
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
String title = rightListAdapter.getItem(firstVisibleItem).toString();
int section = leftListAdapter.indexOf(title);
if (section == -1) return;
leftListView.setItemChecked(section, true);
leftListView.smoothScrollToPosition(section);
}
但是呢出现了一个问题,当右边的第一个条目为商品类型时,左边的ListView不能滑动,或者说是滑动了,但是又被定位到右边商品类型所对应的左边的位置,打断点发现,即使触摸区域在左边的ListView范围,还是会走右边ListView的onScroll()方法。语言表达可能不准确,有兴趣可以自己试一下。我的解决方法呢就是设置一个标志位,当右边的ListView的滚动状态为停止的时候就不去执行onScroll()里的代码。所以代码就变成了这样。
rightListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
shouldSet = false;
} else {
shouldSet = true;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (shouldSet){
String title = rightListAdapter.getItem(firstVisibleItem).toString();
int section = leftListAdapter.indexOf(title);
if (section == -1) return;
leftListView.setItemChecked(section, true);
leftListView.smoothScrollToPosition(section);
}
}
});
好了 就是这样!
下面是MainActivity的代码,demo戳这里。
package com.ccc.listviewlinkage;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView leftListView;
private ListView rightListView;
private LeftListAdapter leftListAdapter;
private RightListAdapter rightListAdapter;
private List<String> leftList;
private List<GoodsBean> rightList;
private boolean isScroll;
private boolean shouldSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initViews();
}
private void initData() {
leftList = new ArrayList<>();
rightList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
leftList.add("商品类型 " + i);
}
for (int i = 0; i < 10; i++) {
rightList.add(new GoodsBean("商品类型 " + i, 0));
for (int i1 = 0; i1 < 10; i1++) {
rightList.add(new GoodsBean("商品名称 " + i1, 1));
}
}
}
private void initViews() {
leftListView = (ListView) findViewById(R.id.left_list_view);
rightListView = (ListView) findViewById(R.id.right_list_view);
leftListAdapter = new LeftListAdapter(this, leftList);
leftListView.setAdapter(leftListAdapter);
rightListAdapter = new RightListAdapter(this, rightList);
rightListView.setAdapter(rightListAdapter);
leftListView.setItemChecked(0, true);
leftListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
isScroll = false;
leftListView.setItemChecked(position, true);
int section = rightListAdapter.indexOf(leftListAdapter.getItem(position).toString());
if (section == -1) return;
rightListView.setSelection(section);
}
});
rightListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
shouldSet = false;
} else {
shouldSet = true;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (isScroll){
if (shouldSet){
String title = rightListAdapter.getItem(firstVisibleItem).toString();
int section = leftListAdapter.indexOf(title);
if (section == -1) return;
leftListView.setItemChecked(section, true);
leftListView.smoothScrollToPosition(section);
}
} else {
isScroll = true;
}
}
});
}
}