Firebase ListView не обновляется в режиме реального времени - PullRequest
0 голосов
/ 17 января 2019

Когда я изменяю данные, отображаемые с помощью 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;
}

}

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Я предлагаю вам использовать уже встроенную библиотеку, чтобы список автоматически обновлялся, когда новые данные помещаются в базу данных: проверьте это Если вы хотите придерживаться пользовательской реализации, сначала определите адаптер в OnCreate обратном вызове и вызывайте adapter.notifyDataSetChanged() каждый раз, когда вы обновляете свои данные. Если вы хотите вставить / обновить / удалить только один элемент в вашем списке, вызовите adapter.notifyItemChanged(position) с вашего адаптера.

Я настоятельно рекомендую вам переключиться на RecyclerView вместо ListView в Android (интересное сравнение между ними)

0 голосов
/ 17 января 2019

Вы используете addListenerForSingleValueEvent(), который будет прослушивать только одно значение и затем останавливаться. Вам нужно использовать addValueEventListener().

0 голосов
/ 17 января 2019

Один из способов сделать это - добавить элементы в ArrayList<RequestItem> list, сделав их статическими в классе адаптера, а не в списке действий, который вы передаете адаптеру, тогда функция notifyDataSetChanged () будет работать, если вы хотите показать изменения в списке в реальном времени

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...