自定义偏好的 OnSharedPreferenceChangeListener

OnSharedPreferenceChangeListener of custom preference

我创建了一个扩展 android.support.v7.preference 的 class 以创建自定义首选项,然后将其包含在我的 preference.XML 文件中。 我在我的 MainActivity 和 @Override onSharedPreferenceChanged 中实现了 SharedPreferences.OnSharedPreferenceChangeListener,默认首选项触发了该函数,但自定义首选项没有。 谁能帮忙

您可以查看 here

中的所有项目

这是我的自定义偏好class

import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.TextView;


public class SeekbarPreference extends Preference  {

    private static final String TAG = "SeekbarPreference";

    public SeekbarPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setLayoutResource(R.layout.seekbar_preferences);

    }


    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        holder.itemView.setClickable(false);
        SeekBar seekBar = (SeekBar) holder.findViewById(R.id.seekbar);
        final TextView tvSummary = (TextView) holder.findViewById(R.id.tvSummary);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                tvSummary.setText(String.valueOf(progress));
                Log.d(TAG, "onProgressChanged: ");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStartTrackingTouch: ");

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStopTrackingTouch: ");

            }
        });

    }
}

主要活动class

public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {

    private static final String SWITCH_ON_SHARED_KEY = "switchON";

    private static final String CHECK_SHARED_KEY = "allUsers";

    private static final String SEEKBAR_SHARED_KEY = "Seekbar_after";
    private static final String TAG = "MainActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setupSharedPreferences();
    }

    private void setupSharedPreferences() {
        // Get all of the values from shared preferences to set it up
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);


        sharedPreferences.registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.setting_item) {
            Intent intent = new Intent(this, SettingActivity.class);
            startActivity(intent);
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

        Log.d(TAG, "onSharedPreferenceChanged: " + key);
    }
}

我的preference.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <SwitchPreferenceCompat
        android:defaultValue="@bool/default_switch"
        android:key="switchON"
        android:summaryOff="@string/hidden_text"
        android:summaryOn="@string/shown_text"
        android:title="Mode ON" />
    <PreferenceCategory android:title="Decorate">
        <CheckBoxPreference
            android:defaultValue="@bool/default_check"
            android:key="allUsers"
            android:summaryOff="@string/hidden_text"
            android:summaryOn="@string/shown_text"
            android:title="All" />


        <com.example.momenali.custompreference.SeekbarPreference
            android:defaultValue="light"
            android:key="Seekbar_after" />
    </PreferenceCategory>
</PreferenceScreen>

经过研究我找到了解决方案。

这是更新后的项目here

要触发侦听器并保存数据,我需要调用 seekbarPreference 中的 persistInt() 函数 class

public SeekbarPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setLayoutResource(R.layout.seekbar_preferences);

    }


    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        holder.itemView.setClickable(false);
        SeekBar seekBar = (SeekBar) holder.findViewById(R.id.seekbar);
        final TextView tvSummary = (TextView) holder.findViewById(R.id.tvSummary);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                tvSummary.setText(String.valueOf(progress));
                Log.d(TAG, "onProgressChanged: ");
                persistInt(progress);               // call the persistInt function to save the data
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStartTrackingTouch: ");

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStopTrackingTouch: ");

            }
        });

    }
}

在调用 persistInt 后,seekbar 进度值已保存,但当我们重新设置时,seekbar 值仍为默认值

所以我们需要覆盖 onSetInitialValue() 函数来获取保存的数据如下

  @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
        super.onSetInitialValue(restorePersistedValue, defaultValue);
        if (restorePersistedValue){
            presentValue = getPersistedInt(0);
            Log.d(TAG, "SeekbarPreference: "+ presentValue );
        }else{
            presentValue = 5;
        }

    } 

然后我们可以在onBindViewHolder函数中更新seekbar的进度值