webentwicklung-frage-antwort-db.com.de

Ich möchte, dass mein RecyclerView einige Elemente nicht recycelt

Ich verwende eine RecyclerView mit heterogenen Ansichten, wie in diesem Tutorial gezeigt .

Ich habe einige Elemente in dieser RecyclerView, die auch RecyclerViews sind. Zu schwer vorstellbar? Nehmen wir an, ich möchte das Play Store-Layout kopieren: Eine große RecyclerView mit vertikalem, linearem Layout und vielen Elementen: Einzelne Apps und Karussell von Apps.

Wenn das hinzuzufügende Element das Layout für eine einzelne App ist, wird ID 1 verwendet, und ich füge das Layout für ein einzelnes Element hinzu RecyclerView: Ein weiterer RecyclerView mit eigenem Adapter.

Das funktioniert sehr gut. Außer beim Scrollen der RecyclerView-Hauptansicht. Warum? Weil einige Ansichten zerstört werden, wenn sie nicht mehr sichtbar sind, und dann in der onBindViewHolder()-Methode neu erstellt werden. Warum hier? Weil der Adapter der RecyclerView-Hauptposition die Position X durchläuft und dann OnBindViewHolder() aufruft. Dieser erstellt dann einen neuen RecyclerView mit eigenem Adapter und ordnet diesen zu. Ich möchte diese Ansichten behalten, nur weil sie schwer sind, jedes Mal neu aufzublasen. 

Ist das möglich? Wenn ja, kannst du mir sagen wie?

15
Joaquin Iurchuk

Benutze das:

recyclerView.getRecycledViewPool().setMaxRecycledViews(TYPE_CAROUSEL, 0);

Dadurch wird keine Ansicht von viewType TYPE_CAROUSEL wiederverwendet. Wenn jedoch die Anzahl der Elemente dieses Typs sehr hoch ist, wird dadurch die Leistung erheblich beeinträchtigt, was möglicherweise sogar zu OOMEs führt

EDIT

Nachdem ich die Antwort von MML13 gelesen habe, denke ich, dass es für Sie funktionieren könnte. Sie machen sich Sorgen, dass Elemente Ihres Karussells erneut aufgeblasen werden, wenn diese Ansicht in der äußeren RecyclerView-Ansicht erneut eingebunden wird. Wenn alle diese Karussells vom gleichen Typ sind, d. H., Sie verwenden denselben Adapter, können Sie den Adapter im äußeren RecyclerView-ViewHolder belassen und einfach Daten austauschen und notifyDataSetChanged() oder notifyItemRangeChanged(...) bei erneutem Binden dieses Adapters aufrufen. Dadurch werden alle Karussellansichten und alle Ansichten innerhalb dieser Karussells wieder hergestellt.

49
Sourabh

Sie können auch unten in der onBindViewholder () - Methode des Adapters Code festlegen.

holder.setIsRecyclable(false);

Ich habe auf diesen Link Bezug genommen

http://aphoe.com/blog/prevent-androids-recyclerview-recycling-views/

13
Nancy Y

Weil einige Ansichten zerstört werden, wenn sie nicht mehr sichtbar sind und dann in der onBindViewHolder () -Methode neu erstellt.

Es ist nicht wahr, sie werden nicht erneut erstellt, sie binden sich einfach. Wenn Sie eine Sicht für Position X (in Schrott oder Recycling) haben, wird RecyclerView diese verwenden und erneut binden.

Ich möchte diese Ansichten behalten, nur weil sie schwer sind, jedes Mal neu aufzublasen.

Die Hauptvariante RecyclerView behält diese für Sie. Sie müssen nur die Adapterdaten Ihres zweiten RecyclerView ändern und notifyDataSetChanged aufrufen. Bewahren Sie Ihren zweiten RecyclerView-Adapter auch im viewHolder Ihres Haupt-RecyclerView auf.

8
user5703518

Sie können in Ihrem Adapter hinzufügen:

@Override
public void onBindViewHolder(final CommentViewHolder viewHolder, final int position) {
    viewHolder.setIsRecyclable(false);
}

Informiert den Recycler, ob dieser Artikel recycelt werden kann. Ansichten, die nicht recycelt werden können, werden nicht für andere Elemente verwendet, bis setIsRecyclable() später auf true gesetzt wird. Aufrufe von setIsRecyclable() sollten immer gepaart sein (ein Aufruf von setIsRecyclabe(false) sollte immer mit einem späteren Aufruf von setIsRecyclable(true) abgeglichen werden). Anrufpaare können verschachtelt sein, da der Status intern referenziert wird.

4

Stellen Sie die folgende Zeile in Ihrer Aktivität ein

recyclerView.getRecycledViewPool().setMaxRecycledViews(1,0);

set Below Code in der RecyclerViewAdapter-Klasse

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

Mein Code funktioniert für das Zurücksetzen der Benutzeroberfläche in recycleview.

public class BooleanViewHolder extends BaseViewHolder<ConfigItemBoolean> {
    private SwitchCompat configBoolean;

    BooleanViewHolder(View view) {
        super(view);
        configBoolean = view.findViewById(R.id.enable_config_boolean);
        configBoolean.setOnCheckedChangeListener((buttonView, isChecked) -> {
            ((ConfigItemBoolean) getItem(getAdapterPosition())).setValue(isChecked);
            DataSet.mConfigDataSet.getConfigItemBooleanMap().put(configPairList.get(getAdapterPosition()).first, ((ConfigItemBoolean) getItem(getAdapterPosition())));
        });
    }

    @Override
    void bind(ConfigItemBoolean item, String key) {
        configBoolean.setText(item.getDisplayName());
        configBoolean.setChecked(item.isValue());
    }

}
0
May Yamin Thant