android - SwipeRefreshLayout 干扰 ViewPager 内的 GridView

标签 android gridview android-viewpager swiperefreshlayout

我有一个ViewPager作为主布局,有3个 fragment 作为页面,其中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>

第一个 fragment 的代码:

<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>

GridView 充满了项目。当我向上滚动时,在列表中间,SwipeRefreshLayout 在列表到达顶部之前被触发。 我该如何解决这个问题?

最佳答案

我讨厌回答自己的问题,但我总是这样做:)。

以谷歌为例SwipeRefreshMultipleViews ,通过对类 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;
    }

}

关于android - SwipeRefreshLayout 干扰 ViewPager 内的 GridView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27885600/

相关文章:

java - 如何在编辑文本字段上设置单词java(android)

c# - GridView 编辑/更新事件在 1 次单击后未触发

Android - Fragment 之间的通信

gridview - 如何在 yii2 分页中使用 bootstrap glyphicon 图标作为上一个和下一个按钮?

c# - 数据绑定(bind)不刷新 Gridview

android - ViewPager SetCurrentItem点击后不设置位置

android - Android fragment 问题

java - 如果我在 XML 布局中声明一个 fragment ,我如何将它传递给 Bundle?

android - setContentView 和 findViewById

android - 从 fragment 通知 RecyclerView 适配器