Skip to content

Instantly share code, notes, and snippets.

@vipulasri
Created November 18, 2016 07:03
Show Gist options
  • Save vipulasri/ae7fee8cc49677c02265c9827feef82e to your computer and use it in GitHub Desktop.
Save vipulasri/ae7fee8cc49677c02265c9827feef82e to your computer and use it in GitHub Desktop.
RecyclerView-Grid-with-Load-More
/**
* Created by Vipul on 18/11/16.
*/
public class Elements {
private int icon;
private String name;
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/**
* Created by Vipul on 18/11/16.
*/
public class ElementsAdapter extends RecyclerView.Adapter {
interface Callbacks {
public void onClickLoadMore();
}
private Callbacks mCallbacks;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_FOOTER = 2;
private boolean mWithHeader = false;
private boolean mWithFooter = false;
private List<Elements> mFeedList;
public ElementsAdapter(List<Elements> feedList) {
this.mFeedList = feedList;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = null;
if (viewType == TYPE_FOOTER) {
itemView = View.inflate(parent.getContext(), R.layout.row_loadmore, null);
return new LoadMoreViewHolder(itemView);
} else {
itemView = View.inflate(parent.getContext(), R.layout.row_element, null);
return new ElementsViewHolder(itemView);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof LoadMoreViewHolder) {
LoadMoreViewHolder loadMoreViewHolder = (LoadMoreViewHolder) holder;
loadMoreViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mCallbacks!=null)
mCallbacks.onClickLoadMore();
}
});
} else {
ElementsViewHolder elementsViewHolder = (ElementsViewHolder) holder;
Elements elements = mFeedList.get(position);
elementsViewHolder.icon.setImageResource(elements.getIcon());
elementsViewHolder.name.setText(elements.getName());
}
}
@Override
public int getItemCount() {
int itemCount = mFeedList.size();
if (mWithHeader)
itemCount++;
if (mWithFooter)
itemCount++;
return itemCount;
}
@Override
public int getItemViewType(int position) {
if (mWithHeader && isPositionHeader(position))
return TYPE_HEADER;
if (mWithFooter && isPositionFooter(position))
return TYPE_FOOTER;
return TYPE_ITEM;
}
public boolean isPositionHeader(int position) {
return position == 0 && mWithHeader;
}
public boolean isPositionFooter(int position) {
return position == getItemCount() - 1 && mWithFooter;
}
public void setWithHeader(boolean value){
mWithHeader = value;
}
public void setWithFooter(boolean value){
mWithFooter = value;
}
public void setCallback(Callbacks callbacks){
mCallbacks = callbacks;
}
public class ElementsViewHolder extends RecyclerView.ViewHolder {
private ImageView icon;
private TextView name;
public ElementsViewHolder(View itemView) {
super(itemView);
icon = (ImageView) itemView.findViewById(R.id.icon);
name = (TextView) itemView.findViewById(R.id.name);
}
}
public class LoadMoreViewHolder extends RecyclerView.ViewHolder {
public LoadMoreViewHolder(View itemView) {
super(itemView);
}
}
}
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* ItemDecoration implementation that applies and inset margin
* around each child of the RecyclerView. It also draws item dividers
* that are expected from a vertical list implementation, such as
* ListView.
*/
public class GridDividerDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = { android.R.attr.listDivider };
private Drawable mDivider;
private int mInsets;
public GridDividerDecoration(Context context) {
TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
mInsets = 1;
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
drawVertical(c, parent);
drawHorizontal(c, parent);
}
/** Draw dividers at each expected grid interval */
public void drawVertical(Canvas c, RecyclerView parent) {
if (parent.getChildCount() == 0) return;
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - params.leftMargin - mInsets;
final int right = child.getRight() + params.rightMargin + mInsets;
final int top = child.getBottom() + params.bottomMargin + mInsets;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
/** Draw dividers to the right of each child view */
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + params.rightMargin + mInsets;
final int right = left + mDivider.getIntrinsicWidth();
final int top = child.getTop() - params.topMargin - mInsets;
final int bottom = child.getBottom() + params.bottomMargin + mInsets;
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//We can supply forced insets for each item view here in the Rect
outRect.set(mInsets, mInsets, mInsets, mInsets);
}
}
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ElementsAdapter.Callbacks{
private List<Elements> mainList = new ArrayList<>();
private List<Elements> dummyList = new ArrayList<>();
private RecyclerView recyclerView;
private ElementsAdapter elementsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
int columns = 2;
final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, columns);
recyclerView.addItemDecoration(new GridDividerDecoration(this));
recyclerView.setLayoutManager(gridLayoutManager);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return elementsAdapter.isPositionFooter(position) ? gridLayoutManager.getSpanCount() : 1;
}
});
// added all elements to main list
for(int i = 0; i<12; ++i) {
Elements elements = new Elements();
elements.setIcon(R.mipmap.ic_launcher);
elements.setName("Element "+i);
mainList.add(elements);
}
// now only add number of elements for the first show i.e. 6
for(int i = 0; i<6; ++i) {
dummyList.add(mainList.get(i));
}
elementsAdapter = new ElementsAdapter(dummyList);
elementsAdapter.setCallback(this);
elementsAdapter.setWithFooter(true); //enabling footer to show
recyclerView.setAdapter(elementsAdapter);
}
@Override
public void onClickLoadMore() {
elementsAdapter.setWithFooter(false); // hide footer
// now add remaining elements
for(int i = 6; i<mainList.size(); ++i) {
dummyList.add(mainList.get(i));
}
elementsAdapter.notifyDataSetChanged(); // more elements will be added
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="25dp"
android:background="@android:color/white"
android:gravity="center">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/icon"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/name" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="15dp"
android:text="Load More"
android:textSize="16sp"
android:textColor="#FF5722"/>
</LinearLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment