繁体   English   中英

从片段更新ListView适配器内的TextView

[英]Updating TextView inside ListView Adapter from a Fragment

我的OrderFragment有一个价格TextView ,我想更新onItemSelected的每件商品折扣和每张账单Spinner折扣。 更改商品价格后,我尝试在ArrayList上使用notifyDataSetChanged ,但它没有更新ListView 当我在不同的片段中使用它来添加和删除ArrayList元素时, notifyDataSetChanged可以正常工作,但是为此更新ArrayList上的价格似乎不起作用。

为了更新每张账单的折扣,我参考了多个问题,但似乎无法正常运行: notifyDataSetChange无法从自定义适配器运行Android:notifyDataSetChanged(); 不工作Android的ListView控件不notifyDataSetChanged后刷新等还。 然后,我尝试使用ListView.getChildAt()从我的Fragment更改TextView ,但由于ListView仅加载可见行,所以它不起作用,因此其他不可见的行不会更新。

至于每件商品的折扣,我可以使用,但是使用2个Callback似乎不太有效。

OrderFragment

public class OrderFragment extends Fragment {
private ArrayList<Product> orderList = new ArrayList<Product>();
private ListView lvConfirmOrder;
private ListViewOrderAdapter lvConfirmOrderAdapter;
private TextView tvTotalOrderPrice;
private int totalOrderPrice;
private Spinner sBillDiscount;
private int billDiscount = 0;
private ItemClickListener itemClickListener;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.fragment_order, container, false);

    activity = getActivity();
    db = DatabaseHelper.getInstance(activity);

    Bundle bundle = new Bundle();
    orderList = getArguments().getParcelableArrayList("orderList");
    tvTotalOrderPrice = (TextView) view.findViewById(R.id.tvShowTotalPrice);
    sBillDiscount = (Spinner) view.findViewById(R.id.sBillDiscount);

    lvConfirmOrder = (ListView) view.findViewById(R.id.lvConfirmOrder);

    lvConfirmOrderAdapter = new ListViewOrderAdapter(activity, orderList, new ItemClickListener() {
        @Override
        public void onItemClick(Product product) {

        }

        @Override
        public void onItemClick(ProductCategory productCategory) {

        }

        @Override
        public void onItemClick(ArrayList<Product> productList) {
            tvTotalOrderPrice.setText(String.format("%d",setTotalPrice()));
        }
    });
    lvConfirmOrder.setAdapter(lvConfirmOrderAdapter);

    // Get the total price of all items
    totalOrderPrice = setTotalPrice();

    // Set the total price into TextView
    tvTotalOrderPrice.setText(String.format("%d",totalOrderPrice));

    addItemsOnSBillDiscountAndPreselect(billDiscount);

    sBillDiscount.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            float spinnerValue = Float.parseFloat(adapterView.getItemAtPosition(i).toString());
            float discount = 1.0f - (spinnerValue/100.0f);
            totalAfterDiscount(discount);
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

    return view;
}

private int setTotalPrice() {
    int totalPrice = 0;

    for (int index = 0; index < orderList.size(); index++) {
        totalPrice += orderList.get(index).getOrderPrice();
    }

    return totalPrice;
}

// add items into spinner
public void addItemsOnSBillDiscountAndPreselect(int discount) {
    List<Integer> list = new ArrayList<Integer>();
    for(int index = 0; index <= 100; index++) {
        list.add(index);
    }
    ArrayAdapter<Integer> dataAdapter = new ArrayAdapter<Integer>(activity,
            android.R.layout.simple_spinner_item, list);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    sBillDiscount.setAdapter(dataAdapter);

    int spinnerPosition = dataAdapter.getPosition(discount);
    sBillDiscount.setSelection(spinnerPosition);
}

public void totalAfterDiscount(float discount) {
    float totalItemPrice[] = new float[orderList.size()];
    for (int i = 0; i < orderList.size(); i++) {
        totalItemPrice[i] = orderList.get(i).getOrderPrice() * discount;
    }
    TextView tvPrice;
    for ( int i = 0 ; i < lvConfirmOrder.getCount() ; i++){
        View v = getViewByPosition(i,lvConfirmOrder);

        tvPrice = (TextView) v.findViewById(R.id.tvQtyPrice);
        tvPrice.setText(String.valueOf(totalItemPrice[i]));
    }

    tvTotalOrderPrice.setText(String.format("%d",setTotalPrice()));
    lvConfirmOrderAdapter.notifyDataSetChanged();
}

public View getViewByPosition(int position, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition =firstListItemPosition + listView.getChildCount() - 1;

    if (position < firstListItemPosition || position > lastListItemPosition ) {
        return listView.getAdapter().getView(position, listView.getChildAt(position), listView);
    } else {
        final int childIndex = position - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}
}

ListViewOrderAdapter

public class ListViewOrderAdapter extends ArrayAdapter {
//to store the list of products
private ArrayList<Product> productList = new ArrayList<Product>();

private ItemClickListener itemClickListener;
private ViewHolder viewHolder;
private DiscountSpinnerListener discountSpinnerListener;

private static class ViewHolder {
    TextView tvProductName;
    TextView tvProductSku;
    TextView tvPrice;
    TextView tvProductNum;
    TextView iAddQuantity;
    TextView tvQuantity;
    TextView tvQtyPrice;
    TextView iMinusQuantity;
    Spinner sDiscount;
    TextView iDelete;
}

public ListViewOrderAdapter(Activity context, ArrayList<Product> listProduct, ItemClickListener itemClickListener){

    super(context,R.layout.row_order , listProduct);
    this.context = context;
    this.productList = listProduct;
    this.itemClickListener = itemClickListener;

}

public View getView(final int position, View view, ViewGroup parent) {
    final Product product = productList.get(position);

    if (view == null) {
        // If there's no view to re-use, inflate a brand new view for row
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(context);
        view = inflater.inflate(R.layout.row_order, null, false);
        viewHolder.tvProductName = (TextView) view.findViewById(R.id.tvOrderProduct);
        viewHolder.tvProductSku = (TextView) view.findViewById(R.id.tvOrderSKU);
        viewHolder.tvPrice = (TextView) view.findViewById(R.id.tvProductPrice);
        viewHolder.tvProductNum = (TextView) view.findViewById(R.id.tvOrderNum);
        viewHolder.iAddQuantity = (TextView) view.findViewById(R.id.iAddQuantity);
        viewHolder.tvQuantity = (TextView) view.findViewById(R.id.tvQuantity);
        viewHolder.tvQtyPrice = (TextView) view.findViewById(R.id.tvQtyPrice);
        viewHolder.iMinusQuantity = (TextView) view.findViewById(R.id.iMinusQuantity);
        viewHolder.sDiscount = (Spinner) view.findViewById(R.id.sDiscount);
        viewHolder.iDelete = (TextView) view.findViewById(R.id.iDelete);

        // Cache the viewHolder object inside the fresh view
        view.setTag(viewHolder);
    } else {
        // View is being recycled, retrieve the viewHolder object from tag
        viewHolder = (ViewHolder) view.getTag();
    }

    //this code sets the values of the objects to values from the arrays
    viewHolder.tvProductName.setText(product.getProduct_name());
    viewHolder.tvProductSku.setText(product.getProduct_sku());
    viewHolder.tvPrice.setText(String.valueOf(product.getPrice_max()));
    String num = Integer.toString(position + 1);
    viewHolder.tvProductNum.setText(num);
    viewHolder.tvQuantity.setText(String.valueOf(product.getOrderQuantity()));
    addItemsOnSDiscountAndPreselect(viewHolder,product.getDiscount_per_item());

    viewHolder.sDiscount.setOnItemSelectedListener(new SpinnerListener(viewHolder, position, new DiscountSpinnerListener() {
        @Override
        public void onDiscountChange(TextView tvPrice, int pos, float price) {
            if (position == pos) {
                tvPrice.setText(String.valueOf(price));
                itemClickListener.onItemClick(productList);
            }
        }
    }));

    font = Typeface.createFromAsset(context.getAssets(), "fonts/fontawesome-webfont.ttf" );
    viewHolder.iAddQuantity.setTypeface(font);
    viewHolder.iMinusQuantity.setTypeface(font);
    viewHolder.iDelete.setTypeface(font);

    viewHolder.iAddQuantity.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            product.setOrderQuantity(product.getOrderQuantity() + 1);
            product.setOrderPrice(product.getOrderQuantity() * product.getPrice_max());
            itemClickListener.onItemClick(productList);
            notifyDataSetChanged();
        }
    });

    viewHolder.iMinusQuantity.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            product.setOrderQuantity(product.getOrderQuantity() - 1);
            product.setOrderPrice(product.getOrderQuantity() * product.getPrice_max());
            if (product.getOrderQuantity() == 0) {
                createAndShowAlertDialog(position, productList);
            } else {
                itemClickListener.onItemClick(productList);
                notifyDataSetChanged();
            }
        }
    });

    viewHolder.iDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            createAndShowAlertDialog(position, productList);
            notifyDataSetChanged();
        }
    });

    return view;

}

private void createAndShowAlertDialog(final int position, final ArrayList<Product> productList) {
    AlertDialog.Builder builder = new AlertDialog.Builder(context,R.style.MyDialogTheme);
    builder.setTitle("Are you sure you want to delete " + productList.get(position).getProduct_name());
    builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            productList.remove(position);
            itemClickListener.onItemClick(productList);
            notifyDataSetChanged();
            dialog.dismiss();
        }
    });
    builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            productList.get(position).setOrderQuantity(1);
            dialog.dismiss();
        }
    });
    AlertDialog dialog = builder.create();
    dialog.setCancelable(false);
    dialog.setCanceledOnTouchOutside(false);
    dialog.show();
}

// add items into spinner
public void addItemsOnSDiscountAndPreselect(ViewHolder viewHolder, int discount) {
    List<Integer> list = new ArrayList<Integer>();
    for(int index = 0; index <= 100; index++) {
        list.add(index);
    }
    ArrayAdapter<Integer> dataAdapter = new ArrayAdapter<Integer>(context,
            android.R.layout.simple_spinner_item, list);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    viewHolder.sDiscount.setAdapter(dataAdapter);

    int spinnerPosition = dataAdapter.getPosition(discount);
    viewHolder.sDiscount.setSelection(spinnerPosition);
}

private class SpinnerListener implements AdapterView.OnItemSelectedListener {

    private int mSpinnerPosition;
    private DiscountSpinnerListener discountSpinnerListener;
    private ViewHolder viewHolder;

    public SpinnerListener(ViewHolder viewHolder, int spinnerPosition, DiscountSpinnerListener discountSpinnerListener) {
        mSpinnerPosition = spinnerPosition;
        this.discountSpinnerListener = discountSpinnerListener;
        this.viewHolder = viewHolder;
    }

    @Override
    public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        float spinnerValue = Float.parseFloat(arg0.getItemAtPosition(arg2).toString());
        float discount = 1.0f - (spinnerValue/100.0f);
        float totalItemPrice = productList.get(mSpinnerPosition).getPrice_max() * productList.get(mSpinnerPosition).getOrderQuantity() * discount;
        productList.get(mSpinnerPosition).setOrderPrice(totalItemPrice);
        productList.get(mSpinnerPosition).setDiscount_per_item(Integer.parseInt(arg0.getItemAtPosition(arg2).toString()));

        // Listener to set total price of an item after discount
        discountSpinnerListener.onDiscountChange(viewHolder.tvQtyPrice, mSpinnerPosition, totalItemPrice);
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {
        // TODO Auto-generated method stub

    }
}
}

P / S:请先忽略要获得折扣价格的计算,因为它确实与我的两个折扣微调器发生冲突(最初我只是实现每件商品的折扣)。

这是我的应用的屏幕截图: 请参见此处

您正在适配器中使用orderList,但在计算折扣后是否更新了orderList?

如果您不更新orderList中的数据,则notifyDataSetChangeddoesnt实际上会执行任何操作。

希望能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM