2017-06-18 82 views
0

我正在使用自定義適配器來顯示ListView中RequestDetails類型的對象。每個listView項目都有一個接受和拒絕按鈕。 單擊按鈕時,將對(Firebase)數據庫進行相應更改 - 在這兩種情況下,都會從數據庫中刪除請求,但我不知道如何刷新listView以反映數據庫中所做的更改。 我讀了notifyDataSetChanged(),但我不太清楚如何使用它在我的情況。如何更新動態刪除項目時適配器的listView數據?

下面是該onClickListeners在自定義適配器的按鈕代碼段(RequestAdapter)我創建:

acceptButton = (Button) listItemView.findViewById(R.id.accept_request_button); 
     denyButton = (Button) listItemView.findViewById(R.id.deny_request_button); 
     acceptButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       DatabaseReference requestsRef = FirebaseDatabase.getInstance().getReference().child("Requests"); 
       if(mIsOCRequest){ 
        HashMap<String,Object> tournamentStatus = new HashMap<String, Object>(); 
        tournamentStatus.put("isOrganizing",true); 
        tournamentStatus.put("isParticipating",false); 

        Toast.makeText(getContext(),"Requested Accepted",Toast.LENGTH_SHORT).show(); 
        userRef.child("tournamentStatuses").child(request.getTournamentId()).updateChildren(tournamentStatus); 

       } 
       else if(mIsParticipantRequest){ 
        HashMap<String,Object> tournamentStatus = new HashMap<String, Object>(); 
        tournamentStatus.put("isOrganizing",false); 
        tournamentStatus.put("isParticipating",true); 

        Toast.makeText(getContext(),"Requested Accepted",Toast.LENGTH_SHORT).show(); 
        userRef.child("tournamentStatuses").child(request.getTournamentId()).updateChildren(tournamentStatus); 
        //TODO: create a child in the user called sports which will have the tournamentID followed by the sport(s) 

       } 
       requestsRef.addValueEventListener(new ValueEventListener() { 
        @Override 
        public void onDataChange(DataSnapshot dataSnapshot) { 
         if(dataSnapshot.exists()){ 
          for(DataSnapshot requestLooper : dataSnapshot.getChildren()){ 
           RequestDetails retrievedRequest = requestLooper.getValue(RequestDetails.class); 
           if(retrievedRequest.equals(request)){ 
            requestLooper.getRef().removeValue(); 
            Log.d("Removing at",requestLooper.getRef().toString()); 
            notifyDataSetChanged(); 
           } 
          } 
         } 
        } 

        @Override 
        public void onCancelled(DatabaseError databaseError) { 

        } 
       }); 
      } 
     }); 

     denyButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       DatabaseReference requestsRef = FirebaseDatabase.getInstance().getReference().child("Requests"); 
       requestsRef.addValueEventListener(new ValueEventListener() { 
        @Override 
        public void onDataChange(DataSnapshot dataSnapshot) { 
         if(dataSnapshot.exists()) { 
          for (DataSnapshot requestLooper : dataSnapshot.getChildren()) { 
           RequestDetails requestDetails = requestLooper.getValue(RequestDetails.class); 
           if (requestDetails.equals(request)) { 
            requestLooper.getRef().removeValue(); 
            Log.d("Deny Button", "Request Removed"); 
            Log.d("Removing at",requestLooper.getRef().toString()); 
            notifyDataSetChanged(); 
            break; 
           } 
          } 
         } 
        } 

        @Override 
        public void onCancelled(DatabaseError databaseError) { 

        } 
       }); 
      } 
     }); 

出於某種原因,在點擊拒絕按鈕,該項目的副本我「刪除」被附加到listView ..

我敢肯定,我沒有正確使用notifyDataSetChanged()方法,因爲在我讀過的其他文章中,它總是被'適配器'對象調用。如果我嘗試這樣做,我得到一個錯誤'適配器'無法解決。

如果它有什麼用途,這裏的地方設置我的適配器活動的onCreate()代碼:

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_display_requests); 

     requestsRef = FirebaseDatabase.getInstance().getReference().child("Requests"); 

     final ArrayList<RequestDetails> requestDetailsArrayList = new ArrayList<>(); 

     requestsRef.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       if(dataSnapshot.exists()) { 
        for (DataSnapshot request : dataSnapshot.getChildren()) { 
         RequestDetails requestDetails = request.getValue(RequestDetails.class); 
         requestDetailsArrayList.add(requestDetails); 
        } 
       } 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 

     RequestAdapter requestAdapter = new RequestAdapter(this, requestDetailsArrayList); 
     ListView requestsListView = (ListView) findViewById(R.id.requests_list); 
     requestsListView.setAdapter(requestAdapter); 
    } 

誰能幫助我嗎?

提前致謝!

回答

1

適配器的工作方式是它需要一個arraylist作爲參數,並將其轉換爲一個「可表示的」列表以便在ListView中查看。 「notifyDataSetChanged」的工作方式是它在適配器上調用(這是真的),但是由於您在適配器類中調用它,因此編譯器正在以此方式讀取[this.notifyDataSetChanged],其中(這在這裏類似於適配器)。

現在爲您的問題。每當您接受或拒絕某個項目時,將相應的更改應用於Firebase數據庫,爲什麼會出現此問題,正如我前面所說的那樣,notifyDataSetChanged所做的所有操作都是檢查ArrayList中的更改並「刷新」本身,而listView基本上應用這些更改。嘗試訪問在您的自定義數組適配器的構造函數中傳遞的ArrayList,並在denyButton單擊偵聽器中,當您從請求套接字中刪除請求時,也將其從arrayList中移除。

相關問題