2014-02-11 4 views
1

Так что я узнаю о SharedPreferences в Android.Android SharedPreferences не меняется

Я думал, что быстро попытаюсь сделать что-то простое. Когда пользователь выбирает конкретную опцию из списка опций (в этом случае 3 варианта) - соответственно изменится файл макета. Тем не менее, он всегда принимает значение по умолчанию, поэтому никогда не меняет макет при выборе другого параметра - поэтому, когда выбран другой параметр, он записывается в порядке, но макет не меняется, это заставляет меня поверить, что возможно проблема, возникающая при получении предпочтений в первую очередь, мне было интересно, может ли кто-нибудь быстро взглянуть на что-то очевидное или не так очевидно с их опытом/мудростью - вот код:

MainActivity.java:

package com.example.preferenceslayout; 

import android.app.Activity; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 
import android.os.Bundle; 
import android.preference.PreferenceManager; 
import android.view.Menu; 
import android.view.MenuItem; 

public class MainActivity extends Activity 
    implements OnSharedPreferenceChangeListener { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     loadPreferences(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    public boolean onOptionsItemSelected(MenuItem item) { 
     switch(item.getItemId()) { 
     case R.id.preferences: 
      startActivity(new Intent(getApplicationContext(), 
        AppPreferences.class)); 
      break; 
     } 
     return false; 
    } 

    public void loadPreferences() { 
     SharedPreferences prefs = getApplicationContext(). 
      getSharedPreferences("mode", MODE_PRIVATE); 
     int layoutPref = prefs.getInt("mode", 10); 
     switch(layoutPref) { 
     case 10: 
      setContentView(R.layout.activity_main); 
      break; 
     case 20: 
      setContentView(R.layout.second_layout); 
      break; 
     case 30: 
      setContentView(R.layout.third_layout); 
      break; 
     } 
     prefs.registerOnSharedPreferenceChangeListener(MainActivity.this); 
    } 

    @Override 
    public void onSharedPreferenceChanged(SharedPreferences arg0, String arg1) { 
     loadPreferences();  
    } 
} 

preference.xml:

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 
    <ListPreference 
     android:key="mode" 
     android:title="@string/mode" 
     android:defaultValue="1" 
     android:summary="@string/summary" 
     android:entries="@array/listArray" 
     android:entryValues="@array/listValues" /> 
</PreferenceScreen> 

AppPreferences.xml:

package com.example.preferenceslayout; 

import android.os.Bundle; 
import android.preference.PreferenceActivity; 

public class AppPreferences extends PreferenceActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.preference); 
    } 
} 

main.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item 
     android:id="@+id/action_settings" 
     android:orderInCategory="100" 
     android:showAsAction="never" 
     android:title="@string/action_settings"/> 
    <item 
     android:id="@+id/preferences" 
     android:title="Preferences" /> 
</menu> 

PreferencesLayoutManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.preferenceslayout" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="18" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.example.preferenceslayout.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity android:name="com.example.preferenceslayout.AppPreferences"> 
      <intent-filter> 
       <action android:name=".AppPreferences" /> 
      </intent-filter> 
     </activity> 
    </application> 
</manifest> 

array.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string-array name="listArray"> 
     <item>10</item> 
     <item>20</item> 
     <item>30</item> 
    </string-array> 
    <string-array name="listValues"> 
     <item>1</item> 
     <item>2</item> 
    </string-array> 
</resources> 
+1

Я заметил, что у вас нет константы или строки R для имени вашего файла настроек. Мне нравится использовать app_name, поэтому я могу легко повторно использовать класс предпочтений с любым приложением. SharedPreferences sharedPref = context.getSharedPreferences (context.getString (R.string.app_name), Context.MODE_PRIVATE); – danny117

+0

Еще лучше использовать общие настройки по умолчанию –

ответ

2

Вы никогда напишите в соответствии с вашими предпочтениями. Вам понадобится prefs.putInt("mode", some_int);. Также ваш слушатель не имеет никакой цели - отбросьте его.

Вы пишете на по умолчанию общие настройки вызывают настройки экранов. «Режим» - это всего лишь ключ - есть один ключ в стандартных настройках по умолчанию и один в вашем файле предпочтений (с именем «mode_something.xml»), но вы пишете одно (автоматически через экран настроек), и вы читаете другое (который никогда не установлен)

+0

Существует PreferenceActiviy с ListPreference, где устанавливается «режим». Ну, слушатель может быть действительно сброшен, да :-) – donfuxx

+0

@donfuxx: Я думал, что вы были OP: D - вы уверены, что он установлен в задании Preference, которое он опубликовал? ;) –

+0

@Mr_and_Mrs_D, я напечатал его, и он определенно установлен. – user2405469

1

Я Ждут» т выглядят слишком глубоко в ваш код, но после краткого обзора следующие поймала мое внимание:

вы настраиваете это в вашем ListPreference в вашем preference.xml

android:entries="@array/listArray" 
android:entryValues="@array/listValues" 

, но в вашем array.xml у вас есть 3 в вашей строки записи массива и только 2 вещи в вашей listValues ​​строкового массива

<string-array name="listArray"> 
    <item>10</item> 
    <item>20</item> 
    <item>30</item> 
</string-array> 
<string-array name="listValues"> 
    <item>1</item> 
    <item>2</item> 
</string-array> 

Вы должны добавить третий пункт к вашему listValues ​​строкового массива

BTW: вам следует рассмотреть возможность переименования «listArray», чтобы было более ясно, что он содержит записи вашего списка. Поэтому, возможно, назовите это «listEntries». (не забудьте также изменить ссылку на android:entries="@array/listEntries"). В общем, записи - это то, что пользователь действительно видит, значения - это то, что использует андроид.Так, например, ваша строка массив может выглядеть примерно так:

<string-array name="listEntries"> 
    <item>one apple</item> 
    <item>two apples</item> 
    <item>three apples</item> 
</string-array> 
<string-array name="listValues"> 
    <item>1</item> 
    <item>2</item> 
    <item>3</item> 
</string-array> 
+0

Спасибо @donfuxx - это действительно помогает, это более понятно именно так, не заметил недостающий элемент. – user2405469

1

onSharedPreferenceChanged будет вызываться каждый раз, когда вы изменить свои предпочтения, поэтому не создавать новый SharedPreferences объекта каждый раз, когда вы изменяете предпочтение, какой вы должны сделать, это:

во-первых, сделать SharedPreferences атрибут класса, так что вы можете получить доступ к предпочтению везде в вашей деятельности:

private SharedPreferences prefs; 

Теперь внутри OnCreate() вызова:

prefs=PreferenceManager.getDefaultSharedPreferences(this); 
prefs.registerOnSharedPreferenceChangeListener(this); 

И, наконец, ваши loadPreferences() метод должен выглядеть следующим образом:

public void loadPreferences() { 

    int layoutPref = prefs.getInt("mode", 10); 
    switch(layoutPref) { 
    case 10: 
     setContentView(R.layout.activity_main); 
     break; 
    case 20: 
     setContentView(R.layout.second_layout); 
     break; 
    case 30: 
     setContentView(R.layout.third_layout); 
     break; 
    } 

} 

Надеется, что это помогает!

+0

Спасибо, Рик действительно помогает, очень цените это :) – user2405469

+0

Рад это слышать !! если бы было полезно для вас, вы могли бы пометить этот ответ как принятый или проголосовать? Спасибо :) – r1ckr

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