2017-10-14 78 views
1

我Android Studio中工作,並檢索從火力地堡以下數據:如何在檢索Firebase數據後循環訪問HashMap?

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); 

}

,其中 「關鍵」 是設置爲「默認」,「聽衆」是:

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類ha S中的以下內容:

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

所以,我要循環「ObjectMap的」,讓colourSet名稱和描述,然後得到的顏色列表到本地變量colourList,然後將其用於設置「顏色'在ColourSet對象中。

我只是無法在偵聽器中獲得正確的循環。我查了很多答案,但沒有一個似乎適用於我的案例。

目前我已在聽衆中的以下內容:

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循環的監聽器,以循環在顏色。我到目前爲止所嘗試的所有東西都只是給了我一個閃爍的紅線,而沒有任何解釋什麼是錯的。

任何人都可以告訴我嗎?感謝您提供任何幫助。

+1

我不確定你的紅色曲線在哪裏,但你的'HashMap'作爲外部映射的值類型沒有設置泛型類型,這意味着鍵和值都解析爲'Object' 。 – Dave

+0

謝謝。你的意思是objectMap嗎?他們應該設置什麼? – Sharon

+1

我的意思是在'Map '中,'HashMap'部分沒有指定類型參數,所以它實際上是'HashMap '。我想在這種情況下它需要是'HashMap '。這可能很容易導致代碼中的一些扭曲的紅線,但不知道錯誤的位置,我無法確定。我還沒有試圖運行你的代碼呢... – Dave

回答

1

我花了一點時間來看看你的代碼,並且我注意到一些看起來沒有的東西。

首先,當我嘗試實施ValueEventListener時,還有另一種方法需要實施。也許代碼版本有一些區別,但這可能是一個微不足道的問題。

@Override 
public void onCancelled(DatabaseError error) { } 

其次,你的類型轉換爲dataSnapshot.getValue()的返回值可以是不正確的。樣本數據與數據爲Map<String, HashMap>的概念不匹配。 「名稱」和「描述」條目顯然是簡單的,而不是HashMap s。我會想象在運行時失敗。這很可能是你應該鑄造到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

+0

謝謝!是的,我有OnCancelled,只是沒有把它放在這裏,以節省空間 - 道歉,我應該明確表示。 – Sharon

+0

我會檢查其餘的,看看我如何繼續。非常感謝你的幫助。 – Sharon

+0

謝謝!這使事情變得更清晰。我沒有意識到我可以放一個?在Map定義中 - 我試圖使用HashMap,然後將其轉換爲我所需要的,這顯然不起作用。我現在將處理錯誤處理 - 只是想讓事情先行。再次感謝你的幫助! – Sharon