在水平LinearLayout(匹配屏幕宽度)中,我有两个ListView实例(带有动态列表项)和介于两者之间的TextView。使用TextView作为画布,我想绘制(Bezier)线,将左侧ListView中的选定列表项与右侧ListView中的所有列表项连接,反之亦然。现在,完全可能的是,所选列表项或另一侧的任何列表项都在ListView的可见区域之外。在这种情况下,我想绘制那些线(从上/下进入或从上/下离开)只有它们可见。为了绘制这些线,我需要在每一行的开头和结尾都有x和y值。 x只是textView.getLeft()和textView.getRight(),但y取决于两个列表的当前滚动位置。
我的问题是获取特定ListView项目的当前y值:
list.getChildAt(indexOfCurrentlySelectedItem).getY()
列表布局后,我需要访问这些值。我需要确定哪些列表项和哪些列表项不可见(不可见的列表项是否具有y值?视图?可循环查看(使用持有者模式)?)。我需要能够遍历列表,我命令将这些y值传递给TextView的onDraw方法。最后,我需要安装一种机制来在滚动之后重新绘制线条。
如何保持当前的y值(布局后和滚动后)?我是否必须跟踪OnScrollListener中的可见位置?我是否必须在OnGlobalLayoutListener中监听列表布局的结尾?我是否也必须在OnGlobalLayoutListener中为每个列表项侦听列表项布局的结尾?
答案 0 :(得分:0)
好的,我找到了一个很好的解决方案:OnScrollListener提供了我所需要的一切,而这里不需要OnGlobalLayoutListener。
public class ArrayListAdapter extends ArrayAdapter<String>
implements AbsListView.OnScrollListener
...
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public synchronized void onScroll(final AbsListView listView, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
List<Integer>yList = new ArrayList<>();
int checkedPosition = listView.getCheckedItemPosition();
double yChecked = 0;
for (int pos = 0; pos < totalItemCount; pos++) {
CheckedTextView tv = (CheckedTextView) this
.getViewByPosition(pos, listView, firstVisibleItem,
firstVisibleItem + visibleItemCount - 1);
if (pos == checkedPosition) {
yChecked = tv.getY();
}
yList.add(pos, tv.getY());
}
// Here I pass the fresh y-values to the fragment holding the
// two ListViews. After some further calculations the fragment
// passes the data to the TextView where it is stored and
// this.invalidate is called to eventually trigger the onDraw method.
originalFragment.setScrollData(yList, yChecked);
}
private View getViewByPosition(int pos, AbsListView listView, int firstVisibleItem,
int lastVisibleItem) {
if (pos < firstVisibleItem || pos > lastVisibleItem) {
// The next line is the only downside of this solution I have
// found so far. If the convertView of the getView(int
// position, View convertView, ViewGroup parent) method is null
// the holder pattern I applied in my adapter becomes useless.
// In my case the recreation of the CheckedTextViews is fast
// enough though.
return listView.getAdapter().getView(pos, null, listView);
} else {
return listView.getChildAt(pos - firstVisibleItem);
}
}