Skip to content

Most visited

Recently visited

navigation
SwipeRefreshMultipleViews / src / com.example.android.swiperefreshmultipleviews /

MultiSwipeRefreshLayout.java

1
/*
2
 * Copyright 2014 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *       http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
package com.example.android.swiperefreshmultipleviews;
18
 
19
import android.content.Context;
20
import android.support.v4.view.ViewCompat;
21
import android.support.v4.widget.SwipeRefreshLayout;
22
import android.util.AttributeSet;
23
import android.view.View;
24
import android.widget.AbsListView;
25
 
26
/**
27
 * A descendant of {@link android.support.v4.widget.SwipeRefreshLayout} which supports multiple
28
 * child views triggering a refresh gesture. You set the views which can trigger the gesture via
29
 * {@link #setSwipeableChildren(int...)}, providing it the child ids.
30
 */
31
public class MultiSwipeRefreshLayout extends SwipeRefreshLayout {
32
 
33
    private View[] mSwipeableChildren;
34
 
35
    public MultiSwipeRefreshLayout(Context context) {
36
        super(context);
37
    }
38
 
39
    public MultiSwipeRefreshLayout(Context context, AttributeSet attrs) {
40
        super(context, attrs);
41
    }
42
 
43
    /**
44
     * Set the children which can trigger a refresh by swiping down when they are visible. These
45
     * views need to be a descendant of this view.
46
     */
47
    public void setSwipeableChildren(final int... ids) {
48
        assert ids != null;
49
 
50
        // Iterate through the ids and find the Views
51
        mSwipeableChildren = new View[ids.length];
52
        for (int i = 0; i < ids.length; i++) {
53
            mSwipeableChildren[i] = findViewById(ids[i]);
54
        }
55
    }
56
 
58
    /**
59
     * This method controls when the swipe-to-refresh gesture is triggered. By returning false here
60
     * we are signifying that the view is in a state where a refresh gesture can start.
61
     *
62
     * <p>As {@link android.support.v4.widget.SwipeRefreshLayout} only supports one direct child by
63
     * default, we need to manually iterate through our swipeable children to see if any are in a
64
     * state to trigger the gesture. If so we return false to start the gesture.
65
     */
66
    @Override
67
    public boolean canChildScrollUp() {
68
        if (mSwipeableChildren != null && mSwipeableChildren.length > 0) {
69
            // Iterate through the scrollable children and check if any of them can not scroll up
70
            for (View view : mSwipeableChildren) {
71
                if (view != null && view.isShown() && !canViewScrollUp(view)) {
72
                    // If the view is shown, and can not scroll upwards, return false and start the
73
                    // gesture.
74
                    return false;
75
                }
76
            }
77
        }
78
        return true;
79
    }
81
 
83
    /**
84
     * Utility method to check whether a {@link View} can scroll up from it's current position.
85
     * Handles platform version differences, providing backwards compatible functionality where
86
     * needed.
87
     */
88
    private static boolean canViewScrollUp(View view) {
89
        if (android.os.Build.VERSION.SDK_INT >= 14) {
90
            // For ICS and above we can call canScrollVertically() to determine this
91
            return ViewCompat.canScrollVertically(view, -1);
92
        } else {
93
            if (view instanceof AbsListView) {
94
                // Pre-ICS we need to manually check the first visible item and the child view's top
95
                // value
96
                final AbsListView listView = (AbsListView) view;
97
                return listView.getChildCount() > 0 &&
98
                        (listView.getFirstVisiblePosition() > 0
99
                                || listView.getChildAt(0).getTop() < listView.getPaddingTop());
100
            } else {
101
                // For all other view types we just check the getScrollY() value
102
                return view.getScrollY() > 0;
103
            }
104
        }
105
    }
107
}
This site uses cookies to store your preferences for site-specific language and display options.

Hooray!

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.