Skip to content Skip to sidebar Skip to footer

Set Up Pull To Refresh For Staggered Grid View

I am using Staggered Grid View-Master Library to develope the view like Pinterest and I'm quite successful in that. But now I want to implement Pull to refresh within my app. I hav

Solution 1:

I faced similar issue. I found this commit in pull to refresh GIT https://github.com/chrisbanes/Android-PullToRefresh/pull/230/files. Unfortunately, I could not find it in the library. So I copied the file to my project and update it. Here is the class:

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;

import com.handmark.pulltorefresh.library.OverscrollHelper;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.R;
import com.origamilabs.library.views.StaggeredGridView;

publicclassPullToRefreshStaggeredGridViewextendsPullToRefreshBase<StaggeredGridView> {

privatestaticfinal OnRefreshListener<StaggeredGridView> defaultOnRefreshListener = newOnRefreshListener<StaggeredGridView>() {

    @OverridepublicvoidonRefresh(PullToRefreshBase<StaggeredGridView> refreshView) {

    }

};

publicPullToRefreshStaggeredGridView(Context context) {
    super(context);

    /**
     * Added so that by default, Pull-to-Refresh refreshes the page
     */
    setOnRefreshListener(defaultOnRefreshListener);
}

publicPullToRefreshStaggeredGridView(Context context, AttributeSet attrs) {
    super(context, attrs);

    /**
     * Added so that by default, Pull-to-Refresh refreshes the page
     */
    setOnRefreshListener(defaultOnRefreshListener);
}

publicPullToRefreshStaggeredGridView(Context context, Mode mode) {
    super(context, mode);

    /**
     * Added so that by default, Pull-to-Refresh refreshes the page
     */
    setOnRefreshListener(defaultOnRefreshListener);
}

publicPullToRefreshStaggeredGridView(Context context, Mode mode, AnimationStyle style) {
    super(context, mode, style);

    /**
     * Added so that by default, Pull-to-Refresh refreshes the page
     */
    setOnRefreshListener(defaultOnRefreshListener);
}

@Overridepublicfinal Orientation getPullToRefreshScrollDirection() {
    return Orientation.VERTICAL;
}

@Overrideprotected StaggeredGridView createRefreshableView(Context context, AttributeSet attrs) {
    StaggeredGridView gridView;

    if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
        gridView = newInternalStaggeredGridViewSDK9(context, attrs);
    } else {
        gridView = newStaggeredGridView(context, attrs);
    }

    gridView.setId(R.id.gridview);
    return gridView;
}

@OverrideprotectedbooleanisReadyForPullStart() {

    booleanresult=false;
    Viewv= getRefreshableView().getChildAt(0);
    if (getRefreshableView().getFirstPosition() == 0) {
        if (v != null) {
            // getTop() and getBottom() are relative to the ListView,// so if getTop() is negative, it is not fully visiblebooleanisTopFullyVisible= v.getTop() >= 0;

            result = isTopFullyVisible;
        }
    }
    return result;
}

@OverrideprotectedbooleanisReadyForPullEnd() {
    booleanresult=false;
    intlast= getRefreshableView().getChildCount() - 1;
    Viewv= getRefreshableView().getChildAt(last);

    intfirstVisiblePosition= getRefreshableView().getFirstPosition();
    intvisibleItemCount= getRefreshableView().getChildCount();
    intitemCount= getRefreshableView().getAdapter().getCount();
    if (firstVisiblePosition + visibleItemCount >= itemCount) {
        if (v != null) {
            booleanisLastFullyVisible= v.getBottom() <= getRefreshableView().getHeight();

            result = isLastFullyVisible;
        }
    }
    return result;
}

@OverrideprotectedvoidonPtrRestoreInstanceState(Bundle savedInstanceState) {
    super.onPtrRestoreInstanceState(savedInstanceState);
}

@OverrideprotectedvoidonPtrSaveInstanceState(Bundle saveState) {
    super.onPtrSaveInstanceState(saveState);
}

@TargetApi(9)finalclassInternalStaggeredGridViewSDK9extendsStaggeredGridView {

    // WebView doesn't always scroll back to it's edge so we add some// fuzzinessstaticfinalintOVERSCROLL_FUZZY_THRESHOLD=2;

    // WebView seems quite reluctant to overscroll so we use the scale// factor to scale it's valuestaticfinalfloatOVERSCROLL_SCALE_FACTOR=1.5f;

    publicInternalStaggeredGridViewSDK9(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @OverrideprotectedbooleanoverScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
            int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

        finalbooleanreturnValue=super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
                scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);

        // Does all of the hard work...// OverscrollHelper.overScrollBy(PullToRefreshStaggeredGridView.this,// deltaX, scrollX, deltaY, scrollY,// getScrollRange(), OVERSCROLL_FUZZY_THRESHOLD,// OVERSCROLL_SCALE_FACTOR, isTouchEvent);// Does all of the hard work...
        OverscrollHelper.overScrollBy(PullToRefreshStaggeredGridView.this, deltaX, scrollX, deltaY,
                getScrollRange(), isTouchEvent);

        return returnValue;
    }

    /**
     * Taken from the AOSP ScrollView source
     */privateintgetScrollRange() {
        intscrollRange=0;
        if (getChildCount() > 0) {
            Viewchild= getChildAt(0);
            scrollRange = Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop()));
        }
        return scrollRange;
    }

}
}

Use it in XML like this (replace com.example with your package):

<com.example.PullToRefreshStaggeredGridViewxmlns:ptr="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:stretchMode="columnWidth"ptr:ptrMode="both"staggered:itemMargin="10dp"staggered:numColumns="3" ></com.example.PullToRefreshStaggeredGridView>

If you want to set adapter on this gridview, do it with this code:

gridView.getRefreshableView().setAdapter(adapter);

That's all enjoy.

P.S.: If you call notifyDataSetChanged on the adapter of this gridview, it causes the view jump back to top position. You can fix it with the solution here: https://stackoverflow.com/a/5688490/1319519 .

Solution 2:

When I was searching for pinterest style layout on android, I found a post below. http://www.rahuljiresal.com/2014/03/pinterest-style-layout-on-android/ Then I chose to use AndroidStaggeredGrid library as his recommend. But it has not offered pull to refresh function. So I decided to combine etsy's AndroidStaggeredGrid with Chris Banes' Android-PullToRefresh. etsy's AndroidStaggeredGrid https://github.com/etsy/AndroidStaggeredGrid Chris Banes' Android-PullToRefresh https://github.com/chrisbanes/Android-PullToRefresh Here I am introducing how I did to combine those libraries. (1) On etsy's AndroidStaggeredGrid, StaggeredGridView has an issue for working with PullToRefresh. I opened the issue https://github.com/etsy/AndroidStaggeredGrid/issues/177 StaggeredGridView.java

@OverrideprotectedvoidonSizeChanged(int w, int h) {
    super.onSizeChanged(w, h);

    // add below code in order to avoid shrinking width while being wrapped by PullToRefresh.if(w <= 0 || h <= 0) {
        return;
    }

(2) On Chris Banes' Android-PullToRefresh, Create PullToRefreshStaggeredView file which code is below. PullToRefreshStaggeredView.java

package com.handmark.pulltorefresh.library;

  import android.annotation.TargetApi;
  import android.content.Context;
  import android.os.Build.VERSION;
  import android.os.Build.VERSION_CODES;
  import android.util.AttributeSet;
  import android.util.Log;
  import android.view.View;
  import android.view.ViewGroup;

  import com.etsy.android.grid.StaggeredGridView;
  import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor;

  publicclassPullToRefreshStaggeredViewextendsPullToRefreshAdapterViewBase<StaggeredGridView> {

    publicPullToRefreshStaggeredView(Context context) {
        super(context);
    }

    publicPullToRefreshStaggeredView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    publicPullToRefreshStaggeredView(Context context, Mode mode) {
        super(context, mode);
    }

    publicPullToRefreshStaggeredView(Context context, Mode mode, AnimationStyle style) {
        super(context, mode, style);
    }

    @Overridepublicfinal Orientation getPullToRefreshScrollDirection() {
        return Orientation.VERTICAL;
    }

    @OverridepublicvoidsetAdapter(ListAdapter adapter) {
        ((StaggeredGridView) mRefreshableView).setAdapter(adapter);
    }

    @Overrideprotectedfinal StaggeredGridView createRefreshableView(Context context, AttributeSet attrs) {
        final StaggeredGridView gv;
        if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
            gv = newInternalStaggeredGridViewSDK9(context, attrs);
        } else {
            gv = newInternalStaggeredGridView(context, attrs);
        }

        // Use Generated ID (from res/values/ids.xml)
        gv.setId(R.id.gridview);
        return gv;
    }

    classInternalStaggeredGridViewextendsStaggeredGridViewimplementsEmptyViewMethodAccessor {

        publicInternalStaggeredGridView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @OverridepublicvoidsetEmptyView(View emptyView) {
            PullToRefreshStaggeredView.this.setEmptyView(emptyView);
        }

        @OverridepublicvoidsetEmptyViewInternal(View emptyView) {
            super.setEmptyView(emptyView);
        }
    }

    @TargetApi(9)finalclassInternalStaggeredGridViewSDK9extendsInternalStaggeredGridView {

        publicInternalStaggeredGridViewSDK9(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @OverrideprotectedbooleanoverScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
                int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

            finalbooleanreturnValue=super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
                    scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);

            // Does all of the hard work...
            OverscrollHelper.overScrollBy(PullToRefreshStaggeredView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent);

            return returnValue;
        }
    }


  }

(3) On your application, Test it with an activity.

PullToRefreshStaggeredListActivity.java

publicclassPullToRefreshStaggeredListActivityextendsActivity {

     @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.pull_to_refresh_staggered_list);

         PullToRefreshStaggeredViewlistview= (PullToRefreshStaggeredView) findViewById(R.id.list);
         StaggeredGridViewstaggeredView= (StaggeredGridView) ((PullToRefreshAdapterViewBase<?>) listview).getRefreshableView();

         // add headerViewheader= getLayoutInflater().inflate(R.layout.header, null, false);
         staggeredView.addHeaderView(header);

         // add footerViewfooter= getLayoutInflater().inflate(R.layout.footer, null, false);
         staggeredView.addFooterView(footer);

         // set adapter
         listview.setAdapter(newMyAdapter());
     }

 }

pull_to_refresh_staggered_list.xml

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" ><com.handmark.pulltorefresh.library.PullToRefreshStaggeredViewxmlns:ptr="http://schemas.android.com/apk/res-auto"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/list"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center"android:alwaysDrawnWithCache="true"android:background="#10ffff00"app:column_count="3"app:item_margin="8dp"ptr:ptrHeaderBackground="#10ff00ff" /></LinearLayout>

Post a Comment for "Set Up Pull To Refresh For Staggered Grid View"