在将一个元素添加到与listview关联的arrayadapter之后,我正在尝试平滑地滚动到列表的最后一个元素。 问题是它只是滚动到一个随机位置
arrayadapter.add(item);
//DOES NOT WORK CORRECTLY:
listview.smoothScrollToPosition(arrayadapter.getCount()-1);
//WORKS JUST FINE:
listview.setSelection(arrayadapter.getCount()-1);
答案 0 :(得分:55)
您可能希望告诉ListView在UI线程可以处理它时发布滚动(这就是为什么它不能正确滚动)。 SmoothScroll需要做很多工作,而不是只是去一个忽略速度/时间/等的位置。 (“动画”所需)。
因此,您应该执行以下操作:
getListView().post(new Runnable() {
@Override
public void run() {
getListView().smoothScrollToPosition(pos);
}
});
答案 1 :(得分:12)
(从我的回答中复制:smoothScrollToPositionFromTop() is not always working like it should)
这是一个已知错误。请参阅https://code.google.com/p/android/issues/detail?id=36062
但是,我实施了此解决方法,处理可能发生的所有边缘情况:
首先调用smothScrollToPositionFromTop(position)
,然后在滚动完成后,调用setSelection(position)
。后一个调用通过直接跳到所需位置来纠正不完整的滚动。这样做,用户仍然会感觉它正在动画滚动到此位置。
我在两个辅助方法中实现了这个解决方法:
<强> smoothScrollToPosition()强>
public static void smoothScrollToPosition(final AbsListView view, final int position) {
View child = getChildAtPosition(view, position);
// There's no need to scroll if child is already at top or view is already scrolled to its end
if ((child != null) && ((child.getTop() == 0) || ((child.getTop() > 0) && !view.canScrollVertically(1)))) {
return;
}
view.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
view.setOnScrollListener(null);
// Fix for scrolling bug
new Handler().post(new Runnable() {
@Override
public void run() {
view.setSelection(position);
}
});
}
}
@Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
final int totalItemCount) { }
});
// Perform scrolling to position
new Handler().post(new Runnable() {
@Override
public void run() {
view.smoothScrollToPositionFromTop(position, 0);
}
});
}
<强> getChildAtPosition()强>
public static View getChildAtPosition(final AdapterView view, final int position) {
final int index = position - view.getFirstVisiblePosition();
if ((index >= 0) && (index < view.getChildCount())) {
return view.getChildAt(index);
} else {
return null;
}
}
答案 2 :(得分:6)
您应该使用setSelection()方法。
答案 3 :(得分:3)
Lars提到的集合选择方法有效,但动画对于我们的目的来说太过于跳跃,因为它会跳过剩下的东西。另一种解决方案是重复调用该方法,直到第一个可见位置为您的索引。这是最好的快速和限制,因为它将打击用户滚动视图否则。
private void DeterminedScrollTo(Android.Widget.ListView listView, int index, int attempts = 0) {
if (listView.FirstVisiblePosition != index && attempts < 10) {
attempts++;
listView.SmoothScrollToPositionFromTop (index, 1, 100);
listView.PostDelayed (() => {
DeterminedScrollTo (listView, index, attempts);
}, 100);
}
}
解决方案是在C#中。 Xamarin但应该很容易转换为Java。
答案 4 :(得分:2)
np.array(g).astype(np.float64)
答案 5 :(得分:2)
使用LayoutManager平滑滚动
layoutManager.smoothScrollToPosition(recyclerView, new RecyclerView.State(), position);
答案 6 :(得分:1)
致电arrayadapter.notifyDataSetChanged()
后,您是否致电arrayadapter.add()
?另外可以肯定的是,smoothScrollToPosition
和setSelection
是ListView
而非arrayadapter
中可用的方法,如上所述。
无论如何,看看这是否有帮助: smoothScrollToPosition after notifyDataSetChanged not working in android
答案 7 :(得分:0)
在android java中使用它,它对我有用:
private void DeterminedScrollTo(int index, int attempts) {
if (listView.getFirstVisiblePosition() != index && attempts < 10) {
attempts++;
if (listView.canScrollVertically(pos))
listView.smoothScrollToPositionFromTop(index, 1, 200);
int finalAttempts = attempts;
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
DeterminedScrollTo(index, finalAttempts);
}
}, 200);
}
}