Обновить текстовое представление из класса Recyclerview Adapter - PullRequest
0 голосов
/ 01 июля 2018

Я работаю над приложением электронной коммерции для размещения онлайн-заказов. В моем Recyclerview есть продукты, которые были добавлены в предыдущем действии. Здесь я заполняю добавленные продукты в Recyclerview такими подробностями, как имя элемента, количество, цена и т. Д. Есть кнопки для увеличения / уменьшения количества каждого продукта и еще одна кнопка для удаления элемента.

В нижней части макета Recyclerview есть еще одно текстовое представление для отображения итоговой суммы. Поскольку я обрабатываю слики кнопок в классе RecyclerViewAdapter, при обновлении пользователем количества или удалении элемента мне необходимо обновить итоговую сумму. Я попробовал некоторые решения, уже упомянутые здесь, но приложение вылетает при случайном нажатии кнопки. Пожалуйста, предоставьте решение или лучший способ сделать это.

Вот мой класс адаптера:

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

1 Ответ

0 голосов
/ 01 июля 2018

Я бы посоветовал пройти через слушателя, переместить ваши onClickListener и удалить циклы for.

Итак, шаг за шагом

В вашем классе адаптеров объявите интерфейс

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

Затем добавьте приватный OnQuantityChangeListener в ваш класс адаптера и измените конструктор, добавив его при создании:

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

Плохо для производительности устанавливать OnClickListeners в методе onBindViewHolder, потому что это означает, что вам придется добавлять их в любое время, когда представление появляется на экране. Вместо этого установите их в методе 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;
}

Не забудьте в этот момент удалить OnClickListeners из вашего onBindViewHolder метода.

Как только это будет сделано, зайдите в свою активность и добавьте личный итог:

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

    }

} );

И это делает. Не забудьте рассчитать свой первый итог в своей активности один раз (без выхода из цикла for здесь), а затем убедитесь, что вы сохранили свои экземпляры.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...