从Recyclerview Adapter类更新textview [英] Update textview from Recyclerview Adapter class

查看:60
本文介绍了从Recyclerview Adapter类更新textview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个电子商务应用程序,以下一些在线订单.在我的Recyclerview中,有一些产品,它们是在上一个活动中添加的.在这里,我在Recyclerview中用产品名称,数量,价格等详细信息填充了添加的产品.有一些按钮可以增加/减少每种产品的数量,还有一个按钮也可以删除该项目.

I'm working on a E-commerce App to place some online orders. In my Recyclerview there are products, which are added at the previous activity. Here i'm populating the added products in the Recyclerview with the details such as item name, qty, price etc.. There are buttons to increase/decrease the qty of each products and another button to delete the item too.

在Recyclerview布局的底部,还有另一个textview用于显示总计.当我在处理RecyclerViewAdapter类中的按钮时,当用户更新数量或删除项目时,我必须更新总计.我尝试了这里已经提到的一些解决方案,但是该应用程序在随机单击按钮时崩溃.请提供解决方案或更好的方法.

At the bottom of the Recyclerview Layout there is another textview to Show the grand total. As I'm handling the button slicks in the RecyclerViewAdapter class, while user updating the qty or deleting an item, I have to update the Grand total. I tried some solutions already mentioned here, but the app crashes at random button clicks. Please provide a solution or a better way to do this.

这是我的适配器类:

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);
    }
}

这是主要活动"部分:

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循环.

I'd suggest going through a listener, moving your onClickListeners and removing the for loops.

所以,一步一步

在您的适配器类中声明一个接口

In your adapter class declare an interface

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

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

Next add a private OnQuantityChangeListener to your adapter class and change the constructor to add one at creation:

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()方法.

It's bad for performance to set OnClickListeners in the onBindViewHolder method, because this means you're going to have to add them any time a view pops up onto the screen. Set them in the onCreateViewHolder method instead, that way you'll recycle them. To get your current item you can use the getAdapterPosition() method.

因此,在 onCreateViewHolder 方法中设置侦听器:

So in the onCreateViewHolder method set the listeners:

@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.

Remember at this point to remove the OnClickListeners from your onBindViewHolder method.

完成此操作后,转到您的活动并添加私人总计:

Once this is done head over to your Activity and add a private total:

private float total = 0;

并按如下方式编辑适配器的创建:

and edit your adapter creation like so:

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

    @Override
    void onQuantityChange( float difference ){

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

    }

} );

然后就可以了.请记住要一次计算您的活动中的第一个总数(此处不要转义for循环),然后确保保存实例状态.

And that about does it. Remember to calculate your first total in your activity once (no escaping the for loop here) and then make sure you save your instance states.

希望这会有所帮助!

这篇关于从Recyclerview Adapter类更新textview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆