当我更改使用ListView
和DataSnapshot
显示的数据时,直到我重新启动Activity
为止,数据不会实时刷新。 ListView
会毫无问题地加载并显示所有数据。为什么会发生这种情况以及如何解决呢?
MainMenuRequest.java
public class MainMenuRequest extends AppCompatActivity {
String UserNameString;
DatabaseReference db;
ListView lv;
ArrayList<RequestItem> list = new ArrayList<>();
RequestItemAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu_request);
makeItem();
}
public void makeItem ()
{
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReferenceFromUrl("https://vsem-inventory.firebaseio.com/ItemRequest");
ValueEventListener valueEventListener = new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
list = new ArrayList<RequestItem>();
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dSnapshot.getChildren()) {
RequestItem Ri = ds.getValue(RequestItem.class);
Ri.setRefID(ds.getKey());
Log.d("myTag",ds.getKey());
list.add(Ri);
}
}
lv = findViewById(R.id.listViewRequest);
adapter = new RequestItemAdapter(MainMenuRequest.this,list);
lv.setAdapter(adapter);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("DatabaseError", databaseError.getMessage()); //Don't ignore errors!
}
};
rootRef.addListenerForSingleValueEvent(valueEventListener);
}
}
RequestItemAdapter.java
public class RequestItemAdapter extends ArrayAdapter<RequestItem> {
private Context ctx;
private ArrayList<RequestItem> list;
ImageView statusimg;
Drawable lateIcon;
Drawable paidIcon;
public RequestItemAdapter(Context context, ArrayList<RequestItem> list)
{
super(context,0,list);
this.ctx = context;
this.list = list;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItem = convertView;
if(listItem == null)
listItem = LayoutInflater.from(ctx).inflate(R.layout.content_main_menu_request_list,parent,false);
final RequestItem rq = list.get(position);
final TextView tvAmount = listItem.findViewById(R.id.amountReq);
final TextView tvName = listItem.findViewById(R.id.nameReq);
final TextView tvSerial = listItem.findViewById(R.id.serialNoReq);
final TextView tvSupplier = listItem.findViewById(R.id.supplierNameReq);
final ImageView more = listItem.findViewById(R.id.moreReq);
statusimg = listItem.findViewById(R.id.statusReq);
lateIcon = listItem.getResources().getDrawable(R.drawable.late);
Drawable pendingIcon = listItem.getResources().getDrawable(R.drawable.pending);
String userName = rq.getRequestBy();
userName = userName.replace("@vsemtech.com","");
tvAmount.setText(userName);
tvName.setText(rq.getProductName());
tvSerial.setText(rq.getSerialNo());
tvSupplier.setText(rq.getCategory());
String status = rq.getStatus();
if(status.equals("REJECT"))
statusimg.setImageDrawable(lateIcon);
else if (status.equals("APPROVED"))
statusimg.setImageDrawable(paidIcon);
else if (status.equals("PENDING"))
statusimg.setImageDrawable(pendingIcon);
more.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
String RequestBy = rq.getRequestBy();
String Status = rq.getStatus();
String ProductName = rq.getProductName();
String SerialNo = rq.getSerialNo();
String Model = rq.getModel();
String Category = rq.getCategory();
String Quantity = rq.getQuantity();
String Remarks = rq.getRemarks();
showMenu(rq,more);
}
});
return listItem;
}
public void showMenu (RequestItem reqItem,ImageView More)
{
final RequestItem finalItem = reqItem;
final ImageView more = More;
final String shortRequestby = reqItem.getRequestBy().replace("@vsemtech.com","");
final DatabaseReference DeleteRef = FirebaseDatabase.getInstance().getReference().child("ItemRequest").child(shortRequestby);
final DatabaseReference DbRef = FirebaseDatabase.getInstance().getReference().child("ItemRequest").child(shortRequestby).child(finalItem.getRefID());
//Creating the instance of PopupMenu
PopupMenu popup = new PopupMenu(ctx, more);
//Inflating the Popup using xml file
popup.getMenuInflater().inflate(R.menu.menu_options_req, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.item_approve)
{
DeleteRef.child(finalItem.getRefID()).removeValue();
writeNewPost(new RequestItem(finalItem,"APPROVED"));
Toast.makeText(ctx,"Successfully approved request made by " + shortRequestby ,Toast.LENGTH_SHORT).show();
}
else if (itemId == R.id.item_reject)
{
DeleteRef.child(finalItem.getRefID()).removeValue();
writeNewPost(new RequestItem(finalItem,"REJECTED"));
Toast.makeText(ctx,"Successfully rejected request made by " + shortRequestby ,Toast.LENGTH_SHORT).show();
}
return true;
}
});
popup.show();//showing popup menu
}
public void writeNewPost(RequestItem item)
{
DatabaseReference dbReq = FirebaseDatabase.getInstance().getReference().child("ItemHistory").child(item.getRequestBy().replace("@vsemtech.com",""));
String key = dbReq.push().getKey();
Map<String, Object> postValues = toMap(item);
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put(key, postValues);
dbReq.updateChildren(childUpdates);
}
public Map<String, Object> toMap(RequestItem item)
{
HashMap<String, Object> result = new HashMap<>();
result.put("ProductName", item.getProductName());
result.put("SerialNo", item.getSerialNo());
result.put("Quantity", item.getQuantity());
result.put("Category",item.getCategory());
result.put("Model", item.getModel());
result.put("RequestBy", item.getRequestBy());
result.put("Status",item.getStatus());
result.put("Remarks",item.getRemarks());
return result;
}
}
答案 0 :(得分:0)
执行此操作的一种方法是,您需要在此ArrayList<RequestItem> list
中添加元素,方法是在适配器类中将其设置为静态,而不是传递给适配器的活动中的列表,然后notifyDataSetChanged()函数将起作用如果您想实时显示列表中的更改
答案 1 :(得分:0)
我建议您使用内置库来使列表在Firebase中推送新数据时自动更新:check out this
如果要坚持使用自定义实现,请首先在OnCreate
回调中定义适配器,并在每次更新数据时调用adapter.notifyDataSetChanged()
。
如果您只想插入/更新/删除列表中的一项,请从适配器中调用adapter.notifyItemChanged(position)
。
我强烈建议您在Android (interesting comparison between them)中切换到RecyclerView
而不是ListView
答案 2 :(得分:0)
您正在使用addListenerForSingleValueEvent()
,它将仅侦听单个值,然后停止。您需要使用addValueEventListener()
。