当我访问PreferenceScreen时,我注意到自定义开关已关闭。然后打开它并重新启动应用程序。我回到了PreferenceScreen,然后开关又关闭了。当我使用默认的SwitchPreference时,不会发生这种情况。我可以按自己的方式自定义SwitchPreference,因此唯一的问题是开关值未保存。我有四个与自定义SwitchPreference相关的文件,所有的Preferences都放在PreferenceFragment的扩展名中

SettingsFragment.java

public class SettingsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }

}


preferences.xml:

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

    <com.example.CustomSwitchPreference
        android:key="vibration"
        android:title="vibration"
        android:summary=""
        android:defaultValue="true" />

</PreferenceScreen>


CustomSwitchPreference.java:

public class CustomSwitchPreference extends SwitchPreference {
    public CustomSwitchPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomSwitchPreference(Context context) {
        super(context);
    }


    @Override
    protected View onCreateView( ViewGroup parent )
    {
        LayoutInflater li = (LayoutInflater)getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
        return li.inflate( R.layout.customswitch_preference, parent, false);
    }

    /*
    @Override
    protected void onBindView(View view) {
        MainActivity mainActivity = (MainActivity)getContext();
        RelativeLayout relativeLayout = (RelativeLayout)mainActivity.findViewById(R.id.switch_frame);
        Switch s = (Switch)relativeLayout.getChildAt(1);
        s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                persistBoolean(isChecked);
            }
        });
        super.onBindView(view);
    }
    */

}


customswitch_preference.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/switch_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <TextView
        android:id="@+id/switch_title"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:layout_alignParentStart="true"/>


    <Switch
        android:id="@+id/switch_pref"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        />

</RelativeLayout>


MainActivity.java:

public class MainActivity extends Activity {

    private ActionBar actionBar;
    private boolean mInit = false;
    private boolean showIcon = true;
    private Menu m;
    private GridFragment gridFragment;
    private SettingsFragment settingsFragment;
    public ImageButton startButton;
    public TextView gameTimer;
    public TextView mineCount;
    public boolean isVibrating;

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

        setContentView(R.layout.activity_main);
        settingsFragment = new SettingsFragment();
        actionBar = getActionBar();
        actionBar.setTitle("Settings");
        actionBar.setCustomView(R.layout.actionbar);
        //actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setDisplayUseLogoEnabled(false);
        actionBar.setDisplayShowHomeEnabled(false);
        //actionBar.setBackgroundDrawable(new ColorDrawable(Color.BLACK));
        ViewGroup actionBarViews = (ViewGroup)actionBar.getCustomView();
        startButton = (ImageButton)(actionBarViews.findViewById(R.id.actionBarLogo));
        mineCount = (TextView)actionBarViews.findViewById(R.id.topTextViewLeft);
        gameTimer = (TextView)actionBarViews.findViewById(R.id.topTextViewRight);
        startButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        startButton.setImageResource(R.drawable.smiley2);
                        break;
                    case MotionEvent.ACTION_UP:
                        restartGame();
                        break;
                }
                return false;
            }
        });

        Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/digital-7 (mono).ttf");
        TextView textView;
        int[] resources =
                {R.id.textViewLeft,R.id.topTextViewLeft,R.id.textViewRight,R.id.topTextViewRight};
        for(int r: resources) {
            textView = (TextView) findViewById(r);
            textView.setTypeface(myTypeface);
        }

        if (findViewById(R.id.fragment_container) != null){
            if (savedInstanceState != null) {
                return;
            }
        }
    }

    public void restartGame() {
        startButton.setImageResource(R.drawable.smiley);
        getFragmentManager().beginTransaction().remove(gridFragment).commit();
        setText(999, gameTimer);
        startGame();
    }

    private void startGame(){

        gridFragment = new GridFragment();

        gridFragment.setArguments(getIntent().getExtras());

        getFragmentManager().beginTransaction().add(R.id.fragment_container, gridFragment,"gridFragment").commit();

    }

    public void setText(int value, TextView textView){
        value = Math.min(999,value);
        value = Math.max(-99,value);
        textView.setText(String.format("%03d",value));
    }

    @Override
    protected void onStart() {
        if (!mInit) {
            mInit = true;
            Database db = new Database(this);
            db.deleteAllSessions();
            db.close();
            startGame();
        }
        super.onStart();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        m = menu;
        return true;
    }

    private void openSettings(){
        showIcon = false;
        gridFragment.pauseTimer();
        onPrepareOptionsMenu(m);
        actionBar.setDisplayShowCustomEnabled(false);
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
        ft.hide(gridFragment);
        ft.add(android.R.id.content, settingsFragment).commit();
        //ft.replace(android.R.id.content,settingsFragment);
    }

    private void updateSettings(){

        SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

        Map<String, ?> map = sharedPrefs.getAll();
        for (Map.Entry<String, ?> entry : map.entrySet()) {
            Log.d("map values", entry.getKey() + ": " + entry.getValue().toString());
        }
        isVibrating = (Boolean)map.get("vibration");
    }

    private void closeSettings(){
        showIcon = true;
        onPrepareOptionsMenu(m);
        actionBar.setDisplayShowCustomEnabled(true);
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
        ft.show(gridFragment);
        ft.remove(settingsFragment).commit();
        //ft.replace(android.R.id.content,gridFragment);
        gridFragment.resumeTimer();
    }

    @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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            openSettings();
            return true;
        }
        else if(id == R.id.backButton){
            updateSettings();
            closeSettings();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuItem item= menu.findItem(R.id.action_settings);
        item.setVisible(showIcon);
        item = menu.findItem(R.id.backButton);
        item.setVisible(!showIcon);
        return super.onPrepareOptionsMenu(menu);
    }
}

最佳答案

您实际上从未设置或保存开关的状态。您需要覆盖onBindView来设置视图的初始状态,并将选中的更改侦听器附加到Switch(R.id.switch_pref)上以侦听更改并将其持久化为SharedPreferences(您可以调用persistBoolean来执行那)。

10-05 18:21