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 
    } 

Инициализация данных здесь случилось:

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 можно найти here, источник ExpandableListAdapter.java можно найти here и источник MainActivity.java можно найти here)

+1

Я уверен, что версия 'ExpandableListAdapter', с которой вы связаны, не является * той, которую вы используете, поскольку приведение к' NewsItem' происходит в строке 62, а не 66 :( –

+0

@JonSkeet Woops, я удалил несколько строк перед загрузкой. Теперь это действительно на линии 62. Спасибо, что заметили. :) – user1480019

+0

Это не поможет вам не показать, где вы инициализируете «ExpandableListAdapter», либо .. –

ответ

2

Как уже отмечалось, ваши ожидания оправдывают использование Arrays.asList(), а внесение в список ваших данных неверно и не будет работать. Когда вы используете SharedPreferences.Editor.putString(), вы вставляете String в предпочтениях, представляющих строку, возвращаемую List.toString() (которая будет печатать все ее дочерние элементы (с использованием toString()) в квадратных скобках). Когда вы вернете эту строку из настроек, вам нужно ее создать в ListNewsItems.Один из способов, как вы можете сделать это будет, как показано ниже:

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

Код выше, потребует изменений в toString() способе NewsItem класса:

@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 Что произойдет, если вы добавите строку 'sb.append ("; ");' в метод 'toString()' следующим образом: '... sb.append (" date = "); sb.append (дата); sb.append (";"); return sb.toString(); '? – Luksprog

+0

Я пробовал это, но потом повторится то же самое. – user1480019

2

Вам необходимо преобразовать String, вы получаете от SharedPreferences как-то к списку NewsItem. Только бросок этого не сделает.

1

это исключений означает, что вы пытаетесь назначить объект типа String в ссылочной переменной com.example.expandablelistview.NewsItem

я знаю, это не помогает много, но никак

0

Я не уверен, -

Можно ли преобразовать значения карты в список и поместить его в HashMap listDataChild?

Поскольку вы ищете, чтобы сохранить данные POJO в общих привилегированных целях. Вы можете использовать формат JSON, чтобы сериализовать ваш NewsItemList и объекты, которые он содержит, а затем сохранить как строку в SharedPreferences. Google-JSON - хороший api для этого.

Если вы хотите вернуть данные, извлеките String и используйте JSONArray для извлечения каждого объекта и добавления его в новый список NewsItemList.

В противном случае попробуйте сериализации вашего объекта приватного файла. Это поможет вам выйти за рамки putString(), putFloat(), putLong(), putInt() и putBoolean() для SharedPreferences. Спасибо.

Смежные вопросы