簡體   English   中英

Recycler View不保存視圖狀態

[英]Recycler View not saving state of Views

我正在使用Recycler視圖,其中我在適配器中使用LinearLayout。 單擊LinearLayout時,它隱藏了View,同樣再次點擊使其變為可見。 我的問題是Recycler視圖沒有持有Views的狀態,當我滾動時它再次刷新View再次改變狀態視圖的初始時間。

我的RecyclerView代碼以及我的適配器如下所示。

RecyclerView代碼:

 LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
  Menu_Detail_Adapter  searchabledapter = new Menu_Detail_Adapter(getActivity());
   RecyclerView mRecyclerView =(RecyclerView)view.findViewById(R.id.recycler_view);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setItemViewCacheSize(2);
    mRecyclerView.setAdapter(searchabledapter);
    mRecyclerView.setLayoutManager(layoutManager);

我的適配器代碼:

public class Menu_Detail_Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {


    public Menu_Detail_Adapter(Context context1) {
        arrayList = new ArrayList<>();
        arrlist = new ArrayList<>();
        context = context1;
    }




    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder(ViewGroup parent, int viewType) {


            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.kasib_o_karahi_list_view, parent, false);
            return new MemberViewHolder(view, onItemClickListener);

    }



    String imageUrl = "";
    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder  holder, int position) {

        final ParseObject parseObject = arrayList.get(position);

        if(holder instanceof  MemberViewHolder){

            if (arrayList.size() > 0) {
                try {

                    ((MemberViewHolder) holder).linear_layout__add.setVisibility(View.VISIBLE);
                    ((MemberViewHolder) holder).linear_layout_add_subtract_buttons.setVisibility(View.GONE);

                    // Here I am facing a problem

                    // On both LinearLayout click listeners when I am scrolling it 
is again changing my View States


                    ((MemberViewHolder) holder).rrl_add.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ((MemberViewHolder) holder).linear_layout__add.setVisibility(View.GONE);
                            ((MemberViewHolder) holder).linear_layout_add_subtract_buttons.setVisibility(View.VISIBLE);
                        }
                    });

                    ((MemberViewHolder) holder).rrl_minus.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ((MemberViewHolder) holder).linear_layout__add.setVisibility(View.VISIBLE);
                            ((MemberViewHolder) holder).linear_layout_add_subtract_buttons.setVisibility(View.GONE);
                        }
                    });

                    ((MemberViewHolder) holder).rrl_add_btn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                        }
                    });



                } catch (Exception e) {
                    e.getMessage();
                }
            }
        }
    }

    @Override
    public int getItemCount() {
        return arrayList == null ? 0 : arrayList.size();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
    }




    static class MemberViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView txtTitle;
        TextView txtDescription;
        TextView txtCountry;
        OnItemClickListener onItemClickListener;
        ImageView imgDescription;

        LinearLayout linear_layout_add_subtract_buttons, linear_layout__add;
        RelativeLayout rrl_add, rrl_minus, rrl_add_btn;

        public MemberViewHolder(View itemView, OnItemClickListener onItemClickListener) {
            super(itemView);
            linear_layout_add_subtract_buttons = (LinearLayout) itemView.findViewById(R.id.add_subtract_buttons);
            linear_layout__add                 = (LinearLayout) itemView.findViewById(R.id.ll_add);
            rrl_add              = (RelativeLayout) itemView.findViewById(R.id.rrl_add);
            rrl_minus            = (RelativeLayout) itemView.findViewById(R.id.rrl_minus);
            rrl_add_btn          = (RelativeLayout) itemView.findViewById(R.id.rrl_add_btn);


            itemView.setOnClickListener(this);
            this.onItemClickListener = onItemClickListener;
        }

        @Override
        public void onClick(View v) {
            onItemClickListener.onItemClick(v, getAdapterPosition());
        }
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }


}

一個問題是您的代碼既不簡單也不完整且可驗證。 所以我不得不做一個你必須根據自己的需要采用的例子。

我所討論的“單個對象數組”由DataItem類的對象組成,其中包含一個int和兩個boolean s成員。

public class DataItem{
    int dataItem;
    boolean visible1;
    boolean visible2;

    public DataItem(int dataItem, boolean visible1, boolean visible2){
        this.dataItem = dataItem;
        this.visible1 = visible1;
        this.visible2 = visible2;
    }
}

我的活動中的onCreate()如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    int dataItemsLength = 50;
    ArrayList<DataItem> dataItems = new ArrayList<>();
    for (int i = 0; i < dataItemsLength; i++) {
        dataItems.add(new DataItem(i, true, true));
    }
    RecyclerView rv = findViewById(R.id.rv);
    Menu_Detail_Adapter adapter = new Menu_Detail_Adapter(this, dataItems);
    rv.setLayoutManager(new LinearLayoutManager(this));
    rv.setAdapter(adapter);
}

雖然在你的代碼中不清楚你的數據來自何處,但在這里我選擇了在活動中“制作”數據(你可能想要“讀取”它)並將其傳遞給適配器的方法。 原則上,您也可以在適配器中執行此操作。

我為RecyclerView使用了一個非常簡單的布局:

<?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="wrap_content">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

並且項目的布局只是稍微復雜一些:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/rl1"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:background="@android:color/holo_orange_light">

       <TextView
            android:id="@+id/tv1"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rl2"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:background="@android:color/holo_orange_dark">

        <TextView
            android:id="@+id/tv2"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
</LinearLayout>

最重要的是,適配器:

public class Menu_Detail_Adapter extends RecyclerView.Adapter<Menu_Detail_Adapter.ViewHolder> {
    private ArrayList<DataItem> dataItems;
    private final LayoutInflater inflater;

    Menu_Detail_Adapter(Context context, ArrayList<DataItem> dataItems) {
        this.dataItems = new ArrayList<>();
        this.dataItems.addAll(dataItems);
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(inflater.inflate(R.layout.list_item, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.rl1.setVisibility(dataItems.get(position).visible1 ? View.VISIBLE : View.INVISIBLE);
        holder.tv1.setText(String.valueOf(dataItems.get(position).dataItem));
        holder.rl2.setVisibility(dataItems.get(position).visible2 ? View.VISIBLE : View.INVISIBLE);
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        RelativeLayout rl1, rl2;
        TextView tv1;

        ViewHolder(View itemView) {
            super(itemView);
            rl1 = itemView.findViewById(R.id.rl1);
            rl2 = itemView.findViewById(R.id.rl2);
            rl1.setOnClickListener(this);
            rl2.setOnClickListener(this);
            tv1 = itemView.findViewById(R.id.tv1);
            ((TextView) itemView.findViewById(R.id.tv2)).setText("default");
        }

        @Override
        public void onClick(View view) {
            if (view.getId() == R.id.rl1) {
                if (view.getVisibility() == View.VISIBLE) {
                    view.setVisibility(View.INVISIBLE);
                    dataItems.get(getAdapterPosition()).visible1 = false;
                } else {
                    view.setVisibility(View.VISIBLE);
                    dataItems.get(getAdapterPosition()).visible1 = true;
                }
            } else if (view.getId() == R.id.rl2) {
                if (view.getVisibility() == View.VISIBLE) {
                    view.setVisibility(View.INVISIBLE);
                    dataItems.get(getAdapterPosition()).visible2 = false;
                } else {
                    view.setVisibility(View.VISIBLE);
                    dataItems.get(getAdapterPosition()).visible2 = true;
                }
            }
        }
    }
}

關於適配器的一些評論:

  • 確保不要對onBindViewHolder()任何可見性進行硬編碼 請改用您的數據集。

  • 附上onClickListener S 中的構造函數中ViewHolder類。 如果您願意,可以將偵聽器添加為匿名類,並避免使用統一的onClick方法的if子句。 這主要是品味問題。

  • 在偵聽器內部,請小心兩者: 刷新視圖並更新模型 這是至關重要的一點。

  • 出於您的目的,請不要使用notifyDataSetChanged 只有在從名為dataItemsArrayList<DataItem>添加或刪除DateItem時,才需DateItem

也許你可以創建第二個arrayList,默認情況下使用一個包含2個布爾值的對象。 然后每次更改為GONE或VISIBLE時,都會更改布爾值。

初始化視圖時,您將為第二個arraylist提供與當前arrayList相同的大小。

在onBindviewHolder中,您可以根據布爾狀態設置可見性(因此默認情況下它將為true),然后在onClickListener上更改布爾值。

當您希望項狀態依賴於動態值更改時,您可能需要考慮將該值放入對象(來自數組)本身,並使用它而不是依賴於視圖持有者緩存的內存

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM