Please excuse my English, I'm French...
So, I've got a question for my Android App.
I've to integrate a grid view as Pinterest style.
I found this lib : Staggered Grid View (https://github.com/maurycyw/StaggeredGridView)
It's work fine but... There is no OnScrollListener !
I had to know when the user see the last item, in order to load more.
But it's not possible without OnScrollListener !
Have you got an idea for my problem ?
Thanks a lot.
UPDATE:
After testing,
Calling notifyDataSetChanged()
for StaggeredGridView Adapter
case to reset the scroll position to 0 (Start of the Views).
Instead use PinterestLikeAdapterView
I have add loadMoreListener
to the StaggeredGridView
steps:
1- add a loadmore Interface and booelan isLoading (at the top of the class)
public interface OnLoadMoreListener {
public boolean onLoadMore();
}
private boolean mIsLoading;
private OnLoadMoreListener mLoadMoreListener;
2- find trackMotionScroll
function, in the else of deltaY > 0
and after the up = false;
add
if (overhang <= 80) { // 80 is how nearest to the end. ZERO mean the end of list
// scrolling down and almost reach the end of list
if (false == mIsLoading && null != mLoadMoreListener) {
if (false == mLoadMoreListener.onLoadMore()) {
mIsLoading = true;
Log.d(TAG, "loadMore");
}
}
}
3- add setListener()
and loadComplated()
functions
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
this.mLoadMoreListener = onLoadMoreListener;
}
public void loadMoreCompleated() {
mIsLoading = false;
}
HOW to use:
1- define a loadMoreListener
in your Activity/Fragment
private StaggeredGridView.OnLoadMoreListener loadMoreListener = new StaggeredGridView.OnLoadMoreListener() {
@Override
public boolean onLoadMore() {
loading.setVisibility(View.VISIBLE);
// load more data from internet (not in the UI thread)
return true; // true if you have more data to load, false you dont have more data to load
}
};
2- when you done data loading and add it to the adapter call
private void doneLoading() {
gridView.loadMoreCompleated();
loading.setVisibility(View.GONE);
}
Try this if nothing works for you then wrap your recycler view in a scroll view and then check if scroll view has reached its bottom:
In your xml file:
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</RelativeLayout>
</ScrollView>
In your class file:
private ScrollView mScrollView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initScrollView();
...
}
private void initScrollView() {
mScrollView = (ScrollView) mView.findViewById(R.id.scroll_view);
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
if (mScrollView != null) {
if (mScrollView.getChildAt(0).getBottom() <= (mScrollView.getHeight() + mScrollView.getScrollY())) {
// Scroll view is at bottom
// If not loading then start load more
} else {
// Scroll view is not at bottom
}
}
}
});
}
Remember to set nested scrolling of recycler view to false for smooth scrolling in your class file:
mRecyclerView.setNestedScrollingEnabled(false);
If you want to start loading next page just before it reaches the bottomm, then just subtract an integer from mScrollView.getChildAt(0).getBottom()
For example 1000 is subtracted here:
if (mScrollView.getChildAt(0).getBottom() - 1000 <= (mScrollView.getHeight() + mScrollView.getScrollY())) {
// Scroll view is at bottom
// If not loading then start load more
} else {
// Scroll view is not at bottom
}
Use a greater integer to start loading much before the scroll reaches bottom.
had to know when the user see the last item, in order to load more.
But it's not possible without OnScrollListener !
Why would you use onScrollListener for that? Instead, write a class (MyStaggeredGridAdapter, perhaps?) that extends BaseAdapter and apply it to the StaggeredGridView. Then you can use the adapter's getView() method, which will be called whenever a new view needs to be rendered.
To know when the last item is shown on the screen, i use the Adapter's getView() method. Just compare your last index with the "position" parameter. Something like this
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...
if (lastLoaded == position){
loadMore();
}
...
}
and maybe then you would like to see this: How to add data into bottom of Android StaggeredGridView and not go back top? to avoid load the list from the begining and continue from the last item shown.
i hope this helps, don't know if it's the best solution, but is working for me ;)