2017-09-17 67 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