I have a problem with an arraylist in Android Studio

0

I'm something new on Android and I'm doing an app where a list of data taken from firebase is used, which I want to show in a recyclerView and it does not show me directly, but when debugging I look for the error and with certain steps it shows me the list but with the app encouraged, maybe the error is in the adapter or when downloading the info from the database. This is the code where you do not show me the list:

FirebaseFirestore db = FirebaseFirestore.getInstance();
private RecyclerView recyclerView;
private RecyclerViewAdapter adapter;
private RecyclerView.LayoutManager manager;
FirebaseAuth mAuth;

ArrayList<Item> listaItems = new ArrayList<>();
//Aquí declaro mi adaptador y le doy la lista
adapter = new RecyclerViewAdapter(this,getListaItems());
//Método que obtiene la lista de objetos
public ArrayList<Item> getListaItems()
{
    db.collection("Historias")
            .get()
//Al debuguear, se detiene en esta linea y salta hasta el return, dando como resultado un 0 cuando se recibe en el adaptador.
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            Map<String, Object> historias = new HashMap<>();
                            historias = document.getData();
                            String titulo = (String)historias.get("Titulo");
                            String contenido = (String)historias.get("Historia");
                            String usuario = (String)historias.get("Usuario");

                            listaItems.add(
                                    new Item(
                                            titulo,
                                            contenido,
                                            usuario
                                    )
                            );
                        }
                    } else {
                        Toast.makeText(historias.this, "No se pudo actualizar las historias porque... "+task.getException(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
    return listaItems;
}

Adapter class:

public class RecyclerViewAdapter extends RecyclerView.Adapter{
private Context context;
private ArrayList<Item> listaItem;
//Al recibir el Array listaItem aquí me da cero
public RecyclerViewAdapter(Context context, ArrayList<Item> listaItem) {
    this.context = context;
    this.listaItem = listaItem;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder( ViewGroup viewGroup, int i) {
    View contentView = LayoutInflater.from(context).inflate(R.layout.layout_item_lista, null);
    System.out.println("CREATE VIEW HOLDER : " + i);
    return new Holder(contentView);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
    Item item = listaItem.get(i);
    Holder holder = (Holder) viewHolder;
    holder.titulo.setText(item.getTitulo());
    holder.historia.setText(item.getHistoria());
    holder.usuario.setText(item.getUsuario());
}

@Override
public int getItemCount() { return listaItem.size();}

public class Holder extends RecyclerView.ViewHolder {

    private TextView titulo, usuario, historia;

    public Holder(View v) {
        super(v);

        titulo = v.findViewById(R.id.ilTitulo);
        historia = v.findViewById(R.id.ilHistoria);
        usuario = v.findViewById(R.id.ilUsuario);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Item item = new Item(

                        titulo.getText().toString(),
                        historia.getText().toString(),
                        usuario.getText().toString()

                );
                Toast.makeText(
                        context,
                        item.getTitulo() + "\n" +
                                item.getHistoria() + "\n" +
                                item.getUsuario(),
                        Toast.LENGTH_SHORT
                ).show();
            }
        });
    }
}
}

I hope you can help me figure out why he does not show it to me correctly.

    
asked by Erick Ivan Vizcarra Hernandez 26.11.2018 в 09:38
source

1 answer

0

friend I leave you an explanation so that you understand the problem. But you can decipher why it does not work, in the week I empty myself and I'll give you an example. Your getListaItems method returns the empty list because you are calling a firebase request that is running asynchronously. That is, you will place the order to firebase and only when the data is (or has failed) is going to run onComplete and by then you will have returned the list without anything (that's why the debugger jumps to that line and in the adapter you say that you have zero elements, I'm going with that you can not return a value from a call to firebase, you can in the same onComplete complete the list as you already do and notify the adapter that elements were added. The rest should walk.

Summing up: getListItems should return void and then the for in onComplete notifies your adapter Use the debugger with a breakpoint already inside the onComplete to see if it is executed and if you raise the values well. adapter = new RecyclerViewAdapter (this, getListaItems ()); // In this line the function changes by the listItems attribute.

I hope it will help you, after I give you a clearer example, if you did not understand me!

Here is the complete example

First we have the RecyclerView

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private static final String TAG = ItemAdapter.class.getName();
private ArrayList<Item> items;
private OnItemClickListener mItemClickListener;
private Context context;



public ItemAdapter(Context context) {
    this.context = context;
    items= new ArrayList<>();

}

public ItemAdapter(Context context, ArrayList<Item> items) {
    this.context = context;
    this.items= items;
}

public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(context).inflate(R.layout.row, parent, false);
    return new ItemAdapter.ViewHolder(v);
}

@Override
public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
    try {
          Item item = items.get(position);
          holder.titulo.setText(item.getTitulo());
          holder.historia.setText(item.getHistoria());
          holder.usuario.setText(item.getUsuario());

    } catch (NullPointerException ex) {
        Log.e(TAG, "error al cargar la lista. Datos incorrectos: " + ex.getMessage());
    }

}

@Override
public int getItemCount() {
    return items.size();
}



public void setOnItemClickListener(onItemClickListener mItemClickListener) {
    this.mItemClickListener = mItemClickListener;
}

public interface OnItemClickListener {
    void onItemClicked(Item item);

}

public class ViewHolder extends RecyclerView.ViewHolder {
    private TextView titulo, usuario, historia;

    public ViewHolder(View itemView) {
        super(itemView);
        titulo = v.findViewById(R.id.ilTitulo);
        historia = v.findViewById(R.id.ilHistoria);
        usuario = v.findViewById(R.id.ilUsuario);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mItemClickListener != null){
                    mItemClickListener.onItemClicked(items.get(getAdapterPosition()));
                }
            }
        });

    }
}

}

// make sure you create an interface to capture the click on the item and return the item so you do not have to show it directly from the Adapter and you can do what you want from the outside.

The main activity where we want to show the list

public class MainActivity extends Activity {
   private ItemAdapter mAdapterItem;
   private ArrayList<Item> items = new ArrayList<>();
   @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mAdapterItem= new ItemAdapter(getApplicationContext(), items);
    RecyclerView items= findViewById(R.id.items_recyclerview);
    items.setLayoutManager(new 
    LinearLayoutManager(getApplicationContext()));
    items.setAdapter(mAdapterItem);
            mAdapterItem.setOnItemClickListener(new ItemAdapter.OnItemClickListener() {
        @Override
        public void onItemClicked(Item item) {
           // hace lo que quieras con tu item seleccionado
    });
}

public void readListaItems()
{
  db.collection("Historias")
        .get()
   //Al debuguear, se detiene en esta linea y salta hasta el return, dando como resultado un 0 cuando se recibe en el adaptador.
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        Map<String, Object> historias = new HashMap<>();
                        historias = document.getData();
                        String titulo = (String)historias.get("Titulo");
                        String contenido = (String)historias.get("Historia");
                        String usuario = (String)historias.get("Usuario");

                        items.add(
                                new Item(
                                        titulo,
                                        contenido,
                                        usuario
                                )
                        );
                    }
                    mAdapterItem.notifyDataSetChanged(); //le avisamos al adapter que tiene nuevos elementos
                } else {
                    Toast.makeText(historias.this, "No se pudo actualizar las historias porque... "+task.getException(), Toast.LENGTH_SHORT).show();
                }
            }
        });

}

I hope I do not forget anything, but with those two classes I should walk!

    
answered by 27.11.2018 в 04:01