我有一个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();
}
});
}
答案 0 :(得分:0)
如果需要更新单击的项目,则可以使用const { isMainThread } = require("worker_threads");
var bcrypt;
if (isMainThread) bcrypt = require("bcrypt");
let bcryptFunction = (...param) => {
if (bcrypt == undefined) return Promise.reject("Not in main threads")
return bcrypt.hash(...param)
}
仅更新一个视图而不重新构建所有列表,或者使用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());
此项已更改,需要重新绘制。答案 1 :(得分:0)
您可以将与单击事件和菜单事件有关的所有逻辑移到适配器类.loc[3:5]
中,然后在数据集更改后,您可以在单击方法中的那些适配器上执行那个adapter.notifyDatasetChanged()。您需要将这些逻辑移至该类。并将InventoryAdapter
用作仅包含数据的数据类。