Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Añadir elementos a Endless Scroll RecyclerView con ProgressBar en la parte inferior

Seguí la excelente respuesta de Vilen en SO: Poner una barra de progreso indeterminada como pie de página en una cuadrícula de RecyclerView sobre cómo implementar un scrollerview sin fin con ProgressBar.

Lo implementé yo mismo y funciona, pero me gustaría extender el ejemplo. Quiero agregar elementos adicionales en la parte superior del reciclerview, similar a cómo lo hace Facebook cuando agrega una nueva actualización de estado.

  • No se encontró recurso - Theme.AppCompat.Light.DarkActionBar
  • Documentación para estilos en recursos de Android
  • NullPointerException al llamar a getSupportActionBar () desde dentro de Fragment (ActionBarCompat)
  • IOS Google Analytics Dimensiones personalizadas
  • ¿Cuál es la diferencia entre `DialogInterface.dismiss ()` y `DialogInterface.cancel ()`?
  • Android: Girar animación volver a su estado real después de terminar la animación?
  • No he podido añadir elementos adicionales a la lista correctamente – aquí está mi código que he añadido al código de Vilen en su MainActivity:

    @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.add) { myDataset.add(0, "Newly added"); mRecyclerView.smoothScrollToPosition(0); mAdapter.notifyItemInserted(0); } return super.onOptionsItemSelected(item); } 

    Cuando hice clic en el botón "Añadir":

    Agregar un nuevo elemento

    Cuando me desplazo hacia abajo, consigo dos hilanderos en vez de uno:

    Desplácese hacia abajo

    Cuando los hilanderos terminan y se cargan los 5 ítems siguientes, el hilador todavía está allí:

    Después de spinner

    ¿Qué estoy haciendo mal?

  • Android: 2D. ¿OpenGl o android.graphics?
  • AVD permanece atascado en "Android está empezando"
  • Añadir espacio a la parte superior e inferior de GridView
  • Android: permite el retrato y el paisaje para las tabletas, pero el retrato de la fuerza en el teléfono?
  • Cómo reemplazar R.drawable. "SomeString"
  • Reutilización de objetos de vista de Android: impide que el tamaño antiguo se muestre cuando se vuelve a ver
  • 2 Solutions collect form web for “Añadir elementos a Endless Scroll RecyclerView con ProgressBar en la parte inferior”

    El problema es que cuando se agrega un nuevo elemento interno EndlessRecyclerOnScrollListener no sabe acerca de él y los contadores de ruptura. De hecho, la respuesta con EndlessRecyclerOnScrollListener tiene algunas limitaciones y posibles problemas, por ejemplo, si carga un elemento a la vez, no funcionará. Así que aquí está una versión mejorada.

    1. Deshazte de EndlessRecyclerOnScrollListener ya no lo necesitamos
    2. Cambie su adaptador a este que contiene listeners de desplazamiento

       public class MyAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private final int VIEW_ITEM = 1; private final int VIEW_PROG = 0; private List<T> mDataset; // The minimum amount of items to have below your current scroll position before loading more. private int visibleThreshold = 2; private int lastVisibleItem, totalItemCount; private boolean loading; private OnLoadMoreListener onLoadMoreListener; public MyAdapter(List<T> myDataSet, RecyclerView recyclerView) { mDataset = myDataSet; if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) { final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); totalItemCount = linearLayoutManager.getItemCount(); lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) { // End has been reached // Do something if (onLoadMoreListener != null) { onLoadMoreListener.onLoadMore(); } loading = true; } } }); } } @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).toString()); } else { ((ProgressViewHolder) holder).progressBar.setIndeterminate(true); } } public void setLoaded() { loading = false; } @Override public int getItemCount() { return mDataset.size(); } public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) { this.onLoadMoreListener = onLoadMoreListener; } public interface OnLoadMoreListener { void onLoadMore(); } 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); } } } 
    3. Cambiar código en la clase de actividad

       mAdapter = new MyAdapter<String>(myDataset, mRecyclerView); mRecyclerView.setAdapter(mAdapter); mAdapter.setOnLoadMoreListener(new MyAdapter.OnLoadMoreListener() { @Override public void onLoadMore() { //add progress item myDataset.add(null); mAdapter.notifyItemInserted(myDataset.size() - 1); 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()); } mAdapter.setLoaded(); //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged(); } }, 2000); System.out.println("load"); } }); 

    El resto permanece sin cambios, déjame saber si esto funciona para usted.

    Creo que lo averigüé.

    Olvidé llamar a notifyItemRangeChanged.

     @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.add) { myDataset.add(0, "Newly added"); mAdapter.notifyItemInserted(0); mAdapter.notifyItemRangeChanged(1, myDataset.size()); mRecyclerView.smoothScrollToPosition(0); } return super.onOptionsItemSelected(item); } 

    Una vez que lo agregue, el código funcionará, sin embargo, verá que después de que el hilandero termine de girar, el número de artículo no se incrementará correctamente.

    incremento

    Esto se debe a que el elemento "Recién agregado" en la parte superior cuenta como un elemento real (lo podemos llamar "Artículo 0"), y esto hace que el incremento de 1 como 21 se haya saltado, pero en realidad el número 21 se ha convertido en el elemento 0 En otras palabras, hay 21 ítems reales antes del ítem 22.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.