我想按照像素数滚动Android中的ListView
。例如,我想将列表向下滚动10个像素(以便列表中的第一个项目隐藏其前10个像素行)。
我认为ListView上明显可见的scrollBy
或scrollTo
方法可以完成这项工作,但他们没有,而是错误地滚动整个列表(事实上,getScrollY
即使我用手指滚动列表,也总是返回零。)
我正在做的是我正在捕捉轨迹球事件,我想根据轨迹球的运动平滑地滚动列表视图。
答案 0 :(得分:11)
滚动ListView
窗口小部件的支持方式是:
mListView.smoothScrollToPosition(position);
http://developer.android.com/reference/android/widget/AbsListView.html#smoothScrollToPosition(int)
但是,由于您特别提到要垂直偏移视图,因此必须调用:
mListView.setSelectionFromTop(position, yOffset);
http://developer.android.com/reference/android/widget/ListView.html#setSelectionFromTop(int,%20int)
请注意,您也可以使用smoothScrollByOffset(yOffset)
。但是,它仅在API> = 11
http://developer.android.com/reference/android/widget/ListView.html#smoothScrollByOffset(int)
答案 1 :(得分:10)
如果查看api 19中添加的scrollListBy()方法的源代码,您将看到可以使用包范围trackMotionScroll
方法。
public class FutureListView {
private final ListView mView;
public FutureListView(ListView view) {
mView = view;
}
/**
* Scrolls the list items within the view by a specified number of pixels.
*
* @param y the amount of pixels to scroll by vertically
*/
public void scrollListBy(int y) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mView.scrollListBy(y);
} else {
// scrollListBy just calls trackMotionScroll
trackMotionScroll(-y, -y);
}
}
private void trackMotionScroll(int deltaY, int incrementalDeltaY) {
try {
Method method = AbsListView.class.getDeclaredMethod("trackMotionScroll", int.class, int.class);
method.setAccessible(true);
method.invoke(mView, deltaY, incrementalDeltaY);
} catch (Exception ex) {
throw new RuntimeException(ex);
};
}
}
答案 2 :(得分:3)
以下是我的ListView
子类中的一些代码。它可以很容易地进行调整,因此可以在活动代码中使用。
getListItemsHeight()
返回列表的总像素高度,并使用每个项目的垂直像素偏移填充数组。虽然此信息有效,但getListScrollY()
会返回当前垂直像素滚动位置,而scrollListToY()
会将列表滚动到像素位置。
如果列表的大小或内容发生变化,则必须再次调用getListItemsHeight()
。
private int m_nItemCount;
private int[] m_nItemOffY;
private int getListItemsHeight()
{
ListAdapter adapter = getAdapter();
m_nItemCount = adapter.getCount();
int height = 0;
int i;
m_nItemOffY = new int[m_nItemCount];
for(i = 0; i< m_nItemCount; ++i){
View view = adapter.getView(i, null, this);
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
m_nItemOffY[i] = height;
height += view.getMeasuredHeight();
}
return height;
}
private int getListScrollY()
{
int pos, nScrollY, nItemY;
View view;
pos = getFirstVisiblePosition();
view = getChildAt(0);
nItemY = view.getTop();
nScrollY = m_nItemOffY[pos] - nItemY;
return nScrollY;
}
private void scrollListToY(int nScrollY)
{
int i, off;
for(i = 0; i < m_nItemCount; ++i){
off = m_nItemOffY[i] - nScrollY;
if(off >= 0){
setSelectionFromTop(i, off);
break;
}
}
}
答案 3 :(得分:1)
目前,ListViewCompat可能是更好的解决方案。
android.support.v4.widget.ListViewCompat.scrollListBy(@NonNull ListView listView, int y)
答案 4 :(得分:0)
如果你想按像素移动,那么你可以使用这个
public void scrollBy(ListView l, int px){
l.setSelectionFromTop(l.getFirstVisiblePosition(),l.getChildAt(0).getTop() - px);
}
这适用于具有大量标题的偶数