android - 通过单击项目的按钮更新 RecyclerView 项目
问题描述
我有一个 RecyclerView 显示有关某些产品的详细信息。每个 recyclerview 项目都包含详细信息,例如产品名称、库存数量和售价。还有一个用于销售产品的按钮。
当我点击按钮时,会打开一个alertDialog询问要出售的数量,在出售一定数量后,数据库中的库存会按预期更改,但在alertDialog关闭后recyclerview项目没有更新。如果我去其他活动并回来,recyclerview 项目将更新,但我希望它在 alertDialog 关闭后立即更新。
我检查了其他类似的问题,但我无法解决。最常见的答案是放
adapter.notifyDatasetChanged()
在创建 recyclerview 对象的活动中......但是在哪里?因为接收数量的警报对话框的代码在 ViewHolder 类中。如何从活动类中调用上述内容?
下面是我的活动代码,它有 recyclerview。
public class Inventory extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
RecyclerView recyclerInventory;
RecyclerView.LayoutManager layoutManager;
List<Product> inventory = new ArrayList<>();
InventoryAdapter adapter;
TextView emptyView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inventory);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(R.string.title_activity_inventory);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.add_item);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(Inventory.this, AddItem.class));
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.inventory_navigation_drawer_open, R.string.inventory_navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
recyclerInventory = (RecyclerView) findViewById(R.id.recycler_home);
emptyView = (TextView) findViewById(R.id.empty_image);
layoutManager = new GridLayoutManager(this, 1, RecyclerView.VERTICAL, false);
recyclerInventory.setLayoutManager(layoutManager);
loadProductList();
//InventoryAdapter adapter = new InventoryAdapter(new MSDatabase(this).getProducts(), this);
}
private void loadProductList() {
inventory = new MSDatabase(this).getProducts();
adapter = new InventoryAdapter(inventory, this,new ItemClickListener() {
@Override
public void onItemClick(int position) {
}
});
adapter.notifyDataSetChanged();
recyclerInventory.setAdapter(adapter);
if(adapter.getItemCount() > 0) {
recyclerInventory.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
else {
recyclerInventory.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.inventory, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Inventory/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
还有我的 InventoryAdapter 和 ViewHolder 类
class InventoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnCreateContextMenuListener {
TextView productName, inStock, sellingPrice;
FButton sellButton, purchaseButton, deleteButton;
private WeakReference<ItemClickListener> listenerRef;
EditText sellQuantity;
List<Product> inventory = new ArrayList<>();
InventoryAdapter adapter;
public InventoryViewHolder(View prodView) {
super(prodView);
productName = (TextView) prodView.findViewById(R.id.product_name);
inStock = (TextView) prodView.findViewById(R.id.product_in_stock);
sellingPrice = (TextView) prodView.findViewById(R.id.product_sellingprice);
sellButton = (FButton) prodView.findViewById(R.id.btn_sell);
purchaseButton = (FButton) prodView.findViewById(R.id.btn_purchase);
deleteButton = (FButton) prodView.findViewById(R.id.btn_delete);
sellButton.setOnClickListener(this);
purchaseButton.setOnClickListener(this);
deleteButton.setOnClickListener(this);
prodView.setOnCreateContextMenuListener(this);
}
@Override
public void onClick(View v) {
if(v.getId() == sellButton.getId())
{
AlertDialog.Builder builder1 = new AlertDialog.Builder(v.getContext());
builder1.setMessage("Select quantity");
builder1.setCancelable(true);
Context context = v.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View sell_dialog_layout = inflater.inflate(R.layout.sell_product_layout,null);
builder1.setView(sell_dialog_layout);
builder1.setIcon(R.drawable.ic_warning_black_24dp);
sellQuantity = (EditText) sell_dialog_layout.findViewById(R.id.elegent_number_button);
builder1.setPositiveButton(
"OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id)
{
//Toast.makeText(v.getContext(),"Qty:" + sellQuantity.getText().toString() + " sell position:" + String.valueOf(getAdapterPosition()+1) , Toast.LENGTH_SHORT).show();
new MSDatabase(v.getContext()).sellProduct(getAdapterPosition(), Double.parseDouble(sellQuantity.getText().toString())), v.getContext());
}
});
builder1.setNegativeButton(
"Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
else if(v.getId() == purchaseButton.getId())
{
//Toast.makeText(v.getContext(), "purchase position:" + String.valueOf(getAdapterPosition()+1), Toast.LENGTH_SHORT).show();
// Yet to be done
AlertDialog.Builder builder1 = new AlertDialog.Builder(v.getContext());
builder1.setMessage("Select quantity");
builder1.setCancelable(true);
Context context = v.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View sell_dialog_layout = inflater.inflate(R.layout.sell_product_layout,null);
builder1.setView(sell_dialog_layout);
builder1.setIcon(R.drawable.ic_warning_black_24dp);
sellQuantity = (EditText) sell_dialog_layout.findViewById(R.id.elegent_number_button);
builder1.setPositiveButton(
"OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id)
{
Toast.makeText(v.getContext(),"Qty:" + sellQuantity.getText().toString() + " sell position:" + String.valueOf(getAdapterPosition()+1) , Toast.LENGTH_SHORT).show();
}
});
builder1.setNegativeButton(
"Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
else if(v.getId() == deleteButton.getId())
{
Toast.makeText(v.getContext(), "delete position:" + String.valueOf(getAdapterPosition()+1), Toast.LENGTH_SHORT).show();
// Yet to be done
}
try {
ItemClickListener checknull = listenerRef.get();
}
catch (Exception e){
Log.v("InventoryViewHolder: ","WeakReference.get() is null");
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle(R.string.select_an_action);
menu.add(0, 0, getAdapterPosition(), Common.UPDATE);
menu.add(0,0,getAdapterPosition(),Common.DELETE);
}
}
public class InventoryAdapter extends RecyclerView.Adapter<InventoryViewHolder> {
private List<Product> listData = new ArrayList<>();
private Context context;
private ItemClickListener listener;
public InventoryAdapter(List<Product> listData, Context context, ItemClickListener listener) {
this.listData = listData;
this.context = context;
this.listener = listener;
}
@NonNull
@Override
public InventoryViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View prodView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.inventory_product_layout, viewGroup, false);
return new InventoryViewHolder(prodView);
}
@Override
public void onBindViewHolder(@NonNull final InventoryViewHolder inventoryViewHolder, int i) {
inventoryViewHolder.productName.setText(listData.get(i).getProductName());
inventoryViewHolder.inStock.setText(String.valueOf(listData.get(i).getProductInStock()));
inventoryViewHolder.sellingPrice.setText(String.valueOf(listData.get(i).getProductSellingPrice()));
}
@Override
public int getItemCount() {
return listData.size();
}
public void setData(List<Product> data){
this.listData = data;
notifyDataSetChanged();
// where this.data is the recyclerView's dataset you are
// setting in adapter=new Adapter(this,db.getData());
}
}
在数据库类中销售产品的方法如下。
public void sellProduct(int rowId, double quantityChange, Context context) {
SQLiteDatabase db = getReadableDatabase();
Product selectedProduct = getSelectedProduct(String.valueOf(rowId));
Log.v("Check name: ", selectedProduct.getProductName());
//Log.v("Check inStock: ", String.valueOf(selectedProduct.getProductInStock()));
ContentValues cv = new ContentValues();
cv.put("ProductName", selectedProduct.getProductName());
cv.put("InStock", selectedProduct.getProductInStock() - quantityChange);
cv.put("CostPrice", selectedProduct.getProductCostPrice());
cv.put("SellingPrice", selectedProduct.getProductSellingPrice());
cv.put("Description", selectedProduct.getProductDescription());
cv.put("PurchaseDate", selectedProduct.getDateOfPurchase());
cv.put("ExpiryDate", selectedProduct.getDateOfExpiry());
cv.put("GstRate", selectedProduct.getGstRate());
cv.put("GstAmount", selectedProduct.getGstAmount());
int result = db.update("Inventory", cv, "rowid = ?", new String[]{String.valueOf(rowId+1)});
if(result > 0) {
Toast.makeText( context, "Sold successfully !", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText( context, "Try again !", Toast.LENGTH_LONG).show();
}
}
我承认有类似的问题,但答案根本不适合我,请帮忙。
更新:
我在 onBindViewHolder 中使用了侦听器
@Override
public void onBindViewHolder(@NonNull final InventoryViewHolder inventoryViewHolder, int i) {
inventoryViewHolder.productName.setText(listData.get(i).getProductName());
inventoryViewHolder.inStock.setText(String.valueOf(listData.get(i).getProductInStock()));
inventoryViewHolder.sellingPrice.setText(String.valueOf(listData.get(i).getProductSellingPrice()));
inventoryViewHolder.sellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(v.getContext());
builder1.setMessage("Select quantity");
builder1.setCancelable(true);
Context context = v.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View sell_dialog_layout = inflater.inflate(R.layout.sell_product_layout,null);
builder1.setView(sell_dialog_layout);
builder1.setIcon(R.drawable.ic_warning_black_24dp);
sellQuantity = (EditText) sell_dialog_layout.findViewById(R.id.elegent_number_button);
builder1.setPositiveButton(
"OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id)
{
//Toast.makeText(v.getContext(),"Qty:" + sellQuantity.getText().toString() + " sell position:" + String.valueOf(getAdapterPosition()+1) , Toast.LENGTH_SHORT).show();
new MSDatabase(v.getContext()).sellProduct(i, Double.parseDouble(sellQuantity.getText().toString())));
notifyItemChanged(i);
Log.v("Position: ", String.valueOf(i));
}
});
builder1.setNegativeButton(
"Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
});
}
解决方案
如果需要更新单击的项目,您可以使用notifyItemChanged()
仅更新一个视图而不是重建所有列表,或者notifyItemRemoved()
如果项目已从列表中删除。
因此,如果您需要更新项目值并在警报后仅重建此项目,您可以尝试在对话框中插入类似的内容(下面提供的描述):
builder1.setPositiveButton(
"OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ExampleItem item = list.get(holder.getAdapterPosition());
notifyItemChanged(holder.getAdapterPosition());
Toast.makeText(v.getContext(), "Item number: " + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
list
- 是你的清单,那个清单在RecyclerView
.item
- 您单击的位置的元素。holder.getAdapterPosition()
- 单击的位置,您可以将所有更改应用于RecyclerView
元素或list
借助它。notifyItemChanged(holder.getAdapterPosition());
- 您通知RecyclerView
此项目已更改,需要重新绘制。
推荐阅读
- here-api - 使用折线路由结果沿路线进行 POI 搜索的问题
- reactjs - Material UI:在 React 类组件中使用主题
- phpbb - PHPBB 3.0.1 网站迁移到新的托管服务
- c# - 无法添加实体类型“Publication”的种子实体,因为没有为所需属性“Image”提供值
- python-3.x - 使用 Matplotlib 设置多组次要刻度
- java - Firebase 退出 Google
- arrays - StreamBuilder arrayContains 和 RangeError(index):无效值:有效值范围为空:0
- python-3.x - parse() 缺少 1 个必需的位置参数:'stream'
- c++ - 隐式转换序列的排序[f(int)和f(const int&)]
- android - 尝试在空对象引用上调用虚拟方法“void androidx.lifecycle.ViewModel.clear()”