ListView adds duplicates of itself when changing the mode to light/dark

Issue

I have a problem with my android app for making notes. When I change mode (in app) from default to dark or light, the list duplicate itself. I have a custom adapter for ListView:

public View getView(int position, View listView, ViewGroup parent) {

    View v = listView;
    TextView tvTitle;
    TextView tvContent;

    Note n = noteList.get(position);
    Set<String> folders = n.getFolders();
    Set<String> foldersForChips = new HashSet<>(folders);
    foldersForChips.remove("Notes");
    foldersForChips.remove("All Notes");

    NoteHolder holder = new NoteHolder();

    if (listView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.row_layout, null);

        // view of the labels of the note ------------------------------------------------------
        holder.foldersChipGroup = (ChipGroup) v.findViewById(R.id.labels_of_note);
        holder.foldersChipGroup.setChipSpacingHorizontal(2);
        holder.foldersChipGroup.setClickable(false);
        holder.foldersChipGroup.setFocusable(false);
        for (String folder : foldersForChips) {
            Chip folderChip = new Chip(context);
            folderChip.setText(folder);
            folderChip.setTextSize(8);
            folderChip.setEnsureMinTouchTargetSize(false);
            folderChip.setHeight(40);
            folderChip.setChipMinHeight(10);
            folderChip.setBackgroundColor(Color.TRANSPARENT);
            folderChip.setChipBackgroundColor(null);

            ChipDrawable chipFolderDrawable = ChipDrawable.createFromAttributes(context, null,0, R.style.Widget_App_Chip);
            folderChip.setChipDrawable(chipFolderDrawable);

            holder.foldersChipGroup.addView(folderChip);
        }

        tvTitle = (TextView) v.findViewById(R.id.title);
        tvContent = (TextView) v.findViewById(R.id.content);

        holder.titleView = tvTitle;
        holder.contentView = tvContent;

        v.setTag(holder);
    } else {
        holder = (NoteHolder) v.getTag();
    }

    // view of the title and content of the note -----------------------------------------------
    if (n.getTitle() == "" || n.getTitle().isEmpty() || n.getTitle() == null ) {
        holder.contentView.setVisibility(View.VISIBLE);
        holder.contentView.setText(n.getContent());
        holder.contentView.setPadding(20,0,20, 0);
    } else if (n.getContent() == "" || n.getContent().isEmpty() || n.getContent() == null){
        holder.titleView.setVisibility(View.VISIBLE);
        holder.titleView.setText(n.getTitle());
        holder.titleView.setPadding(20,0,20, 0);
    } else {
        holder.titleView.setVisibility(View.VISIBLE);
        holder.titleView.setText(n.getTitle());
        holder.titleView.setPadding(20,0,20, 0);
        holder.contentView.setVisibility(View.VISIBLE);
        holder.contentView.setText(n.getContent());
        holder.contentView.setPadding(20,0,20, 0);
    }

    // background color ------------------------------------------------------------------------
    holder.cardView = v.findViewById(R.id.cardView);
    if (getItem(position).getBackgroundColor() != null) {
        holder.cardView.setCardBackgroundColor(Color.parseColor(getItem(position).getBackgroundColor()));
    }

    return v;
}

the button which change the mode in MainActivity.java:

FloatingActionButton fabLight = findViewById(R.id.light);
fabLight.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        themeChange.setVisibility(View.VISIBLE);

        SharedPreferences settingsPreferences = getApplicationContext().getSharedPreferences("com.example.settings", Context.MODE_PRIVATE);
        settingsPreferences.edit().putInt("Mode", AppCompatDelegate.MODE_NIGHT_NO).apply();

        listView.refreshDrawableState();
        noteAdapter.notifyDataSetChanged();
        //listView.setAdapter(noteAdapter);
    }
});

I found similar problem: ListView Added Duplicate item in list when screen orientation changes, but unfortunaltely the answers does not help me – I do not know how to implement them. I am new with android and I will be grateful for some guidance.

I tried refreshDrawableState() and setAdapter(noteAdapter) on my listView and notifyDataSetChanged() on adapter but it does not help. It is probable that I implement getView or my list in it wrong but I do not know how to improve that.
Thank you in advance for all help.

In case – all files are in my GitHub repository:
https://github.com/wmaterkowska/MyNotes_app.git

Solution

Cześć, metoda onCreate() jest wywoływana przy pierwszym uruchomieniu aktywności, ale też po zmianie konfiguracji ekranu – orientacji albo właśnie motywu (no i kilu innych sytuacji) Nie ma gwarancji że zostanie wywołana tylko raz dlatego jeżeli tworzysz w niej listę, musisz ją najpierw wyczyścić, inaczej lista będzie się podwajać zawsze gdy metoda onCreate jest wywoływana.

notesToShow.clear(); //Dodaj tą linikę

for (Note note : allNotes) {
        if (note.getFolders().contains(folder) && !note.getFolders().contains("Recycle Bin")) {
            notesToShow.add(note);
        }
    }

Mam nadzieję, że pomogłem :))

Answered By – Jan Rozenbajgier

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *