2013-08-24 45 views
4

我試圖將expandablelistview子數據保存到SharedPreferences。保存正在工作,但是當我嘗試加載它時,我得到錯誤。java.lang.String不能轉換爲com.example.expandablelistview.NewsItem

問題:

當試圖加載設置,並把它放在一個HashMap我得到這些錯誤(短至3行):

08-24 12:40:05.138: E/AndroidRuntime(807): FATAL EXCEPTION: main 
08-24 12:40:05.138: E/AndroidRuntime(807): java.lang.ClassCastException: java.lang.String cannot be cast to com.example.expandablelistview.NewsItem 
08-24 12:40:05.138: E/AndroidRuntime(807): at com.example.expandablelistview.ExpandableListAdapter.getChildView(ExpandableListAdapter.java:62) 

爲了節約,我會用數據此代碼:

SharedPreferences pref = context.getSharedPreferences("myPrefs", MODE_PRIVATE); 
    SharedPreferences.Editor editor= pref.edit(); 

    for(Entry<String, List<NewsItem>> entry : listDataChild.entrySet()) { 
      editor.putString(entry.getKey(), String.valueOf(entry.getValue())); // Save the values of listDataChild 
    } 

    editor.commit(); 

數據的輸出是:

Yesterday: [[ headline=51.17346, 3.2252, Speed=2.10KM/H, Direction=158, date=18-8-2013 13:37:32]] 
Older: [[ headline=51.74346, 3.23252, Speed=2.00KM/H, Direction=122, date=17-8-2013 11:40:30]] 
Today: [[ headline=51.07346, 3.35252, Speed=0.00KM/H, Direction=122, date=19-8-2013 18:50:42]] 

當試圖加載這些數據(在這裏發生的錯誤),並把它放在一個HashMap,我會用這個(from here):

for(Entry<String, ?> entry : pref.getAll().entrySet()) { 
     listDataChild.put(entry.getKey(), (List<NewsItem>) Arrays.asList(entry.getValue())); // Put it in listDataChild 
    } 

數據的初始化在這裏happend:

static void prepareListData(final Context context) { 
    listDataHeader = new ArrayList<String>(); 
    listDataChild = new HashMap<String, List<NewsItem>>(); 

    // Adding child data 
    listDataHeader.add("Today"); 
    listDataHeader.add("Yesterday"); 
    listDataHeader.add("Older"); 
    List<NewsItem> today = new ArrayList<NewsItem>(); 
    NewsItem newsData = new NewsItem(); 
    newsData.setHeadline("51.07346, 3.35252"); 
    newsData.setSpeed("0.00KM/H"); 
    newsData.setDirection("122"); 
    newsData.setDate("19-8-2013 18:50:42"); 
    today.add(newsData); 

    List<NewsItem> yesterday = new ArrayList<NewsItem>(); 
    newsData = new NewsItem(); 
    newsData.setHeadline("51.17346, 3.2252"); 
    newsData.setSpeed("2.10KM/H"); 
    newsData.setDirection("158"); 
    newsData.setDate("18-8-2013 13:37:32"); 
    yesterday.add(newsData); 

    List<NewsItem> older = new ArrayList<NewsItem>(); 
    newsData = new NewsItem(); 
    newsData.setHeadline("51.74346, 3.23252"); 
    newsData.setSpeed("2.00KM/H"); 
    newsData.setDirection("122"); 
    newsData.setDate("17-8-2013 11:40:30"); 
    older.add(newsData); 

    listDataChild.put(listDataHeader.get(0), today); 
    listDataChild.put(listDataHeader.get(1), yesterday); 
    listDataChild.put(listDataHeader.get(2), older); 
} 

試圖嘗試:

我試圖改變listdataChild.put將數據加載到這一點:

listDataChild.put(entry.getKey(), new ArrayList<NewsItem>((Collection<? extends NewsItem>) Arrays.asList(entry.getValue()))); 

而且這樣的:

listDataChild.put(entry.getKey(), (List<NewsItem>) new ArrayList(Arrays.asList(entry.getValue()))); 

但沒有任何結果。 (我已經得到了同樣的錯誤)

問:

是否有可能映射值轉換爲列表,並把它放在HashMap中listDataChild

還是應該使用newsData.setHeadline("Value");newsData.setSpeed("Value");等? (我不知道如何獲得在SharedPreferences列表具體數值)

(的NewsItem.java源可以發現hereExpandableListAdapter.java源可以發現here,和MainActivity.java源可以發現here

+1

我很肯定你鏈接到*的'ExpandableListAdapter'的版本不是你正在使用的版本,因爲對於'NewsItem'的轉換髮生在62行,而不是66: –

+0

@JonSkeet Woops,我已經在上傳之前刪除了幾行,現在確實已經在第62行。謝謝你的注意。:) – user1480019

+0

這對你沒有顯示你在初始化'ExpandableListAdapter'的位置沒有幫助。 –

回答

2

正如其他人已經指出的那樣,只是簡單地使用Arrays.asList()並轉換到您的數據列表的期望是不正確的,不會工作。在使用SharedPreferences.Editor.putString()時,您將在表示由List.toString()返回的字符串的首選項中插入String(它將在方括號中打印其所有子項(使用toString()))。當您從首選項中獲取此字符串時,您需要將其構建到的NewsItems。你如何能做到這一點的一種方法是象下面這樣:

for (Entry<String, ?> entry : pref.getAll().entrySet()) { 
        List<NewsItem> rowItems = new ArrayList<NewsItem>(); 
        // the string from the preferences as it was saved 
        String prefContent = (String) entry.getValue(); 
        // break against possible multiple NewsItems(I'm assuming that's 
        // why you use a List of NewsItems) for the same 
        // key (every NewsItem starts with * so we split after 
        // that(see the NewsItems.toString method)) 
        String[] newsItems = prefContent.split("\\*"); 
        for (String item : newsItems) { 
         // an item which doesn't have at least 50 characters 
         // isn't a valid NewsItem string representation(based on 
         // its toString() method) 
         if (item.length() > 50) { 
          // ; is the delimiter for the NewsItem's data 
          String[] components = item.split(";"); 
          NewsItem ni = new NewsItem(); 
          // for each of the four data components we split 
          // after = and then use the second value obtained as 
          // that will be the value for that component 
          ni.setHeadline((components[0].split("="))[1]); 
          ni.setSpeed((components[1].split("="))[1]); 
          ni.setDirection((components[2].split("="))[1]); 
          ni.setDate((components[3].split("="))[1]); 
          rowItems.add(ni); 
         } 
        } 
        listDataChild.put(entry.getKey(), rowItems); 
       } 

上面的代碼需要在NewsItem類的toString()方法的變化:

@Override 
public String toString() { 
    StringBuilder sb = new StringBuilder(); 
    sb.append("*headline="); 
    sb.append(headline); 
    sb.append(";"); 
    sb.append("speed="); 
    sb.append(speed); 
    sb.append(";"); 
    sb.append("direction="); 
    sb.append(direction); 
    sb.append(";"); 
    sb.append("date="); 
    sb.append(date); 
    return sb.toString(); 
} 
+0

謝謝!只有一件事,當我在'Date'字符串後面看到列表時,會顯示',',如果列表中的最後一項是'''',我該如何解決這個問題? – user1480019

+1

@GerritHoekstra如果在'toString()'方法中添加'sb.append(「;」)''這行:'... sb.append(「date =」); sb.append(日期); sb.append( 「;」);返回sb.toString();'? – Luksprog

+0

我試過了,但後來又發生了同樣的情況。 – user1480019

2

您需要將String轉換爲NewsItem列表。單獨演員不會那樣做。

1

這個例外意味着你正在嘗試一個String對象分配給com.example.expandablelistview.NewsItem引用變量

我更知道,這並不幫助,但任何方式

0

我不知道 -

是否有可能映射值轉換爲列表,並把它放在 HashMap中listDataChild?

正如您正在尋找將POJO數據保存在共享前綴中一樣。您可以使用JSON格式來序列化您的NewsItemList及其包含的對象,然後將其作爲String存儲到SharedPreferences中。 Google-JSON是一個很好的API。

當您想要取回數據時,請檢索字符串並使用JSONArray檢索每個對象並將其添加到新的NewsItemList中。

否則,請嘗試序列化您的對象到私人文件。這將幫助你超越SharedPreferences的putString(),putFloat(),putLong(),putInt()和putBoolean()。 謝謝。

相關問題