我的RecyclerView数据在向下滚动时丢失了。

4

我有一个RecyclerView,并在其中设置了一些TextView的文本。当我向下滚动或我的Fragment进入onPause状态时,我的数据丢失了。我该怎么办?

import static com.test.mohammaddvi.snappfood.Adapter.SectionListDataAdapter.decodeSampledBitmapFromResource;
public class RecyclerViewMenuFragmentAdapter extends RecyclerView.Adapter<RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment> {

private ArrayList<Food> foodList;
private Context mContext;

public RecyclerViewMenuFragmentAdapter(ArrayList<Food> foodList, Context mContext) {
    this.foodList = foodList;
    this.mContext = mContext;

}

@NonNull
@Override
public RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.foodlist, null);
    return new RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment(v);
}

@Override
public void onBindViewHolder(final RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment holder, int position) {
    Food food = foodList.get(position);
    holder.foodName.setText(food.getName());
    holder.foodDetails.setText(food.getDetails());
    holder.foodPrice.setText(food.getPrice() + " تومان ");
    holder.foodOrderNumber.setVisibility(View.INVISIBLE);
    holder.foodMinusButton.setVisibility(View.INVISIBLE);
    holder.foodOrderNumber.setText(0 + "");
    holder.foodImage.setImageBitmap(decodeSampledBitmapFromResource(mContext.getResources(), mContext.getResources().getIdentifier(food.getImage(),
            "drawable", mContext.getPackageName()), 50, 50));
    handleClick(holder, position);
}

private void handleClick(final SingleItemInMenuFragment holder, final int position) {
    holder.foodPlusButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            int orderNumber = Integer.parseInt(holder.foodOrderNumber.getText().toString());
            holder.foodOrderNumber.setText(orderNumber + 1 + "");
            holder.foodOrderNumber.setVisibility(View.VISIBLE);
            holder.foodMinusButton.setVisibility(View.VISIBLE);

        }
    });
    holder.foodMinusButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            int orderNumber = Integer.parseInt(holder.foodOrderNumber.getText().toString());
            if (orderNumber > 1) {

                holder.foodOrderNumber.setText(orderNumber - 1 + "");
                holder.foodOrderNumber.setVisibility(View.VISIBLE);

            }
            if (orderNumber == 1) {

                holder.foodOrderNumber.setText(orderNumber - 1 + "");
                holder.foodOrderNumber.setVisibility(View.INVISIBLE);
                holder.foodMinusButton.setVisibility(View.INVISIBLE);

            }
        }
    });
}

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


public class SingleItemInMenuFragment extends RecyclerView.ViewHolder {
    TextView foodName;
    TextView foodPrice;
    Button foodPlusButton;
    Button foodMinusButton;
    TextView foodOrderNumber;
    ImageView foodImage;
    TextView foodDetails;

    SingleItemInMenuFragment(View itemView) {

        super(itemView);
        this.foodName = itemView.findViewById(R.id.foodName);
        this.foodImage = itemView.findViewById(R.id.imageFood);
        this.foodPrice = itemView.findViewById(R.id.foodPrice);
        this.foodDetails = itemView.findViewById(R.id.foodDetails);
        this.foodPlusButton = itemView.findViewById(R.id.plusbutton);
        this.foodMinusButton = itemView.findViewById(R.id.minusbutton);
        this.foodOrderNumber = itemView.findViewById(R.id.ordernumber);

    }
}

这是我在RecyclerView中使用的片段:

...

public class MenuFragment extends Fragment{
private static final String TAG = "menufragment";
ArrayList<Food> allfoods = new ArrayList<>();
RecyclerView recyclerview;
private static Bundle bundle;
private final String KEY_RECYCLER_STATE= "recycler_state";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.menufragment, container, false);
}

@Override
public void onStart() {
    super.onStart();
    String jsonFilePath = "foods.json";
    recyclerview = getActivity().findViewById(R.id.lstitems);
    RecyclerViewMenuFragmentAdapter adapter = new RecyclerViewMenuFragmentAdapter(allfoods, getContext());
    recyclerview.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
    recyclerview.setHasFixedSize(true);
    recyclerview.setAdapter(adapter);
    parsJson(jsonFilePath);
}

//this method is for read a local json and return a string
public String readLocalJson(String jsonFile) {
    String json;
    try {
        InputStream is = getActivity().getAssets().open(jsonFile);
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        json = new String(buffer, "UTF-8");
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    return json;
}

public void parsJson(String jsonFilePath) {
    try {
        JSONObject obj = new JSONObject(readLocalJson(jsonFilePath));
        JSONArray jsonArray = obj.getJSONArray("results");
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String image = jsonObject.getString("image");
            JSONArray jsonArrayFoot = jsonObject.getJSONArray("foots");
            for (int j = 0; j < jsonArrayFoot.length(); j++) {
                JSONObject jsonObjectFoot = jsonArrayFoot.getJSONObject(j);
                String foodName = jsonObjectFoot.getString("name");
                String fooddetails = jsonObjectFoot.getString("fooddetails");
                String price = jsonObjectFoot.getString("price");
                allfoods.add(new Food(foodName, price, fooddetails, image));
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

添加您的代码以获得更好的帮助。 - veritas1
@veritas1 我添加了我的RecyclerView适配器。 - Mohammad Davari
将 parsJson(jsonFilePath) 移到您的适配器构造函数之前,或在 parsJson(jsonFilePath) 之后调用适配器的 notifyDataSetChanged。 - Mosius
@Mosius 我的问题仍然存在。 - Mohammad Davari
2个回答

2

将以下代码添加到您的onBindViewHolder方法中,然后再次检查问题是否仍然存在:

 holder.setIsRecyclable(false);

我已经添加了,问题仍然存在。 - Mohammad Davari

1
基本上,你只是在onStart中初始化数据,当你的活动/片段恢复时最终会调用它,因此你所更改的所有数据都被覆盖为初始数据。
将你的onStart初始化移动到onViewCreated中:
@Override
public void onViewCreated() {
    super.onViewCreated();
    String jsonFilePath = "foods.json";
    recyclerview = getActivity().findViewById(R.id.lstitems);
    RecyclerViewMenuFragmentAdapter adapter = new RecyclerViewMenuFragmentAdapter(allfoods, getContext());
    recyclerview.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
    recyclerview.setHasFixedSize(true);
    recyclerview.setAdapter(adapter);
    parsJson(jsonFilePath);
}

对于滚动来说,这是正常的,因为RecyclerView从上面的列表中回收视图,但数据不会回收,所以您需要存储列表源中的值。

@Override
public void onBindViewHolder(final RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment holder, int position) {
    Food food = foodList.get(position);
    holder.foodName.setText(food.getName());
    holder.foodDetails.setText(food.getDetails());
    holder.foodPrice.setText(food.getPrice() + " تومان ");
    holder.foodOrderNumber.setVisibility(View.INVISIBLE);
    holder.foodMinusButton.setVisibility(View.INVISIBLE);
    holder.foodOrderNumber.setText(food.getFoodOrderNumber());
    holder.foodImage.setImageBitmap(decodeSampledBitmapFromResource(mContext.getResources(), mContext.getResources().getIdentifier(food.getImage(),
            "drawable", mContext.getPackageName()), 50, 50));
    handleClick(holder, position);
}

private void handleClick(final SingleItemInMenuFragment holder, final int position) {
    holder.foodPlusButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int orderNumber = Integer.parseInt(holder.foodOrderNumber.getText().toString());
            int newOrderNumber = orderNumber + 1;
            Food food = foodList.get(position);
            food.setFoodOrderNumber(newOrderNumber);
            holder.foodOrderNumber.setText(newOrderNumber + "");
            holder.foodOrderNumber.setVisibility(View.VISIBLE);
            holder.foodMinusButton.setVisibility(View.VISIBLE);

        }
    });
    holder.foodMinusButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Food food = foodList.get(position);

            int orderNumber = food.getFoodOrderNumber();
            if (orderNumber > 1) {
                int newOrderNumber = orderNumber - 1;
                food.setFoodOrderNumber(newOrderNumber);
                holder.foodOrderNumber.setText(newOrderNumber + "");
                holder.foodOrderNumber.setVisibility(View.VISIBLE);

            }
            if (orderNumber == 1) {
                int newOrderNumber = orderNumber - 1;
                food.setFoodOrderNumber(newOrderNumber);
                holder.foodOrderNumber.setText(newOrderNumber + "");
                holder.foodOrderNumber.setVisibility(View.INVISIBLE);
                holder.foodMinusButton.setVisibility(View.INVISIBLE);

            }
        }
    });
}

在你的Food对象上添加以下字段和函数:

public class Food {
    int foodOrderNumber;

    public int getFoodOrderNumber() {
        return foodOrderNumber;
    }

    public void setFoodOrderNumber(int foodOrderNumber) {
        this.foodOrderNumber = foodOrderNumber;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接