从 Recyclerview 适配器更新文本视图 class

Update textview from Recyclerview Adapter class

我正在开发一个电子商务应用程序来下一些在线订单。在我的Recyclerview里面有产品,是在之前activity添加的。在这里,我用项目名称、数量、价格等详细信息填充 Recyclerview 中添加的产品。有按钮 increase/decrease 每个产品的数量和另一个按钮也可以删除项目。

在 Recyclerview 布局的底部有另一个文本视图来显示总计。当我在 RecyclerViewAdapter class 中处理按钮滑动时,当用户更新数量或删除项目时,我必须更新总计。我尝试了这里已经提到的一些解决方案,但应用程序会在随机点击按钮时崩溃。请提供解决方案或更好的方法。

这是我的适配器 class:

public class InvoiceRecyclerViewAdapter extends RecyclerView.Adapter<InvoiceRecyclerViewAdapter.ViewHolder> {
    private static final String TAG = "RecylerViewAdapter";

    List<Products> addedProductsList;
    Context mContext;


    public InvoiceRecyclerViewAdapter(Context mContext,List<Products> addedProductsList)
    {
        this.mContext=mContext;
        this.addedProductsList=addedProductsList;

    }
    public InvoiceRecyclerViewAdapter(Context mContext)
    {
        this.mContext=mContext;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_invoice,parent,false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {

        holder.item_qty.setText("1");
        holder.itemname.setText(addedProductsList.get(position).getName());
        holder.itemprice.setText("Rs "+addedProductsList.get(position).getPrice());
        holder.itemdiscount.setText("Rs "+calculate_dis(position));
        holder.itemtotal.setText("Rs "+calculate_total(position));


        holder.button_inc.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int qty = addedProductsList.get(position).getQty();
                qty++;
                addedProductsList.get(position).setQty(qty);
                holder.item_qty.setText(""+qty);
                holder.itemdiscount.setText("Rs "+calculate_dis(position));
                holder.itemtotal.setText("Rs "+calculate_total(position));

                UpdateTotal();

            }
        });

        holder.button_dec.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int qty = addedProductsList.get(position).getQty();
                qty--;
                if(qty>0){
                    addedProductsList.get(position).setQty(qty);
                    holder.item_qty.setText(""+qty);
                    holder.itemdiscount.setText("Rs"+calculate_dis(position));
                    holder.itemtotal.setText("Rs"+calculate_total(position));

                    UpdateTotal();
                }

            }
        });

        holder.button_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addedProductsList.get(position).setAddedTocart(false);
                //notifyDataSetChanged();
                addedProductsList.remove(position);
                notifyItemRemoved(position);

                UpdateTotal();
            }
        });
    }

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


    public class ViewHolder extends RecyclerView.ViewHolder{

        TextView itemname,itemtotal,itemprice,itemdiscount,item_qty;
        Button button_cancel,button_inc,button_dec;
        ConstraintLayout parent_layout;

        public ViewHolder(View itemView) {
            super(itemView);
            itemname = itemView.findViewById(R.id.textView_item_name);
            itemprice = itemView.findViewById(R.id.textView_item_price);
            itemdiscount = itemView.findViewById(R.id.textView_item_discount);
            itemtotal = itemView.findViewById(R.id.textView_item_total);
            button_cancel = itemView.findViewById(R.id.button_cancel);
            button_inc=itemView.findViewById(R.id.button_inc);
            button_dec=itemView.findViewById(R.id.button_dec);
            item_qty = itemView.findViewById(R.id.textView_qty);
            parent_layout = itemView.findViewById(R.id.invoice_parent_layout);

        }
    }

    private float calculate_dis(int pos){
        float dis = 0;
        if(addedProductsList.get(pos).isPrice_g_enabled()){
            int qty=addedProductsList.get(pos).getQty();
            dis = Float.parseFloat(addedProductsList.get(pos).getPrice())-Float.parseFloat(addedProductsList.get(pos).getPrice_g());
            dis = qty*dis;
        }
        return dis;


    }
    private float calculate_total(int pos){
        int qty=addedProductsList.get(pos).getQty();
        float price,total;
        if(addedProductsList.get(pos).isPrice_g_enabled()){
            price = Float.parseFloat(addedProductsList.get(pos).getPrice_g());
        }
        else{
            price= Float.parseFloat(addedProductsList.get(pos).getPrice());
        }

        total = price*qty;
        return total;
    }
    private void UpdateTotal(){

        TextView txtView =((EditQuantity)mContext).findViewById(R.id.textView_total);

        float total=0,price=0;
        int qty=0;
        for(int i=0;i<addedProductsList.size();i++){
            if(addedProductsList.get(i).isAddedTocart()) {
                qty = addedProductsList.get(i).getQty();
                if(addedProductsList.get(i).isPrice_g_enabled()){
                    price = Float.parseFloat(addedProductsList.get(i).getPrice_g());
                }
                else{
                    price= Float.parseFloat(addedProductsList.get(i).getPrice());
                }

            }
            total=total+(qty*price);
        }
        txtView.setText("Rs "+total);
    }
}

这是主要的 Activity 部分:

public class EditQuantity extends AppCompatActivity {

    ArrayList<Products> products_list;
    ArrayList<Products> cart_productslist= new ArrayList<>();
    Products added_product;
    FloatingActionButton fab_next;
    TextView total_textview;

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

        products_list = getIntent().getParcelableArrayListExtra("products");
        Products products;
        for(int i=0;i<products_list.size();i++){
            products = products_list.get(i);
            if(products.isAddedTocart()){
                added_product = new Products(products.getName(),products.getPrice(),products.getPrice_g(),products.getImage(),1,true,products.isPrice_g_enabled());

                cart_productslist.add(added_product);
            }

        }

        Toolbar toolbar = findViewById(R.id.toolbar_invoice);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("Cart");

        total_textview = findViewById(R.id.textView_total);
        total_textview.setText("Rs "+CalTotal());


        fab_next = findViewById(R.id.fab_next);
        fab_next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        InitRecylerView();
    }

    @Override
    public void onBackPressed() {

    }

    private void InitRecylerView() {
        RecyclerView recyclerView = findViewById(R.id.invoice_recyclerview);
        InvoiceRecyclerViewAdapter adapter = new InvoiceRecyclerViewAdapter(
                this ,cart_productslist);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

    }

    public float CalTotal(){
        float total=0;
        float i_total,price;
        for(int i=0;i<cart_productslist.size();i++){
            if(cart_productslist.get(i).isAddedTocart()) {
                int qty = cart_productslist.get(i).getQty();
                if(cart_productslist.get(i).isPrice_g_enabled()){
                    price = Float.parseFloat(cart_productslist.get(i).getPrice_g());
                }
                else{
                    price= Float.parseFloat(cart_productslist.get(i).getPrice());
                }
                i_total = price * qty;
                total = total + i_total;
            }
        }
        return total;
    } 

我建议通过一个侦听器,移动你的 onClickListeners 并删除 for 循环。

所以,一步一步来

在你的适配器中class声明一个接口

public interface OnQuantityChangeListener {
    void onQuantityChange( float change );
}

接下来向您的适配器添加一个私有的 OnQuantityChangeListener class 并更改构造函数以在创建时添加一个:

private OnQuantityChangeListener mListener;

public InvoiceRecyclerViewAdapter(Context mContext,List<Products> addedProductsList, OnQuantityChangeListener listener) {
    this.mContext=mContext;
    this.addedProductsList=addedProductsList;
    mListener = listener;

}
public InvoiceRecyclerViewAdapter(Context mContext, OnQuantityChangeListener listener)
{
    this.mContext=mContext;
    mListener = listener;
}

在 onBindViewHolder 方法中设置 OnClickListeners 对性能不利,因为这意味着您必须在屏幕上弹出视图时随时添加它们。相反,将它们设置在 onCreateViewHolder 方法中,这样您就可以回收它们。要获取当前项目,您可以使用 getAdapterPosition() 方法。

所以在 onCreateViewHolder 方法中设置监听器:

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_invoice,parent,false);
    ViewHolder viewHolder = new ViewHolder(view);

    viewHolder.button_inc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Products product = addedProductsList.get(getAdapterPosition());

            product.setQty( product.getQty() + 1 );

            float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());

            mListener.onQuantityChange( difference );

            notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you

        }
    });

    viewHolder.button_dec.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Products product = addedProductsList.get(getAdapterPosition());

            if( product.getQty() == 0 )// Can't remove an item if it's already at 0
                return;

            product.setQty( product.getQty() - 1 );

            float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());

            mListener.onQuantityChange( -difference );

            notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you

        }
    });

    viewHolder.button_cancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Products product = addedProductsList.get(getAdapterPosition());

            float difference = product.isPrice_g_enabled() ? Float.parseFloat(product.getPrice_g()) : Float.parseFloat(product.getPrice());

            mListener.onQuantityChange( -difference * product.getQty() );

            product.setQty( 0 );

            notifyItemChanged( getAdapterPosition ):// This will call onBindViewAdapter again and change all your strings for you

            // You decide at this point if you want to remove the item altogether or just show 0

        }
    });

    return viewHolder;
}

此时请记住从您的 onBindViewHolder 方法中删除 OnClickListeners。

完成后前往您的 Activity 并添加一个私人总数:

private float total = 0;

并像这样编辑您的适配器创建:

InvoiceRecyclerViewAdapter adapter = new InvoiceRecyclerViewAdapter(
        this ,cart_productslist, new InvoiceRecyclerViewAdapter.OnQuantityChangeListener(){

    @Override
    void onQuantityChange( float difference ){

        total += difference;
        total_textview.setText("Rs "+ total);

    }

} );

就是这样。请记住计算一次 activity 中的第一个总数(不要在此处转义 for 循环),然后确保保存实例状态。

希望对您有所帮助!