SwipeRefreshLayout 干扰 ViewPager 内的 GridView
SwipeRefreshLayout interfere with GridView inside ViewPager
我有一个 ViewPager
作为主布局,有 3 个片段作为页面,其中 2 个有一个 GrideView
里面。
主页代码:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</android.support.v4.widget.SwipeRefreshLayout>
第一个片段的代码:
<GridView
android:id="@+id/firstCategoryGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="1"
android:stretchMode="columnWidth"
android:scrollbars="none"
android:listSelector="#00000000">
</GridView>
网格视图中充满了项目。在列表中间,当我向上滚动时 SwipeRefreshLayout
在列表到达顶部之前被触发。 我该如何解决?
我讨厌回答我自己的问题,但我总是这样做:)。
所以根据 google SwipeRefreshMultipleViews 的示例,对 class MultiSwipeRefreshLayout
稍作改动,我设法解决了问题。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/dark_blue"
app:theme="@style/Theme.AppCompat"
android:layout_alignParentTop="true"/>
<com.mehdok.slidingtabs.SlidingTabLayout
android:id="@+id/main_sliding_tabs"
android:background="@color/blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/main_toolbar" />
<fr.castorflex.android.smoothprogressbar.SmoothProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="4dp"
android:indeterminate="true"
app:spb_sections_count="4"
app:spb_color="@color/white"
app:spb_speed="0.5"
app:spb_stroke_width="4dp"
app:spb_stroke_separator_length="4dp"
app:spb_reversed="false"
app:spb_mirror_mode="false"
app:spb_progressiveStart_activated="false"
app:spb_progressiveStart_speed="1.5"
app:spb_progressiveStop_speed="3.4"
android:layout_below="@id/main_toolbar"
android:visibility="gone"
android:id="@+id/downloadBar"/>
<com.mehdok.views.MultiSwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_sliding_tabs">
<android.support.v4.view.ViewPager
android:id="@+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</android.support.v4.view.ViewPager>
</com.mehdok.views.MultiSwipeRefreshLayout>
</RelativeLayout>
java部分
public class MultiSwipeRefreshLayout extends SwipeRefreshLayout {
private GridView[] mSwipeableChildren;
private int visibleView = 0;
public MultiSwipeRefreshLayout(Context context) {
super(context);
mSwipeableChildren = new GridView[3];
}
public MultiSwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mSwipeableChildren = new GridView[3];
}
public void addGridView(GridView v, int i)
{
mSwipeableChildren[i] = v;
}
/**
* 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) {
for(int i = 0; i < 3; i++)
{
if((i == visibleView) && mSwipeableChildren[i] != null && !canViewScrollUp(mSwipeableChildren[i]))
{
return false;
}
}
}
return true;
}
/**
* 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(GridView view)
{
return view.getChildCount() > 0 &&
(view.getFirstVisiblePosition() > 0
|| view.getChildAt(0).getTop() < view.getPaddingTop());
}
public void setVisibleView(int i)
{
visibleView = i;
}
}
使用新的 class 扩展 SwipeRefreshLayout 并覆盖其 canChildScrollUp()。 return 当您想要向下滚动以查看 gridview 时为真。前
@override.
boolean canChildScrollUp()
{
return gridview.getFirstVisibleItemPostion()!=0;
}
我有一个 ViewPager
作为主布局,有 3 个片段作为页面,其中 2 个有一个 GrideView
里面。
主页代码:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</android.support.v4.widget.SwipeRefreshLayout>
第一个片段的代码:
<GridView
android:id="@+id/firstCategoryGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="1"
android:stretchMode="columnWidth"
android:scrollbars="none"
android:listSelector="#00000000">
</GridView>
网格视图中充满了项目。在列表中间,当我向上滚动时 SwipeRefreshLayout
在列表到达顶部之前被触发。 我该如何解决?
我讨厌回答我自己的问题,但我总是这样做:)。
所以根据 google SwipeRefreshMultipleViews 的示例,对 class MultiSwipeRefreshLayout
稍作改动,我设法解决了问题。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/dark_blue"
app:theme="@style/Theme.AppCompat"
android:layout_alignParentTop="true"/>
<com.mehdok.slidingtabs.SlidingTabLayout
android:id="@+id/main_sliding_tabs"
android:background="@color/blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/main_toolbar" />
<fr.castorflex.android.smoothprogressbar.SmoothProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="4dp"
android:indeterminate="true"
app:spb_sections_count="4"
app:spb_color="@color/white"
app:spb_speed="0.5"
app:spb_stroke_width="4dp"
app:spb_stroke_separator_length="4dp"
app:spb_reversed="false"
app:spb_mirror_mode="false"
app:spb_progressiveStart_activated="false"
app:spb_progressiveStart_speed="1.5"
app:spb_progressiveStop_speed="3.4"
android:layout_below="@id/main_toolbar"
android:visibility="gone"
android:id="@+id/downloadBar"/>
<com.mehdok.views.MultiSwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_sliding_tabs">
<android.support.v4.view.ViewPager
android:id="@+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</android.support.v4.view.ViewPager>
</com.mehdok.views.MultiSwipeRefreshLayout>
</RelativeLayout>
java部分
public class MultiSwipeRefreshLayout extends SwipeRefreshLayout {
private GridView[] mSwipeableChildren;
private int visibleView = 0;
public MultiSwipeRefreshLayout(Context context) {
super(context);
mSwipeableChildren = new GridView[3];
}
public MultiSwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mSwipeableChildren = new GridView[3];
}
public void addGridView(GridView v, int i)
{
mSwipeableChildren[i] = v;
}
/**
* 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) {
for(int i = 0; i < 3; i++)
{
if((i == visibleView) && mSwipeableChildren[i] != null && !canViewScrollUp(mSwipeableChildren[i]))
{
return false;
}
}
}
return true;
}
/**
* 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(GridView view)
{
return view.getChildCount() > 0 &&
(view.getFirstVisiblePosition() > 0
|| view.getChildAt(0).getTop() < view.getPaddingTop());
}
public void setVisibleView(int i)
{
visibleView = i;
}
}
使用新的 class 扩展 SwipeRefreshLayout 并覆盖其 canChildScrollUp()。 return 当您想要向下滚动以查看 gridview 时为真。前
@override.
boolean canChildScrollUp()
{
return gridview.getFirstVisibleItemPostion()!=0;
}