<div class="it610-blog-content-contain" style="font-size: 14px">
关于两个ListView同时滚动的问题,一般人的思维都是在其中一个ListView的onScroll事件中的时候给另个ListView.ScrollTo(x,y)来实现,可是实际上在取另一个ListView的View的getScrollX()或者getScrollY()时,无论怎么取都是0。网站上有通过获得第一个可见的的View的矩形来达到同时滚动的目的,但实际上这种滚动并不是实时同步的,只有在可见的ListViewItem变更了的情况下才会使另一个ListView也同步,而且这个方法仅限于ScorllView和ListView或者其派生类(可能还有些别的,这个我就不清楚了),而我的需求是两个GridView要达到同步。
简单的说下我的需求,一个电影院选票系统,左侧是行号,右侧是座位,座位可以上下和左右拖动,由于左右拖动的需求,所以独立出行号,为此必须在竖向滚动时保证座位和行号是对应的,且同步。以下是关于这两个gridView同步的一种方法(如果还有其他方法,可以互相交流)。
mGridView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(final AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
View v = view.getChildAt(view.getFirstVisiblePosition()/20);
int[] location = new int[2];
if(null!=v){
v.getLocationOnScreen(location);
mRowGridView.scrollTo(0,view.getFirstVisiblePosition()*40/20-location[1]+1116);
}
}
});
其中,mGridView为座位GridView,mRowGridView为行号GridView。
View v = View.getChildAt(view.getFirstVisiblePosition()/20);
通过可见的第一个GridViewItem的Position除以它的列数(列数为20),来获得AbsListView的Child下标,从而获得该行的View。
v.getLocationOnScreen(location);是获得第一行的View在屏幕中的的绝对坐标。这个坐标是用于在滚动而滚动的量还没有达到整整一行时的同步,因为它的值大于0 小于一个Item的高度。
mRowGridView.scrollTo(0,view.getFirstVisiblePosition()*40/20-location[1]+1116);
这就是关键的滚动代码了,Y轴,view.getFirstVisiblePosition()*40/20 是为行数滚动了几行,是一个整数,每次mGridView行数Item的高度的整数倍时,mRowGridView的行数也滚动一个Item的高度(其中40是我一个Item的高度dp,20是列数)。 而之后的location[1]+1116是可见的第一行的Item的相对坐标。其中[1]指的是Y轴,+1116呢,是在实机上测出来当没有任何移动时的绝对坐标
通过整行的和微调的相互合并,达到同步的要求~
</div>