Skip to content

Most visited

Recently visited

navigation
SwipeRefreshListFragment / src / com.example.android.swiperefreshlistfragment /

SwipeRefreshListFragment.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.swiperefreshlistfragment;
18
 
19
import android.content.Context;
20
import android.os.Bundle;
21
import android.support.v4.app.ListFragment;
22
import android.support.v4.view.ViewCompat;
23
import android.support.v4.widget.SwipeRefreshLayout;
24
import android.view.LayoutInflater;
25
import android.view.View;
26
import android.view.ViewGroup;
27
import android.widget.ListView;
28
 
29
/**
30
 * Subclass of {@link android.support.v4.app.ListFragment} which provides automatic support for
31
 * providing the 'swipe-to-refresh' UX gesture by wrapping the the content view in a
32
 * {@link android.support.v4.widget.SwipeRefreshLayout}.
33
 */
34
public class SwipeRefreshListFragment extends ListFragment {
35
 
36
    private SwipeRefreshLayout mSwipeRefreshLayout;
37
 
38
    @Override
39
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
40
            Bundle savedInstanceState) {
41
 
42
        // Create the list fragment's content view by calling the super method
43
        final View listFragmentView = super.onCreateView(inflater, container, savedInstanceState);
44
 
45
        // Now create a SwipeRefreshLayout to wrap the fragment's content view
46
        mSwipeRefreshLayout = new ListFragmentSwipeRefreshLayout(container.getContext());
47
 
48
        // Add the list fragment's content view to the SwipeRefreshLayout, making sure that it fills
49
        // the SwipeRefreshLayout
50
        mSwipeRefreshLayout.addView(listFragmentView,
51
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
52
 
53
        // Make sure that the SwipeRefreshLayout will fill the fragment
54
        mSwipeRefreshLayout.setLayoutParams(
55
                new ViewGroup.LayoutParams(
56
                        ViewGroup.LayoutParams.MATCH_PARENT,
57
                        ViewGroup.LayoutParams.MATCH_PARENT));
58
 
59
        // Now return the SwipeRefreshLayout as this fragment's content view
60
        return mSwipeRefreshLayout;
61
    }
62
 
63
    /**
64
     * Set the {@link android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener} to listen for
65
     * initiated refreshes.
66
     *
67
     * @see android.support.v4.widget.SwipeRefreshLayout#setOnRefreshListener(android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener)
68
     */
69
    public void setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) {
70
        mSwipeRefreshLayout.setOnRefreshListener(listener);
71
    }
72
 
73
    /**
74
     * Returns whether the {@link android.support.v4.widget.SwipeRefreshLayout} is currently
75
     * refreshing or not.
76
     *
77
     * @see android.support.v4.widget.SwipeRefreshLayout#isRefreshing()
78
     */
79
    public boolean isRefreshing() {
80
        return mSwipeRefreshLayout.isRefreshing();
81
    }
82
 
83
    /**
84
     * Set whether the {@link android.support.v4.widget.SwipeRefreshLayout} should be displaying
85
     * that it is refreshing or not.
86
     *
87
     * @see android.support.v4.widget.SwipeRefreshLayout#setRefreshing(boolean)
88
     */
89
    public void setRefreshing(boolean refreshing) {
90
        mSwipeRefreshLayout.setRefreshing(refreshing);
91
    }
92
 
93
    /**
94
     * Set the color scheme for the {@link android.support.v4.widget.SwipeRefreshLayout}.
95
     *
96
     * @see android.support.v4.widget.SwipeRefreshLayout#setColorScheme(int, int, int, int)
97
     */
98
    public void setColorScheme(int colorRes1, int colorRes2, int colorRes3, int colorRes4) {
99
        mSwipeRefreshLayout.setColorScheme(colorRes1, colorRes2, colorRes3, colorRes4);
100
    }
101
 
102
    /**
103
     * @return the fragment's {@link android.support.v4.widget.SwipeRefreshLayout} widget.
104
     */
105
    public SwipeRefreshLayout getSwipeRefreshLayout() {
106
        return mSwipeRefreshLayout;
107
    }
108
 
109
    /**
110
     * Sub-class of {@link android.support.v4.widget.SwipeRefreshLayout} for use in this
111
     * {@link android.support.v4.app.ListFragment}. The reason that this is needed is because
112
     * {@link android.support.v4.widget.SwipeRefreshLayout} only supports a single child, which it
113
     * expects to be the one which triggers refreshes. In our case the layout's child is the content
114
     * view returned from
115
     * {@link android.support.v4.app.ListFragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)}
116
     * which is a {@link android.view.ViewGroup}.
117
     *
118
     * <p>To enable 'swipe-to-refresh' support via the {@link android.widget.ListView} we need to
119
     * override the default behavior and properly signal when a gesture is possible. This is done by
120
     * overriding {@link #canChildScrollUp()}.
121
     */
122
    private class ListFragmentSwipeRefreshLayout extends SwipeRefreshLayout {
123
 
124
        public ListFragmentSwipeRefreshLayout(Context context) {
125
            super(context);
126
        }
127
 
128
        /**
129
         * As mentioned above, we need to override this method to properly signal when a
130
         * 'swipe-to-refresh' is possible.
131
         *
132
         * @return true if the {@link android.widget.ListView} is visible and can scroll up.
133
         */
134
        @Override
135
        public boolean canChildScrollUp() {
136
            final ListView listView = getListView();
137
            if (listView.getVisibility() == View.VISIBLE) {
138
                return canListViewScrollUp(listView);
139
            } else {
140
                return false;
141
            }
142
        }
143
 
144
    }
145
 
147
    /**
148
     * Utility method to check whether a {@link ListView} can scroll up from it's current position.
149
     * Handles platform version differences, providing backwards compatible functionality where
150
     * needed.
151
     */
152
    private static boolean canListViewScrollUp(ListView listView) {
153
        if (android.os.Build.VERSION.SDK_INT >= 14) {
154
            // For ICS and above we can call canScrollVertically() to determine this
155
            return ViewCompat.canScrollVertically(listView, -1);
156
        } else {
157
            // Pre-ICS we need to manually check the first visible item and the child view's top
158
            // value
159
            return listView.getChildCount() > 0 &&
160
                    (listView.getFirstVisiblePosition() > 0
161
                            || listView.getChildAt(0).getTop() < listView.getPaddingTop());
162
        }
163
    }
165
 
166
}
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.