检索Firebase数据后如何循环HashMap?

问题描述 投票:1回答:1

我在Android Studio中工作,并从Firebase检索以下数据:

coloursets:
   default:
      name: "Default colour set"
      description: "Default set of colours"
      colours:
          white:
             red: 255
             green: 255
             blue: 255
             name: "white"
          black:
             red: 0
             green: 0
             blue: 0
             name: "black"

我正在检索它:

public void initialiseColourSet(ValueEventListener listener) {

    if(this.key == null) return;

DatabaseReference mColourSetReference = FirebaseDatabase.getInstance().getReference()
        .child("coloursets").child(this.key);

mColourSetReference.addListenerForSingleValueEvent(listener);
}

其中“key”设置为“default”,“listener”为:

new ValueEventListener() {

  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
       ArrayList<ChartColour> colourList= new ArrayList<>();
       Map<String, HashMap> objectMap = (HashMap<String, HashMap>) dataSnapshot.getValue();

       // SOMETHING NEEDS TO GO HERE - SEE BELOW

       }

}

ColourSet类具有以下内容:

String key, name, description;
ArrayList<ChartColour> colours = new ArrayList<>();

所以,我想循环'objectMap'来获取colourSet名称和描述,然后将颜色列表放入局部变量colourList,然后用于在ColourSet对象中设置'colors'。

我只是无法在侦听器中获得正确的循环。我查了很多答案,但似乎没有一个适用于我的情况。

目前我在听众中有以下内容:

new ValueEventListener() {

   @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    ArrayList<ChartColour> colourList= new ArrayList<>();
    Map<String, HashMap> objectMap = (HashMap<String, HashMap>) dataSnapshot.getValue();
     for (Map.Entry<String, HashMap> entry : objectMap.entrySet()) {
       switch (entry.getKey()) {
         case "name":
           mColourSet.setName(String.valueOf(entry.getValue()));
           break;
         case "description":
           mColourSet.setDescription(String.valueOf(entry.getValue()));
           break;
         case "colours":
           // Need some kind of FOR LOOP here
             ChartColour colour = new ChartColour();
             /*
                colour.setKey(??);
                colour.setName(??);
                colour.setRed(??);
                   ... etc ... */
                colourList.add(colour);
           // END OF FOR LOOP
           mColourSet.setColours(colourList);
       }
     }
   }
});

所以,我只是不确定我需要在侦听器的FOR循环中放置什么,以便循环颜色。到目前为止我尝试的所有东西都给了我一条摇摆不定的红线,没有任何对错误的解释。

android firebase-realtime-database
1个回答
1
投票

我花了一些时间来查看你的代码,我注意到了一些似乎没有的东西。

首先,当我尝试实现ValueEventListener时,还有另一种方法需要实现。也许代码版本存在一些差异,但这可能是一个微不足道的问题。

@Override
public void onCancelled(DatabaseError error) { }

其次,dataSnapshot.getValue()返回值的类型转换不正确。样本数据与数据为Map<String, HashMap>的概念不匹配。 “名称”和“描述”条目显然是简单的Strings,而不是HashMaps。我想在运行时会失败。你更有可能投射到Map<String, ?>。从那时起,您将必须通知代码每个条目值的预期值,根据哪个键,它可以变化为StringMapInteger。如果我不得不猜测你的onDataChange方法应该是什么样子(根据你的样本数据),它看起来像这样:

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    @SuppressWarnings("unchecked")
    Map<String, ?> defaultColourSet = (Map<String, ?>)dataSnapshot.getValue();
    if (defaultColourSet == null) {
        /* log a warning, DataSnapshot.getValue may return null */
        return;
    }
    List<ChartColour> colourList= new ArrayList<>();
    for (Map.Entry<String, ?> colorSetEntry : defaultColourSet.entrySet()) {
        switch (colorSetEntry.getKey()) {
            case "name":
                mColourSet.setName((String)colorSetEntry.getValue());
                break;
            case "description":
                mColourSet.setDescription((String)colorSetEntry.getValue());
                break;
            case "colours":
                @SuppressWarnings("unchecked")
                Map<String, ?> colourMap = (HashMap<String, ?>)colorSetEntry.getValue();
                for (Map.Entry<String, ?> colourEntry : colourMap.entrySet()) {
                    @SuppressWarnings("unchecked")
                    Map<String, ?> colourValueMap = (Map<String, ?>)colourEntry.getValue();
                    ChartColour colour = new ChartColour();
                    // Note that the following calls are based on assumption...
                    colour.setName((String)colourValueMap.get("name"));
                    colour.setRed((Integer)colourValueMap.get("red"));
                    colour.setGreen((Integer)colourValueMap.get("green"));
                    colour.setBlue((Integer)colourValueMap.get("blue"));
                    colourList.add(colour);
                }
                mColourSet.setColours(colourList);
                break;
        }
    }
}

我已经在未经检查的强制转换发生的地方添加了@SupressWarnings("unchecked"),以指示强制转换是基于编译器无法获得的知识。它严格按照JSON数据的布局进行通知。它可能在运行时失败,特别是在数据发生变化时。我建议添加更强大的错误处理,比如try-catch来处理ClassCastException

© www.soinside.com 2019 - 2024. All rights reserved.