Created
October 13, 2015 06:12
-
-
Save Folyd/8b748a9aae366823bfe4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2014 The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.example.android.swiperefreshmultipleviews; | |
import android.content.Context; | |
import android.support.v4.view.ViewCompat; | |
import android.support.v4.widget.SwipeRefreshLayout; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.widget.AbsListView; | |
/** | |
* A descendant of {@link android.support.v4.widget.SwipeRefreshLayout} which supports multiple | |
* child views triggering a refresh gesture. You set the views which can trigger the gesture via | |
* {@link #setSwipeableChildren(int...)}, providing it the child ids. | |
*/ | |
public class MultiSwipeRefreshLayout extends SwipeRefreshLayout { | |
private View[] mSwipeableChildren; | |
public MultiSwipeRefreshLayout(Context context) { | |
super(context); | |
} | |
public MultiSwipeRefreshLayout(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
/** | |
* Set the children which can trigger a refresh by swiping down when they are visible. These | |
* views need to be a descendant of this view. | |
*/ | |
public void setSwipeableChildren(final int... ids) { | |
assert ids != null; | |
// Iterate through the ids and find the Views | |
mSwipeableChildren = new View[ids.length]; | |
for (int i = 0; i < ids.length; i++) { | |
mSwipeableChildren[i] = findViewById(ids[i]); | |
} | |
} | |
// BEGIN_INCLUDE(can_child_scroll_up) | |
/** | |
* This method controls when the swipe-to-refresh gesture is triggered. By returning false here | |
* we are signifying that the view is in a state where a refresh gesture can start. | |
* | |
* <p>As {@link android.support.v4.widget.SwipeRefreshLayout} only supports one direct child by | |
* default, we need to manually iterate through our swipeable children to see if any are in a | |
* state to trigger the gesture. If so we return false to start the gesture. | |
*/ | |
@Override | |
public boolean canChildScrollUp() { | |
if (mSwipeableChildren != null && mSwipeableChildren.length > 0) { | |
// Iterate through the scrollable children and check if any of them can not scroll up | |
for (View view : mSwipeableChildren) { | |
if (view != null && view.isShown() && !canViewScrollUp(view)) { | |
// If the view is shown, and can not scroll upwards, return false and start the | |
// gesture. | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
// END_INCLUDE(can_child_scroll_up) | |
// BEGIN_INCLUDE(can_view_scroll_up) | |
/** | |
* Utility method to check whether a {@link View} can scroll up from it's current position. | |
* Handles platform version differences, providing backwards compatible functionality where | |
* needed. | |
*/ | |
private static boolean canViewScrollUp(View view) { | |
if (android.os.Build.VERSION.SDK_INT >= 14) { | |
// For ICS and above we can call canScrollVertically() to determine this | |
return ViewCompat.canScrollVertically(view, -1); | |
} else { | |
if (view instanceof AbsListView) { | |
// Pre-ICS we need to manually check the first visible item and the child view's top | |
// value | |
final AbsListView listView = (AbsListView) view; | |
return listView.getChildCount() > 0 && | |
(listView.getFirstVisiblePosition() > 0 | |
|| listView.getChildAt(0).getTop() < listView.getPaddingTop()); | |
} else { | |
// For all other view types we just check the getScrollY() value | |
return view.getScrollY() > 0; | |
} | |
} | |
} | |
// END_INCLUDE(can_view_scroll_up) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment