studio progressbar progreso personalizar ejemplo custom cargando barra bar android footer android-recyclerview

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).



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"); } }); } }