【发布时间】:2021-04-27 18:53:50
【问题描述】:
我正在开发一个 android 应用程序,我在手动更改 EditText 的值时以编程方式更改 EditText 的一些值。
- 当用户更改数量时,我将更改总价和售价值。
- 当用户更改销售价格时,我正在更改折扣值。
- 当用户更改折扣时,我正在更改销售价格值。
我在每个EditText 上添加了一个addTextChangedListener()。但在此之前,我已经为每个EditText 全局创建了TextWatcher 对象。
private TextWatcher quantityWatcher;
private TextWatcher priceWatcher;
private TextWatcher discountWatcher;
并定义onBindViewHolder()方法,这样每当我想在上面删除或添加TextChangedListener()时,我都可以轻松完成。
在以编程方式更改任何 EditText 的值之前,我将使用 removeTextChangedListener() 删除每个 TextWatcher 对象上的 addTextChangedListener(),以避免单独调用该函数。更改值并在其上重新注册侦听器后。
对于数量编辑文本
quantityWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("SocialCodia", "afterTextChanged: quantityWatcher Event Listener Called");
quantityEvent(holder);
}
};
折扣EditText。
priceWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("SocialCodia", "afterTextChanged: priceWatcher Event Listener Called");
priceEvent(holder);
}
};
出售价格编辑文本
discountWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("SocialCodia", "afterTextChanged: discountWatcher Event Listener Called");
discountInputEvent(holder);
}
};
我在更改 EditText 值时调用的方法。
private void priceEvent(ViewHolder holder) {
Log.d("SocialCodia", "PriceEvent Method Called");
unregisterTextWatcher(holder);
int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
String sellPriceString = holder.inputSalePrice.getText().toString().trim();
if (sellPriceString.trim().length()>0)
{
int sellPrice = Integer.parseInt(holder.inputSalePrice.getText().toString().trim());
int discount = percentage(sellPrice, totalPrice);
holder.inputSaleDiscount.setText(String.valueOf(discount));
}
else
{
holder.inputSaleDiscount.setText(String.valueOf(100));
}
registerTextWatchers(holder);
}
private void quantityEvent(ViewHolder holder)
{
Log.d("SocialCodia", "quantityEvent Method Called");
unregisterTextWatcher(holder);
String quan = holder.inputSaleQuantity.getText().toString().trim();
String per = holder.inputSaleDiscount.getText().toString().trim();
int quantity;
int percentage;
if (quan == null || quan.length()<1 || quan.isEmpty())
quantity = 1;
else
quantity = Integer.parseInt(quan);
if (per==null || per.length()<1)
percentage = 0;
else
percentage = Integer.parseInt(per);
int price = Integer.parseInt(holder.tvProductPrice.getText().toString());
int finalPrice = price*quantity;
holder.inputTotalPrice.setText(String.valueOf(finalPrice));
int salePrice = percentageDec(finalPrice,percentage);
holder.inputSalePrice.setText(String.valueOf(salePrice));
registerTextWatchers(holder);
}
private void discountInputEvent(ViewHolder holder) {
Log.d("SocialCodia", "discountInputEvent Method Called");
unregisterTextWatcher(holder);
int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
String per = holder.inputSaleDiscount.getText().toString().trim();
int percentage;
if (per==null || per.length()<1)
percentage = 0;
else
percentage = Integer.parseInt(per);
int price = percentageDec(totalPrice, percentage);
holder.inputSalePrice.setText(String.valueOf(price));
registerTextWatchers(holder);
}
private int percentage(int partialValue, int totalValue) {
Log.d("SocialCodia", "percentage Method Called");
Double partial = (double) partialValue;
Double total = (double) totalValue;
Double per = (100 * partial) / total;
Double p = 100 - per;
return p.intValue();
}
private int percentageDec(int totalValue, int per) {
Log.d("SocialCodia", "percentageDec Method Called");
if (per == 0 || String.valueOf(per).length() < 0)
return totalValue;
else {
Double total = (double) totalValue;
Double perc = (double) per;
Double price = (total - ((perc / 100) * total));
Integer p = price.intValue();
return p;
}
}
每个条件、逻辑或方法都运行良好。但是当我在recyclerview 中插入多个视图时。更改任何行 EditText 的值,除了当前插入的视图一次又一次地调用侦听器本身。
我试图找出确切的问题,但无法做到。
我的适配器类AdapterSaleEditable.java
public class AdapterSaleEditable extends RecyclerView.Adapter<AdapterSaleEditable.ViewHolder> {
private Context context;
private List<ModelSale> modelSaleList;
private String token;
private SharedPrefHandler sp;
private ModelUser user;
private boolean discountFlag = false;
private boolean priceEvenFlag = false;
private TextWatcher quantityWatcher;
private TextWatcher priceWatcher;
private TextWatcher discountWatcher;
public AdapterSaleEditable(Context context, List<ModelSale> modelSales) {
this.context = context;
this.modelSaleList = modelSales;
sp = SharedPrefHandler.getInstance(context);
user = sp.getUser();
token = user.getToken();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.row_sale_editable, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ModelSale sale = modelSaleList.get(position);
int productId = sale.getProductId();
int saleId = sale.getSaleId();
String productCategory = sale.getProductCategory();
String productName = sale.getProductName();
String productSize = sale.getProductSize();
String productBrand = sale.getProductBrand();
int productPrice = sale.getProductPrice();
int productQuantity = sale.getProductQuantity();
String productManufacture = sale.getProductManufacture();
String productExpire = sale.getProductExpire();
String createdAt = sale.getCreatedAt();
holder.tvProductName.setText(productName);
holder.tvProductSize.setText("(" + productSize + ")");
holder.tvProductCategory.setText(productCategory);
holder.tvProductPrice.setText(String.valueOf(productPrice));
holder.inputTotalPrice.setText(String.valueOf(productPrice));
holder.inputSaleQuantity.setText(String.valueOf(1));
holder.inputSalePrice.setText(String.valueOf(productPrice));
holder.inputSaleDiscount.setText(String.valueOf(0));
holder.tvProductBrand.setText(productBrand);
holder.tvProductManufacture.setText(productManufacture);
holder.tvProductExpire.setText(productExpire);
holder.tvCount.setText(String.valueOf(position + 1));
holder.cvSell.setOnLongClickListener(view -> {
showDeleteAlert(holder, sale, position);
return true;
});
quantityWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("SocialCodia", "afterTextChanged: quantityWatcher Event Listener Called");
quantityEvent(holder);
}
};
priceWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("SocialCodia", "afterTextChanged: priceWatcher Event Listener Called");
priceEvent(holder);
}
};
discountWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("SocialCodia", "afterTextChanged: discountWatcher Event Listener Called");
discountInputEvent(holder);
}
};
registerTextWatchers(holder);
//End on create method
}
private void registerTextWatchers(ViewHolder holder) {
Log.d("SocialCodia", "Registring Listener");
holder.inputSaleQuantity.addTextChangedListener(quantityWatcher);
holder.inputSalePrice.addTextChangedListener(priceWatcher);
holder.inputSaleDiscount.addTextChangedListener(discountWatcher);
}
private void unregisterTextWatcher(ViewHolder holder)
{
Log.d("SocialCodia", "UnRegistring Listener");
holder.inputSaleQuantity.removeTextChangedListener(quantityWatcher);
holder.inputSalePrice.removeTextChangedListener(priceWatcher);
holder.inputSaleDiscount.removeTextChangedListener(discountWatcher);
}
private void priceEvent(ViewHolder holder) {
Log.d("SocialCodia", "PriceEvent Method Called");
unregisterTextWatcher(holder);
int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
String sellPriceString = holder.inputSalePrice.getText().toString().trim();
if (sellPriceString.trim().length()>0)
{
int sellPrice = Integer.parseInt(holder.inputSalePrice.getText().toString().trim());
int discount = percentage(sellPrice, totalPrice);
holder.inputSaleDiscount.setText(String.valueOf(discount));
}
else
{
holder.inputSaleDiscount.setText(String.valueOf(100));
}
registerTextWatchers(holder);
}
private void quantityEvent(ViewHolder holder)
{
Log.d("SocialCodia", "quantityEvent Method Called");
unregisterTextWatcher(holder);
String quan = holder.inputSaleQuantity.getText().toString().trim();
String per = holder.inputSaleDiscount.getText().toString().trim();
int quantity;
int percentage;
if (quan == null || quan.length()<1 || quan.isEmpty())
quantity = 1;
else
quantity = Integer.parseInt(quan);
if (per==null || per.length()<1)
percentage = 0;
else
percentage = Integer.parseInt(per);
int price = Integer.parseInt(holder.tvProductPrice.getText().toString());
int finalPrice = price*quantity;
holder.inputTotalPrice.setText(String.valueOf(finalPrice));
int salePrice = percentageDec(finalPrice,percentage);
holder.inputSalePrice.setText(String.valueOf(salePrice));
registerTextWatchers(holder);
}
private void discountInputEvent(ViewHolder holder) {
Log.d("SocialCodia", "discountInputEvent Method Called");
unregisterTextWatcher(holder);
int totalPrice = Integer.parseInt(holder.inputTotalPrice.getText().toString().trim());
String per = holder.inputSaleDiscount.getText().toString().trim();
int percentage;
if (per==null || per.length()<1)
percentage = 0;
else
percentage = Integer.parseInt(per);
int price = percentageDec(totalPrice, percentage);
holder.inputSalePrice.setText(String.valueOf(price));
registerTextWatchers(holder);
}
private int percentage(int partialValue, int totalValue) {
Log.d("SocialCodia", "percentage Method Called");
Double partial = (double) partialValue;
Double total = (double) totalValue;
Double per = (100 * partial) / total;
Double p = 100 - per;
return p.intValue();
}
private int percentageDec(int totalValue, int per) {
Log.d("SocialCodia", "percentageDec Method Called");
if (per == 0 || String.valueOf(per).length() < 0)
return totalValue;
else {
Double total = (double) totalValue;
Double perc = (double) per;
Double price = (total - ((perc / 100) * total));
Integer p = price.intValue();
return p;
}
}
private void showDeleteAlert(ViewHolder holder, ModelSale sale, int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Are you sure want to delete?");
builder.setMessage("You are going to delete " + sale.getProductName() + ". The Sale Quantity of this product was " + sale.getSaleQuantity() + " and the total price was " + sale.getSalePrice());
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
deleteSoldProduct(sale.getSaleId(), position);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(context, "Deletion Canceled", Toast.LENGTH_SHORT).show();
}
});
builder.show();
}
private void deleteSoldProduct(int sellId, int position) {
Call<ResponseDefault> call = ApiClient.getInstance().getApi().deleteSoldProduct(sellId, token);
call.enqueue(new Callback<ResponseDefault>() {
@Override
public void onResponse(Call<ResponseDefault> call, Response<ResponseDefault> response) {
if (response.isSuccessful()) {
ResponseDefault responseDefault = response.body();
if (!responseDefault.isError()) {
TastyToast.makeText(context, responseDefault.getMessage(), Toast.LENGTH_SHORT, TastyToast.SUCCESS);
Helper.playSuccess();
Helper.playVibrate();
modelSaleList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, modelSaleList.size());
} else
TastyToast.makeText(context, responseDefault.getMessage(), Toast.LENGTH_SHORT, TastyToast.ERROR);
} else
Toast.makeText(context, "Request Isn't Success", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<ResponseDefault> call, Throwable t) {
t.printStackTrace();
}
});
}
public void updateList(List<ModelSale> list) {
modelSaleList = list;
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return modelSaleList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tvProductName, tvProductSize, tvProductCategory, tvSaleTime, tvProductPrice, tvProductBrand, tvProductManufacture, tvProductExpire, tvCount;
private EditText inputSaleQuantity, inputSaleDiscount, inputSalePrice, inputTotalPrice;
private CardView cvSell;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvProductName = itemView.findViewById(R.id.tvProductName);
tvProductSize = itemView.findViewById(R.id.tvProductSize);
tvProductCategory = itemView.findViewById(R.id.tvProductCategory);
tvSaleTime = itemView.findViewById(R.id.tvSaleTime);
tvProductPrice = itemView.findViewById(R.id.tvProductPrice);
inputSaleQuantity = itemView.findViewById(R.id.inputSaleQuantity);
inputSaleDiscount = itemView.findViewById(R.id.inputSaleDiscount);
inputSalePrice = itemView.findViewById(R.id.inputSalePrice);
tvProductBrand = itemView.findViewById(R.id.tvProductBrand);
tvProductManufacture = itemView.findViewById(R.id.tvProductManufacture);
tvProductExpire = itemView.findViewById(R.id.tvProductExpire);
inputTotalPrice = itemView.findViewById(R.id.inputTotalPrice);
tvCount = itemView.findViewById(R.id.tvCount);
cvSell = itemView.findViewById(R.id.cvSell);
}
}
}
我的片段。从我设置回收站视图的位置。 SellProductFragment.java
public class SellProductActivity extends AppCompatActivity {
private ImageView ivCloseDialog;
private RecyclerView recyclerView;
private EditText inputSearchProduct;
private static List<ModelProduct> modelProductList;
private AdapterProductSale adapterProductSale;
private int productId;
private ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sell_product);
init();
actionBar = getSupportActionBar();
actionBar.setTitle("Sell Product");
setRecyclerView();
inputSearchProduct.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
filter(editable.toString());
}
});
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_close,menu);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id==R.id.miClose)
{
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
private void filter(String text)
{
List<ModelProduct> p = new ArrayList<>();
for(ModelProduct sale : modelProductList)
{
if (sale.getProductName().toLowerCase().trim().contains(text.toLowerCase()))
{
p.add(sale);
}
}
adapterProductSale.updateList(p);
}
private void setRecyclerView() {
LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
modelProductList = DbHandler.getModelProductList();
adapterProductSale = new AdapterProductSale(SellProductActivity.this, modelProductList);
recyclerView.setAdapter(adapterProductSale);
}
private void init() {
recyclerView = findViewById(R.id.rvProducts);
inputSearchProduct = findViewById(R.id.inputSearchProduct);
modelProductList = new ArrayList<>();
}
}
我该如何解决这个问题。
-感谢您的帮助!
【问题讨论】:
标签: java android android-recyclerview android-edittext listener