简体   繁体   中英

RecyclerView Items Duplicating when navigating through different Fragments, arraylist.clear() doesn´t work

This is my first post here. I´m having trouble with a RecyclerView which I´m using into a fragment. I have two different fragments for a BottomNavigationMenu and the items duplicate everytime I get back to the fragment where the RecyclerView is in. I have tried using arraylist.clear(); as it is been suggested many times here but it doesn´t work. I have used the exact same code before using TabLayout with fragments instead of BottomNavigationMenu and it worked fine. the items didn´t duplicate at all.., I´m making a music library for an audio streaming app and I´m using realtime firebase to print the information for the RecyclerView onto the screen: if I use; if (audioFileArrayList == null) { loadData(). } it fixes the issue beacuse this way it doesn´t print the information twice but I don´t think this is a proper solution to this problem. It seems as if everytime I go back to the RecyclerView fragment the view doesn´t refresh but instead it prints everything again and again at the bottom...

This is the MainActivity:

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;
    BottomNavigationView bottomNavigationView;

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

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
        getSupportActionBar().hide(); //escondemos la action bar

        bottomNavigationView = binding.bottomNavigationID;
        getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_id, new BibliotecaFragment()).commit();

        bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {

                Fragment fragmentSeleccionado = null;

                switch (item.getItemId()) {
                    case R.id.biblioteca_ID:
                        fragmentSeleccionado = new BibliotecaFragment();
                        break;
                    case R.id.playlists_ID:
                        fragmentSeleccionado = new PlayListsFragment();
                        break;
                }
                getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_id, fragmentSeleccionado).commit();
                return true;
            }
        });
    }
}

This is the fragment for the library, as I said before if I use

if (audioFileArrayList == null) {
                loadData();
            }

it stops it from printing it twice.

public class BibliotecaFragment extends Fragment {

FragmentBibliotecaBinding binding;
RecyclerView recyclerView;
AudioFileAdapter audioFileAdapter;
static ArrayList<AudioFile> audioFileArrayList;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    binding = FragmentBibliotecaBinding.inflate(getLayoutInflater());

    recyclerView = binding.BibliotecaFragmentRecyclerViewID;
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager manager = new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false);
    recyclerView.setLayoutManager(manager);
    audioFileAdapter = new AudioFileAdapter(getContext());
    recyclerView.setAdapter(audioFileAdapter);


    loadData();
    
    return binding.getRoot();
}

public void loadData() {

    DatabaseReference dbr = FirebaseDatabase.getInstance().getReference();

    dbr.child("biblioteca").addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {

            audioFileArrayList = new ArrayList<>();
            for (DataSnapshot data : snapshot.getChildren()) {

                AudioFile audioFile = data.getValue(AudioFile.class);
                audioFileArrayList.add(audioFile);
            }
            audioFileAdapter.setItems(audioFileArrayList);
            audioFileAdapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });
}

}

This is my adapter:

public class AudioFileAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    static ArrayList<AudioFile> audioFileList = new ArrayList<>();

    public AudioFileAdapter(Context ctx) {
        this.context = ctx;
    }

    public void setItems(ArrayList<AudioFile> audioFile) {
        audioFileList.addAll(audioFile);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.audio_item, parent, false);
        return new AudioFileViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") int position) {

        AudioFileViewHolder audioFileViewHolder = (AudioFileViewHolder) holder;
        AudioFile audioFile = audioFileList.get(position);

        audioFileViewHolder.txtArtist.setText(audioFile.getArtist());
        audioFileViewHolder.txtTitle.setText(audioFile.getTitle());
        Glide.with(context).load(audioFile.getImgURL()).into(audioFileViewHolder.imageViewPicture);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = new Bundle();
                bundle.putInt("posicion", position);
                Intent intent = new Intent(context, Reproductor.class);
                intent.putExtras(bundle);
                context.startActivity(intent);
            }
        });

        ((AudioFileViewHolder) holder).imageViewMenu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                PopupMenu popupMenu = new PopupMenu(context, view);
                popupMenu.getMenuInflater().inflate(R.menu.audio_item_popup_menu, popupMenu.getMenu());
                popupMenu.show();

                popupMenu.setOnMenuItemClickListener((menuItem) -> {

                    switch (menuItem.getItemId()) {

                        case R.id.agregar_a_lista_ID: {

                            break;
                        }
                        case R.id.eliminar_de_biblioteca_ID: {
                            eliminar(position);
                            break;
                        }
                    }
                    return true;
                });
            }
        });
    }

    public void eliminar(int position) {

        String id = audioFileList.get(position).getId();

        DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
        Query delete = databaseReference.child("biblioteca").orderByChild("id").equalTo(id);

        delete.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                audioFileList.clear(); // importante limpiar la lista cada vez que se elimina un item para que no se dupliquen en la parte de abajo...
                for (DataSnapshot data : dataSnapshot.getChildren()) {
                    data.getRef().removeValue();
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
    }

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

    public interface ItemClickListener { //interfaz listener para RyclerView
        void onItemClick(AudioFile audioFile);
    }
}

My ViewHolder:

public class AudioFileViewHolder extends RecyclerView.ViewHolder {

    public TextView txtArtist, txtTitle;
    public ImageView imageViewPicture, imageViewMenu;

    public AudioFileViewHolder(@NonNull View itemView) {
        super(itemView);
        txtArtist = itemView.findViewById(R.id.artistID);
        txtTitle = itemView.findViewById(R.id.titleID);
        imageViewPicture = itemView.findViewById(R.id.item_imageID);
        imageViewMenu = itemView.findViewById(R.id.item_menu_ID);
    }
}

The XML code for MainActivity:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/frame_layout_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottom_navigation_ID" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation_ID"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom"
        app:menu="@menu/bottom_navigation_menu" />

</RelativeLayout>

The XML code for RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BibliotecaFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/BibliotecaFragmentRecyclerViewID"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#3C3A3A"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">

    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

And the XML code for each item into the RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/audio_itemID"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:background="@color/black"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/item_imageID"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/ic_launcher_foreground"
        android:padding="5dp" />

    <TextView
        android:id="@+id/artistID"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:gravity="center"
        android:text="Artist"
        android:textColor="@color/white" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:gravity="center"
        android:text="-"
        android:textColor="@color/white" />

    <TextView
        android:id="@+id/titleID"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:gravity="center"
        android:text="Title"
        android:textColor="@color/white" />

    <ImageView
        android:id="@+id/item_menu_ID"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginLeft="150dp"
        android:background="@drawable/ic_baseline_more_vert"
        android:padding="5dp"
        android:layout_gravity="center_vertical"/>

</LinearLayout>

Sorry for my english, I know it is not perfect, I hope you guys can help me with this.

Rubén.

I'm having the same problem and currently have no answer. You can try my method but only works if your recycler items are definite. Goto your viewholder class=>

@Override
public int getItemCount() {
    return num;
}

Where num is the number of your items in recyclerview.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM