Items repeating in a Recyclerview

Asked

Viewed 772 times

2

I have a fragment v4 which is managed by a SectionsPagerAdapter. In the fragment have a RecyclerView who has a Adapter personalized that receives a ArrayList which contains exactly 96 objects, representing the hours of the day, e.g.: position 0 = 00:00, 1 = 00:15, 2 = 00:30, 3 = 00:45, 4 = 01:00, and so on until 96 = 23:45. Besides the hour itself, he also has a field nome and another procedimentos. These fields will only be filled in if you have someone scheduled for the time, otherwise they are "".

The problem is, he’s scrambling everything when it comes to assembling the Adapter! A schedule he repeats in several random places he has no scheduled nun... so I noticed on log, as does the scroll in recyclerView, she updates the adapter automatically... I think that’s what this bug... but I don’t know how to solve...

Note in the image below, should have appeared the value only at the position 01:45, but also appears at 00:30, detail that at this position of the ArrayList the field name is empty.

print da lista

I’m two days trying to find the problem but I couldn’t... it must be something silly that I’m not realizing =(

follows the codes:

Fragment

public class FragmentAgenda extends Fragment {
private static MVP.Presenter presenter;
private View rootView;
private AdapterHorarios adapterHorarios;

public static FragmentAgenda newInstance(int sectionNumber, String dataInicial) {
    FragmentAgenda fragment = new FragmentAgenda();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    args.putString(ARG_DATA_CONSULTA, dataInicial);
    fragment.setArguments(args);
    return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    this.rootView = inflater.inflate(R.layout.fragment_agenda, container, false);
    this.dad = (AgendaActivity) getContext();

    if (presenter == null)
        presenter = new Presenter();
    presenter.setView(this, getContext());
    presenter.retrieveAgendaDia(getArguments(), savedInstanceState);

    return rootView;
}

@Override
public void onStart() {
    super.onStart();

    initViews();
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getArguments().putParcelableArrayList(KEY_CONSULTAS, presenter.getConsultas());
    getArguments().putParcelableArrayList(KEY_HORARIOS, presenter.getHorarios());
}

private void initViews() {
    RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.containerHorario);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

    adapterHorarios = new AdapterHorarios(getActivity(), presenter.getHorarios(), presenter);
    recyclerView.setAdapter(adapterHorarios);
}

@Override
public void upRecyclerView() {
    adapterHorarios.notifyDataSetChanged();
}
}

Presenter

public class Presenter extends PresenterDad implements MVP.Presenter {
private MVP.Model model;
private MVP.View view;
private Context contexto;
private ArrayList<Consulta> consultas;
private ArrayList<Consulta> horarios;
private String mesAno;

public Presenter() {
    this.model = new Model(this);
    this.consultas = new ArrayList<>();
    this.horarios = new ArrayList<>();
}

@Override
public Context getContext() {
    return contexto;
}

@Override
public void setView(MVP.View view, Context context) {
    this.view = view;
    this.contexto = context;
}

@Override
public void retrieveAgendaDia(Bundle args, Bundle savedInstanceState) {
    String dia = String.valueOf(args.getInt(MVP.View.ARG_SECTION_NUMBER));
    mesAno = args.getString(MVP.View.ARG_DATA_CONSULTA);

    if (args.getParcelableArrayList(MVP.View.KEY_CONSULTAS) != null) {
        horarios = args.getParcelableArrayList(MVP.View.KEY_HORARIOS);
        consultas = args.getParcelableArrayList(MVP.View.KEY_CONSULTAS);
        String data = String.format(dia, mesAno);
        model.montarHorarios(horarios, consultas, data);
        return;
    }
    model.retrieveAgendaDia(consultas, dia, mesAno);
}

@Override
public ArrayList<Consulta> getHorarios() {
    return horarios;
}

@Override
public ArrayList<Consulta> getConsultas() {
    return consultas;
}

@Override
public void upRecyclerView() {
    view.upRecyclerView();
}
}

Model

public class Model implements MVP.Model {
private final MVP.Presenter presenter;
private final ConsultaCtrl consultaCtrl;

public Model(Presenter presenter) {
    this.presenter = presenter;
    this.consultaCtrl = new ConsultaDAO();
}

@Override
public void retrieveAgendaDia(final ArrayList<Consulta> consultas, final String dia, final String mesAno) {
    consultaCtrl.retriveList(consultas, dia, mesAno, new Callback() {
        @Override
        public void result(boolean b) {
            if (b) {
                String data = String.format(Locale.GERMAN, "%02d/%s", Integer.valueOf(dia), mesAno);
                montarHorarios(presenter.getHorarios(), consultas, data);
            }
        }
    });
}

@Override
public void montarHorarios(ArrayList<Consulta> horarios, ArrayList<Consulta> consultas, String dataConsulta) {
    if (horarios.size() < 96) {
        horarios.clear();
        int hora = 0, flagHora = 0;
        int minuto = -15;

        for (int id = 0; id <= 95; id++) {
            if ((flagHora - 4) == 0) {
                hora++;
                flagHora = 1;
            } else flagHora++;

            if (minuto >= 45) minuto = 0;
            else minuto += 15;

            String data = String.format("%s %s:%s",
                    dataConsulta,
                    String.format(Locale.GERMAN, "%02d", hora),
                    String.format(Locale.GERMAN, "%02d", minuto)
            );
            horarios.add(new Consulta(hora, minuto, data.replace("-", "/")));
        }

        for (Consulta c : consultas) {
            for (int i = 0; i < horarios.size(); i++) {
                if (horarios.get(i).getDataConsulta().equals(c.getDataConsulta())) {
                    horarios.set(i, c);
                    i = horarios.size();
                }
            }
        }
    }

    presenter.upRecyclerView();
}
}

Adapter

public class AdapterHorarios extends RecyclerView.Adapter<HorariosViewHolder> {
private ArrayList<Consulta> consultas;
private Context contexto;

public AdapterHorarios(Context contexto, ArrayList<Consulta> consultas, MVP.Presenter presenter) {
    this.consultas = consultas;
    this.presenter = presenter;
    this.contexto = contexto;
}

@Override
public HorariosViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater
            .from(parent.getContext())
            .inflate(R.layout.adapter_agenda, parent, false);
    return new HorariosViewHolder( view );
}

@Override
public void onBindViewHolder(HorariosViewHolder holder, final int position) {
    holder.setDados(consultas.get(position));
}

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

Holder

public class HorariosViewHolder extends RecyclerView.ViewHolder {
private TextView hora, nomePaciente, procedimentos;
private ImageView staus;

public HorariosViewHolder(View itemView) {
    super(itemView);

    staus = (ImageView) itemView.findViewById(R.id.check);
    nomePaciente = (TextView) itemView.findViewById(R.id.nomePaciente);
    procedimentos = (TextView) itemView.findViewById(R.id.procedimentos);
    hora = (TextView) itemView.findViewById(R.id.hora);
}

public void setDados(Consulta consulta){
    if (consulta.getNomePaciente() != null){
        staus.setImageResource(R.drawable.ic_radio_button_checked);
        nomePaciente.setText(consulta.getNomePaciente());
        procedimentos.setText(consulta.getDataConsulta());
    }
    hora.setText(Datas.formatHoraConsulta(consulta.getHoraConsulta(), consulta.getMinutoConsulta())); // retorna hora ex: "07:15"
}
}
  • In the method setDados(), of Horariosviewholder, the if shouldn’t have a else?

  • That’s exactly what it was... I missed Else. I found the problem at 4 o'clock this morning! Rsrs for some reason he was picking up trash from textViews. Putting Else and filling the blank fields solved the problem of repeating. But now another has appeared. Now when you slip into the neighboring pager, the same data repeats gives previous view, but Arraylist is different! I’m almost abandoned the Sectionspagera and use a Fragmentmanager even...

  • You’d better ask another question for this new problem. Enter the Sectionspagera pter code and how you’re doing the switch between Arraylist’s

  • Ok. I’m going to create another topic. Just one question, I can create a new question and put this topic as a link and say that the question is derived from this?

  • You can however put in it the code relevant to this problem.

1 answer

3


Recyclerview.Adapter implements the "View Holder" standard using the Recyclerview.Viewholder class using it in the methods onCreateViewHolder() and onBindViewHolder(), allowing a previously created view to be reused.

It is your responsibility, in the method onBindViewHolder(), return this populated view with the values corresponding to the relevant Recyclerview item.

The method being used for this purpose is the setDados() of Horariosviewholder.
However, it only updates the view when consulta.getNomePaciente() != null.
When this is not the case, the view is returns without change(only hora is updated), it has values of a previously used item.

It shall amend the method in such a way that the two situations are dealt with.

public void setDados(Consulta consulta){
    if (consulta.getNomePaciente() != null){
        staus.setImageResource(R.drawable.ic_radio_button_checked);
        nomePaciente.setText(consulta.getNomePaciente());
        procedimentos.setText(consulta.getDataConsulta());
    }else{
        staus.setImageResource(R.drawable.ic_radio_button_checked);//ou outra, não sei
        nomePaciente.setText("");
        procedimentos.setText("");
    }
    hora.setText(Datas.formatHoraConsulta(consulta.getHoraConsulta(), consulta.getMinutoConsulta())); // retorna hora ex: "07:15"
}
  • Thank you so much for clarifying why this happens... I didn’t know that viewHolder reused view already created previously. Now I understand the problem!

  • The intention of the answer was this, explain why, since in the comment there was no room for it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.