2012-07-16 120 views
0

我目前正在使用SharedPreferences处理应用程序,并试图动态更改Prefs活动屏幕上显示的值。 在屏幕上,我有一个preferencelistview包含一年的月份和两个编辑框来存储关于所选月份的信息。在一个月的选择,我想几件事情发生:动态更改SharedPreferences

  1. 插入与选择的一个月数据库中的行(如果它没有被先前选择) - 这个我可以开始工作刚刚桃色
  2. 将sharedpreference编辑框的值更改为存储在数据库的行中的值 - 这是我遇到问题的地方
  3. 当编辑框更新时,它们应根据数据库更新数据库中的对应行选择月 - 工作没有问题。

所以,基本上,我的问题是项目#2。我有当一个新的月份从列表中选择一个检查一个函数:

public void setMonth(SharedPreferences sp) { 
      ContentValues cv = new ContentValues(); 
    cv.clear(); 

    int sel_month = Integer.valueOf(sp.getString("pActivityMonth", String.valueOf(this.month))); //listvew works with strings, convert to int 
    int stored_new = 0; //default value 
    int stored_ren = 0; //default value 

    Log.d(TAG, String.valueOf(sel_month)); 

    String[] col = { Database.C_MONTH, Database.C_QNEW, Database.C_QRENEW }; 
    String[] arg = { String.valueOf(sel_month) }; 

    Cursor c = db.query(Database.RR_TABLE, col, Database.C_MONTH + "=?", arg, null, null, null); 

    if (c.getCount()<1) { //New month, insert row 
     cv.put(Database.C_MONTH, sel_month); 
     db.insertWithOnConflict(Database.RR_TABLE, null, cv, SQLiteDatabase.CONFLICT_IGNORE); 
    } else { //row exists, get stored values 
     Log.d(TAG, "cursor count: " + String.valueOf(c.getCount())); 
     c.moveToFirst(); 
     stored_new = c.getInt(c.getColumnIndex(Database.C_QNEW)); 
     stored_ren = c.getInt(c.getColumnIndex(Database.C_QRENEW)); 
     Log.d(TAG, "stored_new: " + String.valueOf(stored_new)); 
    } 

      //Change edittext preferences to stored values 
    editor.putString("pNewQuota", String.valueOf(stored_new)); 
    editor.putString("pRenewQuota", String.valueOf(stored_ren)); 
    editor.apply(); 
    editor.commit(); 



} 

所以,我选择一个新的月(7月),点击的EditText上的选项来更新信息一个(可以说我进入20),然后选择一个不同的月份(8月),默认值为0.如果我再次点击edittext,对话框将继续显示20而不是0.如果我将此0更改为其他值,它会存储在数据库的正确行中,但是在更改为另一个月(例如,回到7月)之后,此值将继续保持不变。 我的Logcat显示函数抓取正确的值,并且正在运行putString。 PreferenceScreen无法自行更新?谢谢你的帮助。

+0

所以没有混淆:“编辑器”是活动的onCreate()方法中的全局集合。 – wileyCoyote 2012-07-16 22:15:21

回答

1

如果我理解正确,您似乎有一个PreferenceActivity同时使用SharedPreferences和SQLiteDatabase来保存/保存相同的数据。虽然PreferenceActivity看起来像为数据输入设计的预构建的ListView,但实际上它更多:PreferenceActivity会自动保存并将首选项加载到SharedPreferences,SharedPreferences是分配给您的应用程序并由Android OS管理的特殊数据存储区。

虽然打算存储首选项,但如果需要,可以使用SharedPreferences来保存一些数据;或者自动通过首选项,或手动调用编辑器。您可以以多种方式中断和/或修改此持久性,例如创建首选项子类以替换行为,使用OnPreferenceChangeListener修改行为或通过调用setPersistent(boolean)来切换持久性。

到以这种方式使用PreferenceActivity是创建与一个AdapterView,或者一个ListActivity一个活动,并使用SimpleCursorAdapter自动化数据绑定到视图的替代。

要回答你关于坚持在PreferenceActivity变化SharedPreferences的问题,我已经提供了一些粗略概述在上下文中的示例代码,并概述了几个潜在的问题点。它并不是要表达一个可用的解决方案,而是想要知道你需要什么以及在哪里,我希望这是一个明确的(如果是冗长的)方式,不应该太难以适应你的项目。

/* Preference value modification example. 
    * This is a code sample with some context, not a solution. 
    * @author codeshane.com 
    * */ 
    public class StackOverflow_Question_11513113 extends PreferenceActivity { 
     /* 

     */ 
     class MyPreferenceActivity extends PreferenceActivity { 
      //Preference keys that were either set in xml, or possibly in source via .setKey(): 
      private final String pref_group_key = "some_prefs_key"; 
      private final String list_pref_key = "some_list_key"; 
      private final String edittext_pref_key = "some_edittext_key"; 

      private PreferenceActivity mPreferenceActivity; /* the activity */ 
      private SharedPreferences mSharedPreferences; /* auto-saving preferences */ 
      private Editor mEdit; 
      private PreferenceScreen mPreferenceScreen; /* root of the preference hierarchy */ 
      private PreferenceGroup mPreferenceGroup; /* optional grouping of preferences */ 
      private ListPreference mListPreference; /* a pop-up selectable-items-list */ 
      private EditTextPreference mEditTextPreference; /* a pop-up text entry box */ 
      private int stored_new; 
      private int stored_ren; 

      /* ... */ 

      public void setMonth() { /*SharedPreferences sp*/ 

       /* ... */ 

       //int stored_new = 0; //default value 
       //int stored_ren = 0; //default value 

       /* ... */ 

       /* Should only call either apply() or commit(), not both; calling a .commit() after an .apply() can block the thread (always fun), 
       * not to mention they essentially do the same thing, just synchronously vs asynchronously. 
       * http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply() 
       * */ 
       // mEdit.apply(); //API level 9+, void, asynchronous. 
       // mEdit.commit(); //API level 1+, returns boolean, synchronous. 
      } 
      /* ... */ 

      @Override 
      public void onCreate(Bundle savedInstanceState) { 
       /* Called once when the Activity is created. */ 
       super.onCreate(savedInstanceState); 
       addPreferencesFromResource(R.xml.affirm_prefs); 
       /* ... */ 
      } 
      @Override 
      protected void onResume() { 
       super.onResume(); 
       /* Called when the Activity is created or comes to foreground. */ 
       if (null==mSharedPreferences){init(this);} 
       mSharedPreferences.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener); 
       /* manually load data from shared preferences that IS NOT REPRESENTED 
       * by a Preference already, or for which Persistent has been manually 
       * set to false. */ 
       stored_new = mSharedPreferences.getInt("stored_new", 0); //If not found, assigns a default value of 0. 
       stored_ren = mSharedPreferences.getInt("stored_ren", 0); //If not found, assigns a default value of 0. 
      } 
      @Override 
      protected void onPause() { /* Called when the Activity goes to background. */ 
       super.onPause(); 
       mSharedPreferences.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener); 
       /* manually save data to shared preferences that IS NOT REPRESENTED 
       * by a Preference already, or for which Persistent has been manually 
       * set to false. */ 
       mEdit.putInt("stored_new", stored_new); 
       mEdit.putInt("stored_ren", stored_ren); 
       mEdit.commit(); 
      } 
      private boolean init(PreferenceActivity activity){ 
       mPreferenceActivity = activity; // or PreferenceActivity.this; 
       mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 
       mPreferenceScreen = mPreferenceActivity.getPreferenceScreen(); 
       mPreferenceGroup = (PreferenceGroup)mPreferenceScreen.findPreference(pref_group_key); 
       mListPreference = (ListPreference)mPreferenceScreen.findPreference(list_pref_key); 
       mEditTextPreference = (EditTextPreference)mPreferenceScreen.findPreference(edittext_pref_key); 
       return true; 
      } 
      /* When registered to a preference, this listener is notified of changes before saving. 
      * */ 
      OnPreferenceChangeListener onPreferenceChangeListener = new OnPreferenceChangeListener(){ 
       public boolean onPreferenceChange(Preference preference, Object newValue) { 
        boolean persistNewValue = true; 
        /* This occurs when a user has changed a preference, but before it is persisted */ 
        /* this is a good place for your "setMonth" logic, 
        * at least in a PreferenceActivity*/ 
        updateElement(preference, newValue); 
        changeMoreStuffBonusMethod(preference); 
        return persistNewValue; 
      }}; 
      /* When registered to SharedPreferences, this listener is notified of all saves to SharedPreferences, even if the data is the same 
      * */ 
      OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new OnSharedPreferenceChangeListener(){ 
       public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 

       } 
      }; 
      private boolean updateElement(Preference prefUpdating, Object value){ 
       if (null==prefUpdating) return false; 
       /* This function is for manually changing the value before it 
       * is saved by the PreferenceActivity. */ 

       /* ... */ 

       /* Can match exact instances, such as our mListPreference */ 
       if (mListPreference.equals(prefUpdating)) { 
        /* set selected item by item's index id */ 
        mListPreference.setValueIndex(0); 
        /* or set selected item by item's key*/ 
        mListPreference.setValue("item_key");    
       } 

       /* Can also match by Class, such as any EditTextPreference */ 
       if (prefUpdating instanceof EditTextPreference){ 
        EditTextPreference etp = (EditTextPreference)prefUpdating; 
        String oldText = etp.getText(); 
        etp.setText("Some new text in edit text box"); /* or */ 
        etp.setText(String.valueOf(stored_new)); /* or */ 
        etp.setText(oldText.trim()); /* remove leading/trailing whitespace */ 
        etp.setText(dataModel.get(prefUpdating.getKey())); /* if you use a model.. */ 
       } 

       /* ... */ 
      } 
      private void changeMoreStuffBonusMethod(Preference prefUpdating){ 
       /* Change the preference text */ 
       prefUpdating.setTitle("Click Me!"); 
       prefUpdating.setSummary("I am a cool preference widget!"); 

       /* Change the pop-up list (not items) text */ 
       if (prefUpdating instanceof ListPreference){ 
        ListPreference lp = (ListPreference)prefUpdating; 
        lp.setDialogTitle("I am the pop-up."); 
        lp.setDialogMessage("Select something from my list."); 
       } 
       /* If persistent, PreferenceActivity should handle saving: */ 
       Log.v(TAG,prefUpdating.getClass().getSimpleName()+".isPersistent="+String.valueOf(mListPreference.isPersistent())); 
      } 
     } 
    }