Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android:smoothScrollToPosition()工作不正常_Android_Listview_Selection_Android Arrayadapter_Smooth Scrolling - Fatal编程技术网

android:smoothScrollToPosition()工作不正常

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

在将一个元素添加到与listview关联的arrayadapter之后,我尝试平滑地滚动到列表的最后一个元素。 问题是它只是滚动到一个随机位置

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);
        }
    }