2017-09-17 73 views
0

所以我試圖用基於我的firebase數據庫上的一些信息的顏色來初始化每個日曆單元格,並且爲此我使用了一個設置爲false的標誌,然後如果條件成立得到滿足。問題是addListenerForSingleValueEvent是一個異步方法,所以標誌一直返回false。我應該如何處理它?在Firebase上處理異步addListenerForSingleValueEvent

mCalendar.addDecorator(new DayViewDecorator() { 
       @Override 
       public boolean shouldDecorate(final CalendarDay day) { 
        final boolean[] flag = {false}; 
        final String currentDate = day.getCalendar().get(Calendar.YEAR) 
          + "" + day.getCalendar().get(Calendar.MONTH) 
          + "" + day.getCalendar().get(Calendar.DAY_OF_MONTH); 

        database.child(currentDate).addListenerForSingleValueEvent(new ValueEventListener() { 
         @Override 
         public void onDataChange(DataSnapshot snapshot) { 
          if (snapshot.exists()) { 
           flag[0] = true; 
          } 
         } 

         @Override 
         public void onCancelled(DatabaseError databaseError) { 

         } 
        }); 

        return flag[0]; 
       } 

       @Override 
       public void decorate(DayViewFacade view) { 
        view.addSpan(new ForegroundColorSpan(
          ContextCompat.getColor(getApplicationContext(), R.color.material_red_a200))); 
       } 
      }); 

回答

1

爲了解決這個問題,將您的onDataChange()方法內部boolean[] flag陣列的聲明,否則將始終爲空。

public void onDataChange(DataSnapshot snapshot) { 
    final boolean[] flag = {false}; 
    if (snapshot.exists()) { 
     flag[0] = true; 
    } 
    Log.d("TAG", flag[0]); 
} 

這是由於onDataChange()方法,它甚至你試圖讓這個數組前值稱爲異步行爲發生。 在方法內部移動聲明並在那裏使用它,解決了你的問題。

如果你想使用該方法以外的數組的值,請看看這篇文章的答案How To Get Async Value Outside onDataChange() Method

+0

感謝您的回答,但我無法移動國旗,因爲我需要返回它。我知道,當我有onDataChange時,return語句是無用的,但除非發生返回,否則我無法更改UI。我使用mCalendar.addDecorator(新的DayViewDecorator()),它首先進入shouldDecorate方法,並在返回後返回裝飾方法,以便我需要一個布爾返回值。對不起,如果我不完全瞭解你 – Nick

+0

在這種情況下,你需要改變你的代碼流的邏輯,以在該方法中使用它。或者嘗試在該方法之外使用它,正如我在上面的帖子中所解釋的那樣。 –

+0

我也想過在裝飾方法中使用onDataChange,但這是不可能的,因爲我需要前一個方法中的「day」變量。從數據庫獲得價值後,有什麼方法可以執行回報嗎?我使用Bus看到了解決方案,但沒有多大幫助。 – Nick