设置拉动以刷新交错网格视图

时间:2013-08-19 13:50:40

标签: android pull-to-refresh

我正在使用Staggered Grid View-Master Library开发像Pinterest这样的视图,我在这方面非常成功。但现在我想在我的应用程序中实现Pull刷新。我一直在使用johannilsson中的库,但不包括交错网格视图的拉动刷新。我一直在使用的代码是:

      ((PullToRefreshListView)getListView()).setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Do work to refresh the list here.
                new GetDataTask().execute();
            }
        });


      adapter = new StaggeredAdapter(AllContestsList.this, R.id.imageView1, arrContest,false,false,false);

        gridView.setAdapter(adapter);

        adapter.notifyDataSetChanged();

帮助将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:2)

我遇到了类似的问题。我发现这个提交是为了刷新GIT https://github.com/chrisbanes/Android-PullToRefresh/pull/230/files。不幸的是,我在图书馆找不到它。所以我将文件复制到我的项目并更新它。这是班级:

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;

public class PullToRefreshStaggeredGridView extends PullToRefreshBase<StaggeredGridView> {

private static final OnRefreshListener<StaggeredGridView> defaultOnRefreshListener = new OnRefreshListener<StaggeredGridView>() {

    @Override
    public void onRefresh(PullToRefreshBase<StaggeredGridView> refreshView) {

    }

};

public PullToRefreshStaggeredGridView(Context context) {
    super(context);

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

public PullToRefreshStaggeredGridView(Context context, AttributeSet attrs) {
    super(context, attrs);

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

public PullToRefreshStaggeredGridView(Context context, Mode mode) {
    super(context, mode);

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

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

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

@Override
public final Orientation getPullToRefreshScrollDirection() {
    return Orientation.VERTICAL;
}

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

    if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
        gridView = new InternalStaggeredGridViewSDK9(context, attrs);
    } else {
        gridView = new StaggeredGridView(context, attrs);
    }

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

@Override
protected boolean isReadyForPullStart() {

    boolean result = false;
    View v = 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 visible
            boolean isTopFullyVisible = v.getTop() >= 0;

            result = isTopFullyVisible;
        }
    }
    return result;
}

@Override
protected boolean isReadyForPullEnd() {
    boolean result = false;
    int last = getRefreshableView().getChildCount() - 1;
    View v = getRefreshableView().getChildAt(last);

    int firstVisiblePosition = getRefreshableView().getFirstPosition();
    int visibleItemCount = getRefreshableView().getChildCount();
    int itemCount = getRefreshableView().getAdapter().getCount();
    if (firstVisiblePosition + visibleItemCount >= itemCount) {
        if (v != null) {
            boolean isLastFullyVisible = v.getBottom() <= getRefreshableView().getHeight();

            result = isLastFullyVisible;
        }
    }
    return result;
}

@Override
protected void onPtrRestoreInstanceState(Bundle savedInstanceState) {
    super.onPtrRestoreInstanceState(savedInstanceState);
}

@Override
protected void onPtrSaveInstanceState(Bundle saveState) {
    super.onPtrSaveInstanceState(saveState);
}

@TargetApi(9)
final class InternalStaggeredGridViewSDK9 extends StaggeredGridView {

    // WebView doesn't always scroll back to it's edge so we add some
    // fuzziness
    static final int OVERSCROLL_FUZZY_THRESHOLD = 2;

    // WebView seems quite reluctant to overscroll so we use the scale
    // factor to scale it's value
    static final float OVERSCROLL_SCALE_FACTOR = 1.5f;

    public InternalStaggeredGridViewSDK9(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

        final boolean returnValue = 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
     */
    private int getScrollRange() {
        int scrollRange = 0;
        if (getChildCount() > 0) {
            View child = getChildAt(0);
            scrollRange = Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop()));
        }
        return scrollRange;
    }

}
}

像这样在XML中使用它(将com.example替换为您的包):

<com.example.PullToRefreshStaggeredGridView
        xmlns: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>

如果要在此gridview上设置适配器,请使用以下代码执行:

gridView.getRefreshableView().setAdapter(adapter);

这一切都很有趣。

P.S。:如果在此gridview的适配器上调用notifyDataSetChanged,则会导致视图跳回到顶部位置。您可以在此处使用解决方案进行修复:https://stackoverflow.com/a/5688490/1319519

答案 1 :(得分:0)


当我在android上搜索pinterest样式布局时,我在下面找到了一个帖子。
http://www.rahuljiresal.com/2014/03/pinterest-style-layout-on-android/

然后我选择使用AndroidStaggeredGrid库作为他的推荐。
但它没有提供拉动刷新功能。
所以我决定将etsy的AndroidStaggeredGrid与Chris Banes&#39; Android的PullToRefresh。

etsy的AndroidStaggeredGrid
https://github.com/etsy/AndroidStaggeredGrid

Chris Banes&#39; Android的PullToRefresh
https://github.com/chrisbanes/Android-PullToRefresh

在这里,我将介绍如何组合这些库。

(1)在etsy的AndroidStaggeredGrid上,
StaggeredGridView在使用PullToRefresh时存在问题。 我打开了这个问题
https://github.com/etsy/AndroidStaggeredGrid/issues/177

StaggeredGridView.java

 @Override
 protected void onSizeChanged(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)关于Chris Banes&#39; Android的PullToRefresh,
创建PullToRefreshStaggeredView文件,其代码如下。

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;

  public class PullToRefreshStaggeredView extends PullToRefreshAdapterViewBase<StaggeredGridView> {

    public PullToRefreshStaggeredView(Context context) {
        super(context);
    }

    public PullToRefreshStaggeredView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PullToRefreshStaggeredView(Context context, Mode mode) {
        super(context, mode);
    }

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

    @Override
    public final Orientation getPullToRefreshScrollDirection() {
        return Orientation.VERTICAL;
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        ((StaggeredGridView) mRefreshableView).setAdapter(adapter);
    }

    @Override
    protected final StaggeredGridView createRefreshableView(Context context, AttributeSet attrs) {
        final StaggeredGridView gv;
        if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
            gv = new InternalStaggeredGridViewSDK9(context, attrs);
        } else {
            gv = new InternalStaggeredGridView(context, attrs);
        }

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

    class InternalStaggeredGridView extends StaggeredGridView implements EmptyViewMethodAccessor {

        public InternalStaggeredGridView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        public void setEmptyView(View emptyView) {
            PullToRefreshStaggeredView.this.setEmptyView(emptyView);
        }

        @Override
        public void setEmptyViewInternal(View emptyView) {
            super.setEmptyView(emptyView);
        }
    }

    @TargetApi(9)
    final class InternalStaggeredGridViewSDK9 extends InternalStaggeredGridView {

        public InternalStaggeredGridViewSDK9(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

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

            final boolean returnValue = 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)在您的申请中,
用活动测试它。

PullToRefreshStaggeredListActivity.java

 public class PullToRefreshStaggeredListActivity extends Activity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.pull_to_refresh_staggered_list);

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

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

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

         // set adapter
         listview.setAdapter(new MyAdapter());
     }

 }

pull_to_refresh_staggered_list.xml

  <LinearLayout xmlns: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.PullToRefreshStaggeredView
          xmlns: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>