Skip to content

Instantly share code, notes, and snippets.

@hosseiniSeyRo
Last active October 1, 2019 13:25
Show Gist options
  • Save hosseiniSeyRo/0c305d7b3ba617363ea2052fe0941558 to your computer and use it in GitHub Desktop.
Save hosseiniSeyRo/0c305d7b3ba617363ea2052fe0941558 to your computer and use it in GitHub Desktop.
Endless recyclerView+progressBar
RecyclerView recyclerView;
MovieRecyclerViewAdapter adapter;
boolean isEndOfList = false;
.
.
.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
configureRecyclerView();
}
private void configureRecyclerView() {
recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new MovieRecyclerViewAdapter(this, recyclerView);
recyclerView.setAdapter(adapter);
// set RecyclerView on item click listener
adapter.setOnItemClickedListener(position -> {
//TODO recyclerView click handler
});
//set load more listener for the RecyclerView adapter
adapter.setOnLoadMoreListener(() -> {
//TODO loadMore handler
if (!isEndOfList) {
adapter.addNullData(); //add progress item
new Handler().postDelayed(() -> {
adapter.removeNull(); //remove progress item
adapter.setList(responseWrapper.getData()); // fetch data and set to adapter
adapter.setLoaded(); // set false to adapter isLoading
if (responseWrapper.getData() == null) isEndOfList = true; // determine end of list
}, 2000);
}
});
}
.
.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
.
.
public class CustomeRecyclerViewAdapter extends RecyclerView.Adapter<CustomeRecyclerViewAdapter.CustomViewHolder> {
private Context mContext;
private List<T> dataList = new ArrayList<>();
private OnItemClickedListener onItemClickedListener;
// for load more
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private OnLoadMoreListener onLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 2;
private int lastVisibleItem, totalItemCount;
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
this.onLoadMoreListener = onLoadMoreListener;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
public void setOnItemClickedListener(OnItemClickedListener onItemClickedListener) {
this.onItemClickedListener = onItemClickedListener;
}
public interface OnItemClickedListener {
void onItemClick(int position);
}
public CustomeRecyclerViewAdapter(Context mContext, RecyclerView recyclerView) {
this.mContext = mContext;
// load more
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = layoutManager.getItemCount();
lastVisibleItem = layoutManager.findLastVisibleItemPosition();
if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
});
}
@NonNull
@Override
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_list, parent, false);
return new DataViewHolder(view);
} else if (viewType == VIEW_TYPE_LOADING) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_progress, parent, false);
return new LoadingViewHolder(view);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
if (holder instanceof DataViewHolder) {
T currentObject = dataList.get(position);
DataViewHolder dataViewHolder = (DataViewHolder) holder;
Picasso.with(mContext)
.load(currentObject.getPoster())
.centerCrop()
.resizeDimen(R.dimen.posterWidth, R.dimen.posterHeight)
.placeholder(R.drawable.place_holder)
.error(R.drawable.error_image_loading)
.into(dataViewHolder.poster);
dataViewHolder.title.setText(currentObject.getTitle());
dataViewHolder.year.setText(currentObject.getYear());
dataViewHolder.container.setOnClickListener(v -> {
onItemClickedListener.onItemClick(position);
});
} else {
//Do whatever you want. Or nothing !!
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
@Override
public int getItemCount() {
return dataList == null ? 0 : dataList.size();
}
@Override
public int getItemViewType(int position) {
return dataList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
public T getItem(int position) {
return dataList.get(position);
}
public void setList(List<T> dataList) {
if (dataList != null) {
this.dataList.addAll(dataList);
notifyDataSetChanged();
}
}
public void addNullData() {
dataList.add(null);
notifyItemInserted(dataList.size()-1);
}
public void removeNull() {
if (isLoading) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size());
}
}
public void setLoaded() {
isLoading = false;
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
public CustomViewHolder(@NonNull View itemView) {
super(itemView);
}
}
public class DataViewHolder extends CustomViewHolder {
ImageView poster;
TextView title;
TextView year;
View container;
public DataViewHolder(@NonNull View itemView) {
super(itemView);
poster = itemView.findViewById(R.id.poster);
title = itemView.findViewById(R.id.title);
year = itemView.findViewById(R.id.year);
container = itemView.findViewById(R.id.container);
}
}
public class LoadingViewHolder extends CustomViewHolder {
public ProgressBar progressBar;
public LoadingViewHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progressbar);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:clickable="true"
android:focusable="true"
android:padding="8dp">
<ImageView
android:id="@+id/poster"
android:layout_width="@dimen/posterWidth"
android:layout_height="@dimen/posterHeight"
android:adjustViewBounds="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="movie title"
android:textAppearance="@android:style/TextAppearance.Medium" />
<TextView
android:id="@+id/year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1958" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment