簡體   English   中英

Android-SharedPreferences ListPreference-PreferenceFragment onCreate未調用

[英]Android - SharedPreferences ListPreference - PreferenceFragment onCreate not called

好的,我知道之前有很多關於Android中的SharedPreferences的問題,我確實做到了很多,但是由於我對SharedPreferences有點陌生,所以我不知道如何使其正常工作的最后幾步。

在我的MainActivity中,我有以下內容:

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>

(當然,我還將MyPrefsActivity包含在AndroidManifest.xml中)


我的目標是根據ListPreference中選擇的首選項,使三個復選框選項(在setChosenPreference方法中找到)之一變為可見,而另兩個變為GONE。

現在,onCreate()方法和onSharedPreferenceChanged()中的Listpreference為null,並給出NullPointerException。 因此,我設置了一些斷點(請參見三個“ *”),它們為空的原因是因為未調用第三個“ *”(在靜態類PF中)。

應該在使用findPreference之前調用addPreferencesFromResources,否則它將返回null。 有誰知道為什么在調試過程中我確實到達了AddResourceApi11AndGreater()方法中的第二個“ *”,但是卻沒有到達MyPreferenceFragment-class onCreate method()中的第三個“ *”?.. onCreate沒有被調用完全沒有。

另外,我的其余代碼看起來還可以嗎(-ish),還是應該更改某些內容以使其按預期工作?

預先感謝您的答復。

TL; DR:MyPreferenceFragment實例創建成功,但是從未調用過@Override onCreate方法。


編輯1:好的,我確實找到了問題:當我在活動的onCreate方法中添加addPreferencesFromResource(prefs)作為調試測試時,我發現MyPreferenceFragment-class確實已初始化,然后完成了活動的onCreate方法(如果我不添加addPreferencesFromResource(prefs)測試行,該操作在findPreference()上將失敗,並且只有在活動的onCreate方法完全完成后,它才會轉到MyPreferenceFragment的onCreate方法。

有沒有辦法讓PreferenceFrament的onCreate方法首先進入活動的onCreate方法的中間,因此在AddResourceApi11AndGreater()之后但在findPreference(LIST_PREFERENCE)之前呢?

將您的邏輯移至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;
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM