5

StickyHeaderListview在我的项目中使用来显示内容并刷新列表,我正在使用SwipeRefreshLayout. 这里的问题是,当我尝试向上滚动列表时,它开始刷新列表并且不允许查看列表的先前项目。

我希望这种行为应该是只有当我到达第一个项目并且我尝试向上滚动时才会刷新列表,而不是每次向上滚动列表时。

有人可以帮忙吗?

Ps 为了实现 SwipeRefreshLayout,我指的是这个例子

4

5 回答 5

18

StickyHeaderListview作为SwipeRefreshLayout. _ StickyHeaderListview实际上是一个FrameLayout包裹一个ListView里面。正如nitesh goel解释的那样,这会导致canChildScrollUp(). 基于nitesh goel的示例,这是CustomSwipeRefreshLayout对我来说很好的完整版本:

public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {

    /**
     * A StickyListHeadersListView whose parent view is this SwipeRefreshLayout
     */
    private StickyListHeadersListView mStickyListHeadersListView;

    public CustomSwipeRefreshLayout(Context context) {
        super(context);
    }

    public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setStickyListHeadersListView(StickyListHeadersListView stickyListHeadersListView) {
        mStickyListHeadersListView = stickyListHeadersListView;
    }

    @Override
    public boolean canChildScrollUp() {
        if (mStickyListHeadersListView != null) {
            // In order to scroll a StickyListHeadersListView up:
            // Firstly, the wrapped ListView must have at least one item
            return (mStickyListHeadersListView.getListChildCount() > 0) &&
                    // And then, the first visible item must not be the first item
                    ((mStickyListHeadersListView.getFirstVisiblePosition() > 0) ||
                            // If the first visible item is the first item,
                            // (we've reached the first item)
                            // make sure that its top must not cross over the padding top of the wrapped ListView
                            (mStickyListHeadersListView.getListChildAt(0).getTop() < 0));

            // If the wrapped ListView is empty or,
            // the first item is located below the padding top of the wrapped ListView,
            // we can allow performing refreshing now
        } else {
            // Fall back to default implementation
            return super.canChildScrollUp();
        }
    }
}
于 2014-06-17T14:48:09.480 回答
3

好的,我已经开始工作了。如果SwipeRefreshLayout是布局的根并且ListView位于层次结构的深处(我将ListView内部 aRelativeLayout与空的 一起放入TextView)而不是 的直接子级SwipeRefreshLayout,则它不会正确检测到列表视图上的向上滑动。

您应该创建一个自定义类来扩展SwipeRefreshLayout和覆盖canChildScrollUp()方法SwipRefreshLayout

这是一个例子:

public class CustomSwipeRefreshLayout extends SwipeRefreshLayout{
    private AbsListView view;

    public CustomSwipeRefreshLayout(Context context) {
        super(context);
    }

    public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setView(AbsListView view){
        this.view=view;
    }

    @Override
    public boolean canChildScrollUp() {
        return view.getFirstVisiblePosition()!=0;
    }
}
于 2014-05-13T07:33:38.863 回答
2

我也遇到过类似的问题,直接子应该是ScrollView(或者ListView)的一个实例。SwipeRefreshLayout 将仅考虑直接子级的滚动,而不考虑该直接子级的子级。我设法通过使用两个 SwipeRefreshLayouts 解决了这个问题。

我在github上发布了代码。

于 2014-04-15T10:55:12.550 回答
1

嗨,我想我做了一些一般用途的东西:

public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {
    private View v;

    public CustomSwipeRefreshLayout(Context context) {
        super(context);
    }

    public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setView(View v) {
        this.v = v;
    }

    @Override
    public boolean canChildScrollUp() {
        return this.v.canScrollVertically(-1);
    }
}

使用该解决方案,仅在调用 canChildScrollUp() 之后设置要在 SwipeRefreshLayout 内滚动的视图。像这样 :

this.refreshLayout.setView(aView);
this.refreshLayout.canChildScrollUp();

我没有对其进行大量测试,但如果我是对的,它将适用于 SwipeRefreshLayout 中每个位置(直接子或非直接子)的每个视图。

(对我来说是 SwipeRefreshLayout => RelativeLayout => SrcollView => linearLayout)

于 2016-06-10T15:03:35.170 回答
0

这是非常简单的解决方案:

list.setOnScrollListener(new AbsListView.OnScrollListener() {                                                   
    @Override                                                                                                   
    public void onScrollStateChanged(AbsListView view, int scrollState) {                                       
    }                                                                                                           

    @Override                                                                                                   
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {    
        int topRowVerticalPosition = (list == null || list.getChildCount() == 0) ?                              
                0 : list.getChildAt(0).getTop();                                                                
        swipeRefreshLayout.setEnabled((topRowVerticalPosition >= 0));                                           
    }                                                                                                           
});                                                                                                             

因此,如果您位于列表视图的顶部,您将可以进行刷新。

于 2015-03-02T10:40:56.483 回答