Why are RecyclerView rows being populated with same data?

152
July 24, 2019, at 5:30 PM

I'm trying to populate a RecyclerView using data stored in a ArrayList. When the RecyclerView loads each piece of data is repeted 4x in each row.

I've tried a whole variety of solutions I've found, but none seem to resolve the issue.

After some debugging the data in 'mData', appears to be correct, so that would lead me to believe that this issue is 'onBindViewHolder'?

Adapter

public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public EventsRecyclerViewAdapter(List<String> data) {
    this.mInflater = LayoutInflater.from(MainActivity.mainActivity);
    this.mData = data;
}
// inflates the row layout from xml when needed
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
    return new ViewHolder(view);
}
// binds the data to the TextView in each row
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.keyID.setText(mData.get(position));
    holder.lockID.setText(mData.get(position));
    holder.eventTime.setText(mData.get(position));
    holder.eventType.setText(mData.get(position));
}
// total number of rows
@Override
public int getItemCount() {
    return mData.size();
}

// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView keyID;
    TextView lockID;
    TextView eventTime;
    TextView eventType;
    ViewHolder(View itemView) {
        super(itemView);
        keyID = itemView.findViewById(R.id.keyIDTV);
        lockID = itemView.findViewById(R.id.lockIDTV);
        eventTime = itemView.findViewById(R.id.eventDateTV);
        eventType = itemView.findViewById(R.id.eventTypeTV);
        itemView.setOnClickListener(this);
    }
    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
    }
}


// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}

Fragment

 public class KeyEvents extends Fragment {

    public static KeyInfo newInstance() {
        KeyInfo fragment = new KeyInfo();
        return fragment;
    }
    EventsRecyclerViewAdapter adapter;
    ArrayList<String> eventsList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventsOperationHandler ev = new EventsOperationHandler();
        eventsList = new ArrayList<>();
        for (int i=0; i<ev.getEvents().size(); i++) {
            eventsList.add(ev.getEvents().get(i).get(0));
            eventsList.add(ev.getEvents().get(i).get(1));
            eventsList.add(ev.getEvents().get(i).get(2));
            eventsList.add(ev.getEvents().get(i).get(3));
        }
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_event_info, container, false);

        RecyclerView recyclerView = view.findViewById(R.id.rvEvents);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.mainActivity));
        adapter = new EventsRecyclerViewAdapter(eventsList);
        recyclerView.setAdapter(adapter);
        return view;
    }

}
Answer 1

In your 'onBindViewHolder' you are setting same data in every textView of yours

// binds the data to the TextView in each row
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.keyID.setText(mData.get(position));
    holder.lockID.setText(mData.get(position));
    holder.eventTime.setText(mData.get(position));
    holder.eventType.setText(mData.get(position));
}

Here you are setting mData.get(position) to every textView in the holder

A solution would be creating a Pojo class for your recyclerView

Create Pojo Event class

class Event{
    public String keyID;
    public String lockID;
    public String eventTime;
    public String eventType;
}

Create a list of 'Event' in your fragment

public class KeyEvents extends Fragment {

    public static KeyInfo newInstance() {
        KeyInfo fragment = new KeyInfo();
        return fragment;
    }
    EventsRecyclerViewAdapter adapter;
    ArrayList<Event> eventsList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventsOperationHandler ev = new EventsOperationHandler();
        eventsList = new ArrayList<>();
        for (int i=0; i<ev.getEvents().size(); i++) {
            Event event = new Event();
            event.keyID = ev.getEvents().get(i).get(0);
            event.lockID = ev.getEvents().get(i).get(1);
            event.eventTime = ev.getEvents().get(i).get(2);
            event.eventType = ev.getEvents().get(i).get(3);
            eventsList.add(event);
        }
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_event_info, container, false);

        RecyclerView recyclerView = view.findViewById(R.id.rvEvents);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.mainActivity));
        adapter = new EventsRecyclerViewAdapter(eventsList);
        recyclerView.setAdapter(adapter);
        return view;
    }

}

Modify your recyclerView to handle to 'Event' class

public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.ViewHolder> {
private List<Event> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public EventsRecyclerViewAdapter(List<Event> data) {
    this.mInflater = LayoutInflater.from(MainActivity.mainActivity);
    this.mData = data;
}
// inflates the row layout from xml when needed
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
    return new ViewHolder(view);
}
// binds the data to the TextView in each row
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Event event = mData.get(position);
    holder.keyID.setText(event.keyID);
    holder.lockID.setText(event.lockId);
    holder.eventTime.setText(event.eventTime);
    holder.eventType.setText(event.eventType);
}
// total number of rows
@Override
public int getItemCount() {
    return mData.size();
}

// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView keyID;
    TextView lockID;
    TextView eventTime;
    TextView eventType;
    ViewHolder(View itemView) {
        super(itemView);
        keyID = itemView.findViewById(R.id.keyIDTV);
        lockID = itemView.findViewById(R.id.lockIDTV);
        eventTime = itemView.findViewById(R.id.eventDateTV);
        eventType = itemView.findViewById(R.id.eventTypeTV);
        itemView.setOnClickListener(this);
    }
    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
    }
}


// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}

That's it, this should work perfectly.

READ ALSO
Which event/component allows side editing?

Which event/component allows side editing?

I'm developing an app in Android Studio and would like to use a component / event

114
Joi Validation : Conditionally validate one key based on the value of another key

Joi Validation : Conditionally validate one key based on the value of another key

I am trying to Joi validate one key depending on the value of another keyIn the following example ,I have tried to validate category_children based on has_sub_category's value

119
Problems with fetching div&#39;s ID

Problems with fetching div's ID

I have a problem with getting the div's ID from my applicationI have a JSP file, which generates a HTML

17
How can I change code background color when using nbconvert?

How can I change code background color when using nbconvert?

When converting Jupyter Notebook to html I am trying to change code background color using a Jinja template

12