【问题标题】:Android ListView - scrolls back to top on updateAndroid ListView - 更新时滚动回顶部
【发布时间】:2012-08-06 08:23:53
【问题描述】:

我有一个列表视图,可以根据请求添加其他视图,由 BaseAdapter 维护。更新后如何保持滚动位置?

我知道这已经被问过几次了,但是每次都提出了相同的解决方案,我尝试过,就是在更新包含列表内容的ArrayList之后调用adapter.notifyDataSetChanged();

如何确保保持滚动位置?

【问题讨论】:

    标签: android android-listview android-ui android-adapter


    【解决方案1】:

    在您的活动类中实现OnScrollListener,然后使用以下代码:

    int currentFirstVisibleItem, currentVisibleItemCount, currentTotalItemCount;
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        this.currentFirstVisibleItem = firstVisibleItem;
        this.currentVisibleItemCount = visibleItemCount;
        this.currentTotalItemCount = totalItemCount;
    }
    
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.currentScrollState = scrollState;
        this.isScrollCompleted();
    }
    
    private void isScrollCompleted() {
    
        if (currentFirstVisibleItem + currentVisibleItemCount >= currentTotalItemCount) {
            if (this.currentVisibleItemCount > 0
                    && this.currentScrollState == SCROLL_STATE_IDLE) {
    
                //Do your work
            }
        }
    }
    

    如果您使用AsyncTask 更新数据,则可以在PostExecute() 中包含以下内容以保持滚动位置:

    list.setAdapter(adapter);
    list.setSelectionFromTop(currentFirstVisibleItem, 0);
    

    我希望这会有所帮助。

    【讨论】:

    • 你的意思是//做你的工作。还有什么可做的?
    • 在 //Do your work 中,您可以编写代码,就像您想在滚动完成时执行的任何操作一样。例如,像 Facebook 一样,如果您想在 Scroll down 上加载更多数据,您可以编写这里的代码..
    • 这适用于添加页脚...我要在列表视图中添加页眉以进行刷新。所以请给我一个条件将标题添加到列表视图
    • 非常感谢......这是我遇到的年龄错误之一
    【解决方案2】:

    我采取的方法是在更新后调用ListView.setSelection(position) 滚动到所需的position

    根据您从哪里调用它,您可能需要先调用requestFocusFromTouch,然后再调用setSelection,以确保该项目得到适当的定位。

    【讨论】:

    • 对 requestFocusFromTouch 的调用对我来说是关键的缺失步骤!
    • YESSSSSSSSSSS,如果可以的话,我会拥抱你。这么久才解决这个问题
    【解决方案3】:

    此代码将帮助您....

    // get position of listview
    int index = listView.getFirstVisiblePosition();
    View v = listView.getChildAt(0);
    int top = (v == null) ? 0 : v.getTop();
    
    // notify dataset changed or re-assign adapter here
    
    //re-assign the position of listview after setting the adapter again
    listView.setSelectionFromTop(index, top);
    

    干杯:)

    【讨论】:

    • 完美无瑕,就好像适配器从未改变过,除了更新相关视图,在我的例子中,它会在列表布局中切换点击的图像!非常感谢!!
    【解决方案4】:

    你可以试试这个:

    //Get the top position from the first visible element
    int fVisible = list.getFirstVisiblePosition();
    View vFirst = list.getChildAt(0);
    int pos = 0;
    if (vFirst != null) pos = vFirst.getTop();
    
    //Restore the position
    list.setSelectionFromTop(fVisible, pos);
    

    【讨论】:

    • 不幸的是,令人惊讶的是这不起作用。放入日志后,滚动到所需位置后,它只是重置位置并返回顶部。
    【解决方案5】:

    您可以执行以下操作。如果你想通过滚动到底部加载更多数据,它会有一些变化。

    int currentFirstVisibleItem, currentScrollState;
    int countChange = 0;
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        Log.d("Scroll", "Scrolling");
        this.currentFirstVisibleItem = firstVisibleItem;
        countChange = 0;//during touching you can decide not to refresh by scroll
    }
    
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        Log.d("Scroll", "Changed");
        this.currentScrollState = scrollState;
        if (scrollState == SCROLL_STATE_TOUCH_SCROLL) {
            countChange = 0;
        }
        if (++countChange > 1) {
            //scroll to top and release touch change=2. Simple scroll and release touch change=1
            this.isScrollCompleted();
            countChange = 0;
        }
    }
    
    private void isScrollCompleted() {
        Log.d("Load", "Reload");
        if (currentFirstVisibleItem == 0) {
            //Your loading go here
        }
    }
    

    【讨论】:

    • 是的,这是代码而不是图片的形式。我只是试图写成代码。不像 IDE 中的代码一般写法。
    猜你喜欢
    • 2018-02-24
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    相关资源
    最近更新 更多