Dodać nowy element do programu recyklingowego?

115

Nadal próbuję się rozejrzeć po recyklingu. Mam arraylistę, którego używam do zainicjowania widoku recyklera.

Jak mogę dodać nowe elementy do posta widoku recyklera, ustawiając adapter i menedżer układu?

private void initData() {
        mItems = new ArrayList<String>();
        for (int i = 0; i < ITEMS_COUNT; i++) {
            mItems.add("Item " + (i + 1));
        }
    }

    private void initRecyclerView() {
        mRecentRecyclerView = (RecyclerView) findViewById(R.id.recentrecyclerView);
        mRecentRecyclerView.setHasFixedSize(true);
        mRecentLayoutManager = new LinearLayoutManager(this);
        mRecentRecyclerView.setLayoutManager(mRecentLayoutManager);



        mAdapter = new RecyclerView.Adapter<CustomViewHolder>() {
            @Override
            public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.notice_snippet
                        , viewGroup, false);
                return new CustomViewHolder(view);
            }

            @Override
            public void onBindViewHolder(CustomViewHolder viewHolder, int i) {
                viewHolder.noticeSubject.setText(mItems.get(i));
            }

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

        };
        mRecentRecyclerView.setAdapter(mAdapter);

    private class CustomViewHolder extends RecyclerView.ViewHolder {

        private TextView noticeSubject;

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

            noticeSubject = (TextView) itemView.findViewById(R.id.notice_subject);
        }
    }

Więc w zasadzie po I initdata()i initRecyclerView()jak dodać nowy element do RecyclerView?

Shubham Kanodia
źródło
Możesz zobaczyć ten przykład w kodzie Github Happy !!!
Cabezas

Odpowiedzi:

272

Najpierw dodaj swój przedmiot do, mItemsa następnie użyj:

mAdapter.notifyItemInserted(mItems.size() - 1);

ta metoda jest lepsza niż użycie:

mAdapter.notifyDataSetChanged();

w wydajności.

Mostafa
źródło
11
Dobra odpowiedź. Oznacza to również, że nie zepsuje animacji
Ben Pearson
7
Należy to uznać za właściwą odpowiedź, druga przerywa animacje i jest mniej wydajna niż ta.
Massimo
27
Jestem tym, który odpowiedział na zaakceptowaną odpowiedź i myślę, że powinna to być zaakceptowana odpowiedź: D
Abdelrahman Elkady
2
@AJW yes. Indeks ostatniego elementu mItems to mItems.size () - 1.
Mostafa
2
Dzięki! Mam obrazy, które powinny być ładowane z Internetu w onBindViewHolder. Za każdym razem, gdy otrzymuję dane, muszę dołączyć do listy i wywołać notifyDataSetChanged (). Ale to spowodowało efekt migotania obrazu. Powyżej było właściwym rozwiązaniem, którego szukałem. Możesz także użyć mAdapter.notifyItemRangeInserted (mItems.size () - 1, new_array_of_items_to_be_added.size ());
Vignesh Bala
38

po prostu dodaj do struktury danych (mItems), a następnie powiadom adapter o zmianie zestawu danych

private void addItem(String item) {
  mItems.add(item);
  mAdapter.notifyDataSetChanged();
}

addItem("New Item");
Abdelrahman Elkady
źródło
2
A co, jeśli nie jest to ciąg, który chcę dodać, ale ViewGroup?
Igor Ganapolsky
1
@IgorGanapolsky Ja też mam te same wątpliwości. Czy znalazłeś na to jakieś rozwiązanie?
Sash_KP
ta sama wątpliwość również tutaj! jakaś pomoc?
Srujan Barai
5
@IgorGanapolsky Typ elementu zostanie określony przez adapter, więc może to być naprawdę dowolny obiekt. Pamiętaj jednak, że dodawany element ma być po prostu danymi. RecyclerView ma wbudowane funkcje do zawyżania i wiązania widoku, co się stanie, gdy powiadomiszDataSetChanged (). Możesz debugować onBindViewHolder, aby zobaczyć edytowany widok.
Chris,
1
@IgorGanapolsky ArrayList<T>Musiałbyś użyć typu obiektu, który chcesz dodać, np. ArrayList<ViewGroup>Zamiast ArrayList<String>. Następnie możesz po prostu zmienić typ argumentu z Stringna ViewGroup. (Przepraszam za necro).
Eric Reed
14

jeśli dodajesz wiele pozycji do listy, użyj tego:

mAdapter.notifyItemRangeInserted(startPosition, itemcount);

Powoduje to powiadomienie zarejestrowanych obserwatorów, że aktualnie odzwierciedlone pozycje itemCount zaczynające się od pozycji positionStart zostały nowo wstawione. Element znajdujący się wcześniej w pozycji positionStart i poza nią można teraz znaleźć, zaczynając od pozycji positinStart + itemCount

istniejący element w zbiorze danych jest nadal uważany za aktualny.

Nitin Anand
źródło