更改微调器项目数据时更新recyclerview单行数据

Posted

技术标签:

【中文标题】更改微调器项目数据时更新recyclerview单行数据【英文标题】:Update recyclerview single row data when spinner item data is changed 【发布时间】:2019-06-07 13:40:48 【问题描述】:

我有一个RecyclerView,如下图所示。

我从服务器获取食物数据并将它们绑定到RecyclerView,如上。

食品项目在foodItemList 数组列表中分配,该列表具有foodItemTypeList 数组。在foodItemTypeList数组列表中,存储了类型的值及其对应的价格。

我想要的是当用户选择一种食物类型(例如中等)时,更新相应的单价。

这是FoodItemAdapter 类:

public class FoodItemAdapter extends RecyclerView.Adapter<FoodItemAdapter.CustomViewHolder> 
    private List<FoodItem> foodItemList;
    Context context;
    String token;

    public class CustomViewHolder extends RecyclerView.ViewHolder 
        public TextView food_name, food_unit_price;
        Spinner food_item_type;
        public ImageView food_item_image;
        public Button viewDetail;

        public CustomViewHolder(View view) 
            super(view);
            food_name = (TextView) itemView.findViewById(R.id.food_name);
            food_item_type = (Spinner) itemView.findViewById(R.id.food_item_type);
            viewDetail = (Button) itemView.findViewById(R.id.viewDetail);
            food_unit_price = (TextView) itemView.findViewById(R.id.food_unit_price);
            food_item_image = (ImageView) itemView.findViewById(R.id.food_item_image);
        
    

    public FoodItemAdapter(Context context, List<FoodItem> foodItemList,String token) 
        this.foodItemList = foodItemList;
        this.context = context;
        this.token = token;
    

    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.food_items_item, parent, false);
        return new CustomViewHolder(itemView);
    

    @Override
    public void onBindViewHolder(final CustomViewHolder holder, int position) 
        FoodItem foodItem = foodItemList.get(position);
        holder.food_name.setText(foodItem.getFood_name());
        holder.viewDetail.setOnClickListener(new View.OnClickListener()
            @Override
            public void onClick(View v) 

            
        );

        holder.food_unit_price.setText(foodItem.getFood_unit_price()+" AF");

        if(foodItem.getFood_item_image()!=null && !foodItem.getFood_item_image().isEmpty())
            Picasso.get()
                    .load(foodItem.getFood_item_image())
                    // To fit image into imageView
                    .resize(50, 50)
                    .centerCrop()
                    .into(holder.food_item_image);
         else 
            Log.d("Food Item Image:", "Food Item image is either empty or null");
        

        List<FoodItemType> foodItemTypeList = new ArrayList<>();
        foodItemTypeList = foodItem.getFoodItemTypeList();
        ArrayAdapter userAdapter = new ArrayAdapter(context, R.layout.spinner, foodItemTypeList);
        holder.food_item_type.setAdapter(userAdapter);
        holder.food_item_type.setOnItemSelectedListener(new
            AdapterView.OnItemSelectedListener() 
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int
                        position, long id) 

                    FoodItemType foodItemType = (FoodItemType) (holder.food_item_type).getSelectedItem();
                    Toast.makeText(context, "Clicked: " +
                            foodItemType.getFood_unit_price(), Toast.LENGTH_LONG).show();
                    FoodItem foodItemNew = new FoodItem(foodItemList.get(holder.getAdapterPosition()).getFood_item_id(),foodItemList.get(holder.getAdapterPosition()).getFood_category_id(),foodItemList.get(holder.getAdapterPosition()).getFood_name(),foodItemList.get(holder.getAdapterPosition()).getFood_item_image(),foodItemList.get(holder.getAdapterPosition()).getFood_item_desc(), foodItemType.getFood_item_type_id(),foodItemType.getFood_item_type_name(),foodItemType.getFood_unit_price(), foodItemList.get(holder.getAdapterPosition()).getFoodItemTypeList());
                    foodItemList.set(holder.getAdapterPosition(),foodItemNew);
                    notifyItemChanged(holder.getAdapterPosition());
                

                @Override
                public void onNothingSelected(AdapterView<?> parent) 
                    // todo for nothing selected
                
            );
    

    @Override
    public int getItemCount() 
        return foodItemList.size();
    


我的FoodItemsFragment 课程的一部分如下:

recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_food_item);
foodItemAdapter = new FoodItemAdapter(getActivity(),foodItemList, token);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());

recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(foodItemAdapter);
foodItemAdapter.notifyDataSetChanged(); 

我的问题是:当我滚动 RecyclerView 时,视图被多次加载(一种滞后),而当我更改美食类型(例如:中)时,什么也没有发生。

感谢任何形式的帮助。

【问题讨论】:

这个是点击吐司换菜的时候显示吗? Toast.makeText(context, "Clicked: " + foodItemType.getFood_unit_price(), Toast.LENGTH_LONG).show(); 仅用于调试目的。加载 recyclerview 时,small 类型的价格值显示多次。 我认为问题出在onBindViewHolder。它在滚动期间多次调用并导致滞后。不知道在onBindViewHolder方法中实现setOnItemSelectedListener是不是正确的方法 图片大小如何? 您是否尝试加载相同的列表但没有图像? 【参考方案1】:

我想建议您在FoodItem 类中添加另一个字段,即selectedFoodType。这将保存所选类型的索引。默认情况下,将值初始化为 0,当从下拉列表中选择项目时,只需相应地更新对应的FoodItemselectedFoodType

另一件事是,您不必每次更改FoodItem 的类型时都创建一个新的FoodItem。您只需要拥有selectedFoodType,然后调用notifyDataSetChanged()

所以代码应该如下所示。在您的 onItemSelected 函数中,执行以下操作。

int foodType = foodItemTypeList.get(position);
FoodItem foodItem = foodItemNew.get(holder.getAdapterPosition());
foodItem.setSelectedFoodType = foodType;
notifyDataSetChanged();

请注意,我尚未测试此代码。请根据您的需要进行修改。希望有帮助!

【讨论】:

我试过你的答案。我注意到创造新食物是滞后的。当我使用 notifyDataSetChanged() 时,微调器下拉菜单会冻结。所以,这次我改成notifyItemChanged(holder.getAdapterPosition());,当我选择食物类型(例如中)时,它会刷新回小。 您还需要在微调器中设置所选项目。在onBindViewHolder 中使用selectedFoodType 作为微调器选定的项目。

以上是关于更改微调器项目数据时更新recyclerview单行数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在微调器中更改单选按钮颜色

获取微调器选定项目并传递数据

从 PHP MySql 填充 Android 微调器

如何根据两个不同活动中其他微调器的位置更改微调器的位置

如何在 RecyclerView 中制作动态微调器?

在活动一中选择的微调项目上,必须更改第二个活动中的文本视图