Firebase ListView不能实时更新

时间:2019-01-17 10:38:23

标签: android listview firebase-realtime-database

当我更改使用ListViewDataSnapshot显示的数据时,直到我重新启动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;
}

}

3 个答案:

答案 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()