-1

I have a fragment that is suppose to display the results of my alert dialog in my RecyclerView. Every time I click the "ADD" in my dialog, it adds duplicated results to my RecyclerView. I've searched and searched but cannot seem to find what I am doing wrong. I've tried adding .clear(); but if I add that, nothing shows up in my RecyclerView at all. I've added in my adapter getItemId and getItemViewType to return position; but the items still get duplicated. I've added adapter.setData(model) followed by adapter.notifyDataSetChange(); and my RecyclerView still shows duplicated items. The app runs so I have no logcat to post. Thank you.

Screenshot: duplicate items

Model

public class SubjectsModel
{

    //private long id;
    private String mTitle;
    private String mTeacher;

    public String getmTitle()
    {
        return mTitle;
    }

    public void setmTitle(String title)
    {
        this.mTitle = title;
    }

    public String getmTeacher()
    {
        return mTeacher;
    }

    public void setmTeacher(String teacher)
    {
        this.mTeacher = teacher;
    }
}

Fragment

public class SubjectsFrag extends DialogFragment implements
        SubjectsEditor.OnAddSubjectListener
{
    private static final String TAG = SubjectsFrag.class.getSimpleName();

    @NonNull
    Context context;
    private EditText titleView, teacherView;
    private String sTitle, sTeacher;
    public EmptyRecyclerView recyclerView;
    public RecyclerView.LayoutManager layoutManager;
    public RecyclerSubAdapter recyclerSubAdapter;
    public ArrayList<SubjectsModel> subMod = new ArrayList<>();
    DbHelper helper;
    @BindView(R.id.main_root)
    ViewGroup root;

    public SubjectsFrag() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_subjects, container, false);

        FloatingActionButton fab = view.findViewById(R.id.fab_sub);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showDialog();
            }
        });

        helper = new DbHelper(getActivity());
        helper.getSubject();

        titleView = view.findViewById(R.id.edit_subject);
        teacherView = view.findViewById(R.id.edit_subject_teacher);

        View emptyView = view.findViewById(R.id.empty_subject_view);

        recyclerView = view.findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);


        recyclerSubAdapter = new RecyclerSubAdapter(getContext(), subMod);

        layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(recyclerSubAdapter);

        return view;
    }

    @Override
    public void OnAddSubjectSubmit(String title, String teacher)
    {
        SubjectsModel model = new SubjectsModel();

        model.setmTitle(title);
        model.setmTeacher(teacher);

        //subMod.clear();
        subMod.add(model);
        recyclerSubAdapter.setData(subMod);

        recyclerSubAdapter.notifyDataSetChanged();

    }

    private void showDialog()
    {
        SubjectsEditor addSubjectDialog = new SubjectsEditor();
        addSubjectDialog.setTargetFragment(this, 0);
        addSubjectDialog.show(getFragmentManager(), null);

    }
}

Adapter

public class RecyclerSubAdapter extends RecyclerView.Adapter<RecyclerSubAdapter.ViewHolder>
{
    private static final String TAG = RecyclerSubAdapter.class.getSimpleName();

    public List<SubjectsModel> subMod = new ArrayList<>();
    private OnItemClicked onClick;
    static ClickListener clickListener;
    Context context;
    DbHelper helper;

    public RecyclerSubAdapter(Context context, ArrayList<SubjectsModel> subMod)
    {
        this.context = context;
        this.subMod = subMod;
        this.helper = new DbHelper(context);
    }

    @NonNull
    @Override
    public RecyclerSubAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
    {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.subjects_item_list, parent, false);

        ViewHolder viewHolder = new ViewHolder(view);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final RecyclerSubAdapter.ViewHolder holder, final int position)
    {
       SubjectsModel currentSubject = subMod.get(position);

        holder.titleView.setText(currentSubject.getmTitle());
        holder.teacher.setText(currentSubject.getmTeacher());

        //helper.addClass(subMod.get(position));
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements
            View.OnClickListener
    {
        TextView titleView;
        TextView teacher;
        CardView cardView;

        public ViewHolder(View itemView)
        {
            super(itemView);
            titleView = itemView.findViewById(R.id.subject_subject);
            teacher = itemView.findViewById(R.id.subject_teacher_text);
            cardView = itemView.findViewById(R.id.card_view);

        }

        @Override
        public void onClick(View view)
        {
            if (clickListener != null)
            {
            }
        }
    }

    @Override
    public int getItemCount()
    {
        if (subMod == null)
        {
            Log.d(TAG, "sub is null");
        }
        return subMod.size();
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    @Override
    public int getItemViewType(int position)
    {
        return position;
    }

    public interface OnItemClicked
    {
        void onItemClick(int position);
    }

    public void setOnClick(OnItemClicked onClick)
    {
        this.onClick = onClick;
    }

    public void setClickListener(ClickListener clicked)
    {
        RecyclerSubAdapter.clickListener = clicked;
    }

    public interface ClickListener
    {
        void itemClicked(SubjectsModel model, int position);
    }

    public void setData(ArrayList<SubjectsModel> data)
    {
            this.subMod = data;
            //this.subMod.clear();
            this.subMod.addAll(data);
            notifyDataSetChanged();
    }
}

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main_root">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.example.ashleighwilson.schoolscheduler.adapter.EmptyRecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="60dp"/>

    </LinearLayout>

   <RelativeLayout
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerInParent="true">

    <TextView
        android:id="@+id/empty_subject_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:visibility="gone"
        android:text="@string/no_subjects"/>

   </RelativeLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_sub"
        style="@style/FAB" />

</RelativeLayout>
Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • let the `RecyclerView.Adapter` implement `Filterable`; then you can add all at once and are still able to only return a selection of items. – Martin Zeitler Aug 16 '18 at 18:38
  • Ok I'll try that as soon as I get back to my house from fixing my computer. Got the mac beachball of death. Thanx for the advice! – NaturallyAsh Aug 16 '18 at 18:55
  • here it is explained in detail: https://stackoverflow.com/a/30429439/549372 – Martin Zeitler Aug 16 '18 at 18:57
  • that is an overwhelming post but I get the gist and I will do more research on filters. I am self taught and had never heard of filters so thank you for this! – NaturallyAsh Aug 17 '18 at 00:12

2 Answers2

0

In OnAddSubjectSubmit() you call subMod.add(model);
and then you call recyclerSubAdapter.setData(subMod); which in turn calls this.subMod.addAll(data);.
Check it yourself. I believe it's there where you add the new item twice.
Suggestion: comment out recyclerSubAdapter.setData(subMod); from OnAddSubjectSubmit().

  • yes that seems to be the problem with my duplication, although now I have to press "ADD" on my dialog twice before it gets added to my RV. I first removed sub.add(model) and nothing was added at all. So I instead removed this.subMod.addAll(data) but now I have to submit the data twice before it shows up. Any suggestions? – NaturallyAsh Aug 16 '18 at 18:14
  • its as if the data isn't being set right aways to my RV – NaturallyAsh Aug 16 '18 at 18:14
  • Ok I'll try that in about an hour. Funny thing, I'm at the Mac store now cause I might need a new SATA cable so I'll try that when I get it fixed. Thanx for the advice. – NaturallyAsh Aug 16 '18 at 18:53
  • No that didn't fix my delay problem. But I will accept your answer since you did solve my duplication problem. Thank you. – NaturallyAsh Aug 16 '18 at 23:53
0
       this.subMod = data;

       this.subMod.addAll(data);

You initilize subMod by assigning data to it, and later you add data again: this.subMod.addAll(data);

Nimdokai
  • 787
  • 1
  • 6
  • 18