android:smoothScrollToPosition()工作不正常
在将一个元素添加到与listview关联的arrayadapter之后,我尝试平滑地滚动到列表的最后一个元素。 问题是它只是滚动到一个随机位置android:smoothScrollToPosition()工作不正常,android,listview,selection,android-arrayadapter,smooth-scrolling,Android,Listview,Selection,Android Arrayadapter,Smooth Scrolling,在将一个元素添加到与listview关联的arrayadapter之后,我尝试平滑地滚动到列表的最后一个元素。 问题是它只是滚动到一个随机位置 arrayadapter.add(item); //DOES NOT WORK CORRECTLY: listview.smoothScrollToPosition(arrayadapter.getCount()-1); //WORKS JUST FINE: listview.setSelection(arrayadapter.getCount()-1
arrayadapter.add(item);
//DOES NOT WORK CORRECTLY:
listview.smoothScrollToPosition(arrayadapter.getCount()-1);
//WORKS JUST FINE:
listview.setSelection(arrayadapter.getCount()-1);
调用
arrayadapter.add()
后是否调用arrayadapter.notifyDataSetChanged()
?同样可以肯定的是,smoothScrollToPosition
和setSelection
是您在上面提到的ListView
中可用的方法,而不是arrayadapter
在任何情况下,看看这是否有帮助:
您应该使用setSelection()方法。您可能希望告诉ListView在UI线程能够处理滚动时发布滚动(这就是为什么您的滚动不正常的原因)。SmoothScroll需要做大量的工作,而不是仅仅转到忽略速度/时间等的位置(对于“动画”来说是必需的) 因此,您应该执行以下操作:
getListView().post(new Runnable() {
@Override
public void run() {
getListView().smoothScrollToPosition(pos);
}
});
(摘自我的答案:)
这是一个已知错误。请参阅
但是,我实现了这个解决方案,它处理可能发生的所有边缘情况:
首先调用smothScrollToPositionFromTop(position),然后在滚动完成后,调用setSelection(position)
。后一个调用通过直接跳到所需位置来纠正不完整的滚动。这样做时,用户仍然有被动画滚动到此位置的印象
我在两个助手方法中实现了此解决方案:
smoothScrollToPosition()
getChildAtPosition()
公共静态视图getChildAtPosition(最终适配器视图,最终整型位置){
final int index=position-view.getFirstVisiblePosition();
如果((索引>=0)和&(索引
拉尔斯提到的集合选择方法是可行的,但是动画对于我们来说太过跳跃,因为它跳过了剩下的任何东西。另一个解决方案是反复调用该方法,直到第一个可见位置是索引。这是最好的快速完成,并有一个限制,因为它将战斗的用户滚动视图否则
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);
}
}
private void determinated scrollto(Android.Widget.ListView ListView,int索引,int尝试次数=0){
if(listView.FirstVisiblePosition!=索引和尝试次数<10){
尝试++;
listView.SmoothScrollToPositionFromTop(索引,1100);
listView.PostDelayed(()=>{
确定滚动到(列表视图、索引、尝试);
}, 100);
}
}
解决方案是C#via。Xamarin,但是应该很容易翻译成Java 使用LayoutManager平滑滚动
final Handler handler = new Handler();
//100ms wait to scroll to item after applying changes
handler.postDelayed(new Runnable() {
@Override
public void run() {
listView.smoothScrollToPosition(selectedPosition);
}}, 100);
layoutManager.smoothScrollToPosition(recyclerView, new RecyclerView.State(), position);
在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);
}
}
private void determinated scrollto(整数索引,整数尝试){
if(listView.getFirstVisiblePosition()!=索引和尝试次数<10){
尝试++;
if(listView.CanScrollVertical(pos))
smoothScrollToPositionFromTop(索引,1200);
int finalattests=尝试次数;
新处理程序(Looper.getMainLooper()).postDelayed(newrunnable()){
@凌驾
公开募捐{
确定滚动到(索引、最终尝试);
}
}, 200);
}
}
yea。。我在论坛上犯了一个错误,当然是listview.smoothScrollToPosition(pos)和listview.setSelection(pos)。调用arrayadapter.add()时会自动调用notifyDataSetChanged,否则setSelection将无法工作。setSelection(pos)工作得很好,这很奇怪,但smoothScrollToPosition(pos)却不能,不是吗?而且这个方法对我从来都不起作用。已知错误:请参阅答案它不一定相同,您可能不希望选择该项,或者您可以只是寻找它实际上帮助我解决的平滑效果,而不是什么都没有发生,它仍然会滚动到列表的最后。setSelection
确实可以在smoothScrollToPosition
不起作用的地方工作,但是如果你能告诉我们为什么会这样,那将是很有帮助的。@GiulioPiancastelli smoothScrollToPosition不起作用,因为它应该向所需的位置滚动少量。这意味着它对长列表甚至远超过100dp左右的项目都不起作用。文档中对此并不清楚,但它实际上就是这样工作的。如果您感兴趣,可以通过查看实际的实现代码来了解更多信息。+1了解post
。但是,我偶然发现smoothScrollToPosition
仍然不起作用,在小部件顶部和要滚动的项目之间留有一个小的偏移空间。在这种情况下,setSelection
(当然与post
结合使用)可以完美地工作。是的,我也是。ListView远不如UITableView等。这很悲哀,因为列表是移动设备的核心概念,屏幕大小受到影响,所以我们不得不滚动内容。在任何情况下,正如你所知,滚动是有效的,你只需要理解规则,布局必须已经布置好,你必须在UI线程中进行,你必须发布它,以便列表可以对操作进行排队,等等。滚动必须发生很多魔法。我相信@RomanianGuy可以为这件事提供更多的信息。尽管如此,iSO实施在很大程度上仍然完美无缺。这个家伙的名字是@Rominguy BTW。啊@GiulioPiancastelli,谢谢:)一个拼写错误,但现在无法编辑。这里有一个更完整的解决方法:
layoutManager.smoothScrollToPosition(recyclerView, new RecyclerView.State(), position);
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);
}
}