0

Android에서 SharedPreferences에 대한 많은 질문이있었습니다. 이전에 요청한 사항이 많았지 만 아직까지 익숙하지 않았지만 SharedPreferences에 익숙하지 않기 때문에 그것을 작동시키는 마지막 몇 단계를 안다. 내 MainActivity에서Android - SharedPreferences ListPreference - PreferenceFragment onCreate가 호출되지 않음

나는 다음과 같습니다

public class MainActivity extends ActionBarActivity 
{ 
    ... 

    // Public static MainActivity so we can use findViewById from MyPrefsActivity 
    public static MainActivity mActivity; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     ... 

     mActivity = this; 
    } 

    ... 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     switch(id){ 
      case R.id.action_settings: 
       startActivity(new Intent(this, MyPrefsActivity.class)); 
       return true; 
     } 
     return false; 
    } 
} 

그리고 이것은 MyPrefsActivity.java입니다 :

package com.example.checkboxoptionsv2; 

import android.annotation.TargetApi; 
import android.content.SharedPreferences; 
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 
import android.os.Bundle; 
import android.preference.ListPreference; 
import android.preference.Preference; 
import android.preference.Preference.OnPreferenceChangeListener; 
import android.preference.PreferenceActivity; 
import android.preference.PreferenceFragment; 
import android.preference.PreferenceManager; 
import android.view.View; 
import android.widget.ImageButton; 

public class MyPrefsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener 
{ 
    private static int prefs = R.xml.settings; 
    private ImageButton cbButton, spinnerButton, popupButton; 
    private final String LIST_PREFERENCE = "prefCheckboxOption"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     try{ 
      getClass().getMethod("getFragmentManager"); 
      AddResourceApi11AndGreater(); 
     } 
     catch(NoSuchMethodException e){ // Android API < 11 
      AddResourceApiLessThan11(); 
     } 

     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); 
     preferences.registerOnSharedPreferenceChangeListener(this); 
*  ListPreference listPreference = (ListPreference) findPreference(LIST_PREFERENCE); 
     if(listPreference.getValue() == null) 
      listPreference.setValue("0"); 

     cbButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnCheckbox); 
     spinnerButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnSpinner); 
     popupButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnPopup); 

     setChosenPreference(0); 
    } 

    private void setChosenPreference(int chosen_value){ 
     // First put all Visibilities on GONE 
     cbButton.setVisibility(View.GONE); 
     spinnerButton.setVisibility(View.GONE); 
     popupButton.setVisibility(View.GONE); 

     // Then turn the chosen on VISIBLE again 
     switch(chosen_value){ 
      case 0: // Multi-Click CheckBox 
      default: 
       cbButton.setVisibility(View.VISIBLE); 
       break; 
      case 1: // Dropdown CheckBox 
       spinnerButton.setVisibility(View.VISIBLE); 
       break; 
      case 2: // Pop-up CheckBox 
       popupButton.setVisibility(View.VISIBLE); 
       break;   
     } 
    } 

    @Override 
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 
     if(key.equals(LIST_PREFERENCE)){ 
      ListPreference listPreference = (ListPreference) findPreference(key); // LIST_PREFERENCE 
      listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 
       @Override 
       public boolean onPreferenceChange(Preference preference, Object newValue) { 
        int chosen_option = Integer.valueOf((String) newValue); 
        setChosenPreference(chosen_option); 
        return false; 
       } 
      }); 
     } 
     else{ 
      // Other settings 
     } 
    } 

    @SuppressWarnings("deprecation") 
    protected void AddResourceApiLessThan11(){ 
     addPreferencesFromResource(prefs); 
    } 

    @TargetApi(11) 
    protected void AddResourceApi11AndGreater(){ 
*  MyPreferenceFragment pf = new MyPreferenceFragment(); 
     getFragmentManager().beginTransaction().replace(android.R.id.content, pf).commit(); 
    } 

    @TargetApi(11) 
    public static class MyPreferenceFragment extends PreferenceFragment{ 
     @Override 
     public void onCreate(Bundle savedInstanceState){ 
      super.onCreate(savedInstanceState); 
*   addPreferencesFromResource(MyPrefsActivity.prefs); // outer class 
      // private members seem to be visible for inner class, and 
      // making it static made things so much easier 
     } 
    } 
} 

그리고 Settings.XML의 :

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 

    <PreferenceCategory android:title="@string/checkbox_options_title" > 
     <ListPreference 
       android:key="prefCheckboxOption" 
       android:title="@string/pref_checkbox_option" 
       android:summary="@string/checkbox_options_summary" 
       android:entries="@array/checkbox_options" 
       android:entryValues="@array/checkbox_option_values" /> 

    </PreferenceCategory> 

</PreferenceScreen> 

및 arrays.xml :

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string-array name="checkbox_options"> 
     <item>CheckBox as Multi-Click</item> 
     <item>CheckBox as Dropdown</item> 
     <item>CheckBox as Pop-up</item> 
    </string-array> 
    <string-array name="checkbox_option_values"> 
     <item>0</item> 
     <item>1</item> 
     <item>2</item> 
    </string-array> 
</resources> 

(물론 나는 또한 AndroidManifest.xml에있는 MyPrefsActivity을 포함 시켰습니다)


내 목표 표시합니다 (setChosenPreference 방법에 있음) 세 개의 체크 박스 - 옵션 중 하나를 만들기 위해, 그리고 다른 두 GONE, ListPreference에서 선택한 환경 설정을 기반으로.

지금은 onCreate() 메서드와 onSharedPreferenceChanged()에서 Listpreference가 null이며 NullPointerException을 제공합니다. 그래서 세 번째 "*"(정적 클래스 PF에서) 호출되지 않기 때문에 일부 중단 점을 설정하고 (세 개의 "*"참조) null 인 이유를 설명합니다.

findPreferences를 사용하기 전에 addPreferencesFromResources를 호출해야합니다. 그렇지 않으면 null을 반환합니다. 누구도 왜 디버깅하는 동안 AddResourceApi11AndGreater() 메서드에서 두 번째 "*"얻을 수 있지만, MyPreferenceFragment 클래스 onCreate 메서드()에서 세 번째로 가지 않을거야? .. onCreate 호출되지 않습니다. 전혀.

또한 내 코드의 나머지 부분은 ok (-ish)로 보이거나 내가 의도 한대로 작동하도록하려면 변경해야합니까?

미리 답변 해 주셔서 감사합니다.

TL : DR : MyPreferenceFragment instantion이 성공적으로 생성되었지만 @Override onCreate 메소드가 호출되지 않습니다.


편집 1 : 좋아, 내가 문제를 발견 않았다 내가 디버그 테스트와 같은 활동의에서 onCreate 방법 addPreferencesFromResource (의 환경 설정)을 추가 할 때, 나는 밖으로 발견 MyPreferenceFragment 수준은 참으로 초기화되고 있음을, 그런 다음 addPreferencesFromResource (prefs) 테스트 라인을 추가하지 않은 경우 findPreference()에서 실패한 activity의 onCreate 메소드를 완료하고 activity의 onCreate 메소드가 완전히 끝난 후에 만 ​​MyPreferenceFragment의 onCreate 메소드로 이동합니다 .

AddResourceApi11AndGreater()하지만 findPreference (LIST_PREFERENCE) 이전에 PreferenceFrament의 onCreate 메서드를 먼저 처리하는 방법이 있습니까?

답변

0

로직을 PF으로 이동하십시오. PreferenceActivity에서 일을하지 마십시오. 환경 설정 변경 내용을 청취하는 방법에도 변화가 있습니다. 코드를 확인하십시오.

public class MyPrefsActivity extends PreferenceActivity { 
    private static int prefs = R.xml.settings; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     try{ 
      getClass().getMethod("getFragmentManager"); 
      AddResourceApi11AndGreater(); 
     } 
     catch(NoSuchMethodException e){ // Android API < 11 
      AddResourceApiLessThan11(); 
     } 
    } 

    @SuppressWarnings("deprecation") 
    protected void AddResourceApiLessThan11(){ 
     addPreferencesFromResource(prefs); 
    } 

    @TargetApi(11) 
    protected void AddResourceApi11AndGreater(){ 
     getFragmentManager().beginTransaction().replace(android.R.id.content, 
       new PF()).commit(); 
    } 

    @TargetApi(11) 
    public static class PF extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 
     private ImageButton cbButton, spinnerButton, popupButton; 
     private final String LIST_PREFERENCE = "prefCheckboxOption"; 

     @Override 
     public void onCreate(final Bundle savedInstanceState){ 
      super.onCreate(savedInstanceState); 
      addPreferencesFromResource(MyPrefsActivity.prefs); // outer class 
      // private members seem to be visible for inner class, and 
      // making it static made things so much easier 

      SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
      preferences.registerOnSharedPreferenceChangeListener(this); 
      ListPreference listPreference = (ListPreference) findPreference(LIST_PREFERENCE); 
      if(listPreference.getValue() == null) 
       listPreference.setValue("0"); 



      cbButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnCheckbox); 
      spinnerButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnSpinner); 
      popupButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnPopup); 

      setChosenPreference(Integer.valueOf(preferences.getString(LIST_PREFERENCE, "0"))); 
     } 

     @Override 
     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 
      int chosen_option = Integer.valueOf(sharedPreferences.getString(key, "0")); 
      setChosenPreference(chosen_option); 
     } 

     private void setChosenPreference(int chosen_value){ 
      // First put all Visibilities on GONE 
      cbButton.setVisibility(View.GONE); 
      spinnerButton.setVisibility(View.GONE); 
      popupButton.setVisibility(View.GONE); 

      // Then turn the chosen on VISIBLE again 
      switch(chosen_value){ 
       case 0: // Multi-Click CheckBox 
       default: 
        cbButton.setVisibility(View.VISIBLE); 
        break; 
       case 1: // Dropdown CheckBox 
        spinnerButton.setVisibility(View.VISIBLE); 
        break; 
       case 2: // Pop-up CheckBox 
        popupButton.setVisibility(View.VISIBLE); 
        break; 
      } 
     } 
    } 
} 
+0

흠. PF 클래스에 모든 것을 넣으면 내 API가 11보다 낮 으면 아무 것도하지 않습니다. 그 이유는 처음부터 모든 것을 Activity에 넣었 기 때문입니다. 추신 : 저는 PF의 onCreate가 불려지 지 않은 이유를 발견하고 편집했습니다. –

+0

왜 11 개보다 낮은 API에 대해 하나, 11보다 큰 API에 대해 하나씩 두 가지 설정 활동을 만드시겠습니까? 그리고 그에 따라 시작하십시오. –