android - progressbar - Ponga una barra de progreso indeterminada como pie de página en una cuadrícula RecyclerView
progressbar android circle (5)
Aquí hay una pequeña modificación a la respuesta de @Vilen Melkumyan en el
RecyclerView.Adapter
que funcionó mejor para mí.
Y puede usar su
EndlessRecyclerOnScrollListener
de la forma que desee para cargar los datos, también habilitando o deshabilitando el pie de página en cualquier momento.
PD:
Funcionó con
GridLayoutManager
.
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_ITEM = 1;
private final int VIEW_TYPE_PROGRESSBAR = 0;
private boolean isFooterEnabled = true;
private List<String> items;
public static class TextViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public TextViewHolder(View v) {
super(v);
mTextView = (TextView)v.findViewById(android.R.id.text1);
}
}
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar)v.findViewById(R.id.progressBar);
}
}
public MyRecyclerViewAdapter(List<String> myDataset) {
items = myDataset;
}
@Override
public int getItemCount() {
return (isFooterEnabled) ? items.size() + 1 : items.size();
}
@Override
public int getItemViewType(int position) {
return (isFooterEnabled && position >= items.size() ) ? VIEW_TYPE_PROGRESSBAR : VIEW_TYPE_ITEM;
}
/**
* Enable or disable footer (Default is true)
*
* @param isEnabled boolean to turn on or off footer.
*/
public void enableFooter(boolean isEnabled){
this.isFooterEnabled = isEnabled;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
if(viewType== VIEW_TYPE_ITEM) {
View v = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
vh = new TextViewHolder(v);
}else {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.progressbar, parent, false);
vh = new ProgressViewHolder(v);
}
return vh;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof ProgressViewHolder){
((ProgressViewHolder)holder).progressBar.setIndeterminate(true);
} else if(items.size() > 0 && position < items.size()) {
((TextViewHolder)holder).mTextView.setText(items.get(position));
}
}
}
Mis 2 centavos, paz !!
¿Cómo obtener un indicador circular indeterminado para "Desplazarse hacia arriba para cargar más" en una cuadrícula RecycleView?
El patrón se describe allí: http://www.google.com/design/spec/components/progress-activity.html#progress-activity-behavior en "Cargas en dos fases" y "Ejemplo 2: desplazarse hacia arriba para cargar más "videos de ejemplo.
Estoy tratando de lograr esto usando el nuevo RecyclerView, pero no puedo encontrar una forma "no muy hack" de hacerlo, en primer lugar porque no hay una manera de agregar un pie de página que cubra una fila completa en la cuadrícula . ¿Alguna sugerencia?
Es muy simple hacer eso.
La solución es usar el mismo enfoque del
LinearLayoutManager
con un
GridLayoutManager
y luego usar el método
setSpanSizeLookup
en el
LayoutManager
esta manera:
mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
switch(myAdapter.getItemViewType(position)){
case MyAdapter.VIEW_TYPES.Product:
return 1;
case MyAdapter.VIEW_TYPES.Progress:
return 2; //number of columns of the grid
default:
return -1;
}
}
});
Esto hará que el elemento cubra automáticamente una fila completa de la cuadrícula (si la fila no está totalmente vacía, este elemento pasará a la siguiente fila).
Mira mi solución en https://github.com/ramirodo/endless-recycler-view-adapter o https://bintray.com/ramiro/android/endless-recycler-view-adapter . Hay un ejemplo allí y también los pasos para configurar la biblioteca en su proyecto.
Solo necesita extender su adaptador de vista de reciclador implementando los métodos requeridos. También puede configurar el diseño del pie de página de progreso.
Puede simplificar la respuesta de Bronx insertando el código dentro de un adaptador.
public class ArticleGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_ITEM = 0;
private final int VIEW_LOADING = 1;
private Context mContext;
private List<Article> mArticles = new ArrayList<>();
private RecyclerView mRecyclerView;
private GridLayoutManager mManager;
public ArticleGridAdapter(Context context, List<Article> articles, RecyclerView recyclerView) {
this.mContext = context;
this.mArticles = articles;
this.mRecyclerView = recyclerView;
this.mManager = (GridLayoutManager) recyclerView.getLayoutManager();
mManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return getItemViewType(position) == VIEW_LOADING ? mManager.getSpanCount() : 1;
}
});
}
}
Tenga en cuenta que la solución a continuación tiene algunos problemas y limitaciones potenciales, para una solución revisada, marque esta casilla Agregar elementos a Endless Scroll RecyclerView con ProgressBar en la parte inferior
Esta es la solución que se me ocurrió recientemente: la idea es tener RecyclerView con 2 tipos de elementos, uno es nuestros elementos habituales, el segundo es la barra de progreso, luego debemos escuchar el evento de desplazamiento y decidir si vamos a cargar más y mostrar la barra de progreso o no . Entonces, desde la idea hasta el código de ejemplo
progress_item.xml
<?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="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:indeterminate="true"
style="@android:style/Widget.Holo.ProgressBar"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ring="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
EndlessRecyclerOnScrollListener.java
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
private int visibleThreshold = 1; // The minimum amount of items to have below your current scroll position before loading more.
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
private LinearLayoutManager mLinearLayoutManager;
public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal+1) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
current_page++;
onLoadMore(current_page);
loading = true;
}
}
public abstract void onLoadMore(int current_page);
}
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
private List<String> mDataset;
public static class TextViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public TextViewHolder(View v) {
super(v);
mTextView = (TextView)v.findViewById(android.R.id.text1);
}
}
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (ProgressBar)v.findViewById(R.id.progressBar);
}
}
public MyAdapter(List<String> myDataset) {
mDataset = myDataset;
}
@Override
public int getItemViewType(int position) {
return mDataset.get(position)!=null? VIEW_ITEM: VIEW_PROG;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
if(viewType==VIEW_ITEM) {
View v = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
vh = new TextViewHolder(v);
}else {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.progress_item, parent, false);
vh = new ProgressViewHolder(v);
}
return vh;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof TextViewHolder){
((TextViewHolder)holder).mTextView.setText(mDataset.get(position));
}else{
((ProgressViewHolder)holder).progressBar.setIndeterminate(true);
}
}
@Override
public int getItemCount() {
return mDataset.size();
}
}
y finalmente MainActivity.java
package virtoos.com.testapps;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private MyAdapter mAdapter;
private final List<String> myDataset = new ArrayList<>();
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
addItems(20);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
//mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
@Override
public void onLoadMore(int current_page) {
//add progress item
myDataset.add(null);
mAdapter.notifyItemInserted(myDataset.size());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//remove progress item
myDataset.remove(myDataset.size() - 1);
mAdapter.notifyItemRemoved(myDataset.size());
//add items one by one
for (int i = 0; i < 15; i++) {
myDataset.add("Item"+(myDataset.size()+1));
mAdapter.notifyItemInserted(myDataset.size());
}
//or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
}
}, 2000);
System.out.println("load");
}
});
}
}