[英]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
。 只有在從名為dataItems
的ArrayList<DataItem>
添加或刪除DateItem
時,才需DateItem
。
也許你可以創建第二個arrayList,默認情況下使用一個包含2個布爾值的對象。 然后每次更改為GONE或VISIBLE時,都會更改布爾值。
初始化視圖時,您將為第二個arraylist提供與當前arrayList相同的大小。
在onBindviewHolder中,您可以根據布爾狀態設置可見性(因此默認情況下它將為true),然后在onClickListener上更改布爾值。
當您希望項狀態依賴於動態值更改時,您可能需要考慮將該值放入對象(來自數組)本身,並使用它而不是依賴於視圖持有者緩存的內存
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.