gpt4 book ai didi

java - 调用 onSharedPreferenceChanged 后应用主题没有改变

转载 作者:行者123 更新时间:2023-11-29 18:45:36 34 4
gpt4 key购买 nike

创建首选项 Activity 后,我注意到尽管调用了 onSharedPreferenceChanged,但当我的复选框首选项被选中时,我的主要 Activity 并没有改变主题。有谁知道出了什么问题以及如何解决这个问题?

样式.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!--<item name="android:windowBackground">@color/colorLight</item>-->
</style>

<style name="MyDarkMaterialTheme" parent="android:Theme.Material">
<item name="android:windowBackground">@android:color/black</item>
</style>

<style name="MyLightMaterialTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:windowBackground">@color/colorLight</item>
</style>

MainActivity 类

public class MainActivity extends Activity {

boolean themeState;

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

setTheme(R.style.MyDarkMaterialTheme);

setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);

return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
return true;

default:
return super.onOptionsItemSelected(item);
}
}


@Override
public void onResume(){
super.onResume();
loadPreferences();
displaySettings();
}

private void loadPreferences(){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
themeState = sharedPreferences.getBoolean("pref_pref1", true);
}

public void displaySettings() {
if (themeState) {
setTheme(R.style.MyDarkMaterialTheme);
recreate();
} else {
setTheme(R.style.MyLightMaterialTheme);
recreate();
}
}
}

SettingsActivity 类

public class SettingsActivity extends Activity {

boolean themeState;

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

if (savedInstanceState == null) {
Fragment preferenceFragment = new SettingsFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.pref_container, preferenceFragment);
ft.commit();
}
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
final Intent intent = getParentActivityIntent();
if(intent != null){
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
}
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}


@Override
public void onResume(){
super.onResume();
loadPreferences();
displaySettings();
}

private void loadPreferences(){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
themeState = sharedPreferences.getBoolean("pref_pref1", true);
}

public void displaySettings() {
if (themeState) {
getApplication().setTheme(R.style.MyDarkMaterialTheme);
recreate();
} else {
getApplication().setTheme(R.style.MyLightMaterialTheme);
recreate();
}
}
}

SettingsFragment 类

public class SettingsFragment extends PreferenceFragment {

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

//Load the Preferences from the XML file
addPreferencesFromResource(R.xml.app_preferences);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// Settings activity or fragment should restart with changes applied

}
};
}
}

xml/app_preferences

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

<CheckBoxPreference
android:key="pref_pref1"
android:title="@string/dark_theme"
android:defaultValue="false"
android:layout="@layout/preference_multiline"
/>

</PreferenceScreen>

Csongi77的建议

public class SettingsFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {

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

//Load the Preferences from the XML file
addPreferencesFromResource(R.xml.app_preferences);

// Find appropriate preference
CheckBoxPreference mThemePreference =(CheckBoxPreference)getPreferenceManager().findPreference("pref_pref1");
// we have to set up listener in order for persisting change to new value
mThemePreference.setOnPreferenceChangeListener(this);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mThemePreference.getContext());
Boolean value=sharedPreferences.getBoolean("pref_pref1",true);
onPreferenceChange(mThemePreference, value);
}

// overriding onPreferenceChange - if we return true, the preference will be persisted
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String preferenceKey = preference.getKey();
// we have to check the preference type and key, maybe later we have more preferences....
if(preference instanceof CheckBoxPreference){
if(preferenceKey.equals("pref_pref1")){
((CheckBoxPreference)preference).setChecked((Boolean)newValue);
// ... do other preference related stuff here - if necessary, for example setSummary, etc...
getActivity().setTheme(R.style.MyDarkMaterialTheme);
} else {
getActivity().setTheme(R.style.MyLightMaterialTheme);
}
}
return true;
}
}

逻辑猫

          Process: com.companyname.appname, PID: 4505
java.lang.NullPointerException: Attempt to invoke interface method 'void com.companyname.appname.SettingsFragment$PreferenceXchangeListener.onXchange(java.lang.Boolean)' on a null object reference
at com.companyname.appname.SettingsFragment.onPreferenceChange(SettingsFragment.java:57)
at android.preference.Preference.callChangeListener(Preference.java:928)
at android.preference.TwoStatePreference.onClick(TwoStatePreference.java:64)
at android.preference.Preference.performClick(Preference.java:983)
at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:214)
at android.widget.AdapterView.performItemClick(AdapterView.java:300)
at android.widget.AbsListView.performItemClick(AbsListView.java:1143)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3044)
at android.widget.AbsListView$3.run(AbsListView.java:3833)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

SettingsActivity 类

public class SettingsActivity extends Activity implements SettingsFragment.PreferenceXchangeListener {
private static final String TAG = SettingsActivity.class.getSimpleName();

// declaring initial value for applying appropriate Theme
private Boolean mCurrentValue;

@Override
protected void onCreate(Bundle savedInstanceState) {

// Checking which Theme should be used. IMPORTANT: applying Themes MUST called BEFORE super.onCreate() and setContentView!!!
Log.d(TAG, "onCreate:::: retrieving preferences");
SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mCurrentValue = mSharedPreferences.getBoolean("my_preference",false);
Log.d(TAG, "onCreate:::: my_preference and mCurrentValue=" + mCurrentValue);
if(mCurrentValue){
// we have to use simple setTheme() instead getApplication.setTheme()!!!
setTheme(R.style.DarkTheme);
Log.d(TAG, "onCreate:::: setTheme:DarkTheme");
} else {
setTheme(R.style.LightTheme);
Log.d(TAG, "onCreate:::: setTheme:LightTheme");
}

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);

Fragment preferenceFragment = new SettingsFragment();
getFragmentManager().beginTransaction().add(R.id.preference_container, preferenceFragment).commit();
}

// callback method for changing preference. It's called only if "my_preference" has changed
@Override
public void onXchange(Boolean value) {
// if value differs from previous Theme, we recreate Activity
Log.d(TAG, "onXchange:::: \n has called");
if (value!=mCurrentValue) {
Log.d(TAG, "onXchange:::: \n new value!=oldValue");
mCurrentValue=value;
recreate();
}
}
}

SettingsFragment 类

public class SettingsFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {
private static final String TAG = SettingsFragment.class.getSimpleName();

// declaring PreferenceXchangeListener
private PreferenceXchangeListener mPreferenceXchangeListener;

public SettingsFragment() {
}

// declaring PreferenceXchangeListener in order to communicate with Activities
public interface PreferenceXchangeListener {
void onXchange(Boolean value);
}

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

//Load the Preferences from the XML file
addPreferencesFromResource(R.xml.app_preferences);

CheckBoxPreference mCheckBoxPreference = (CheckBoxPreference)findPreference("my_preference");
mCheckBoxPreference.setOnPreferenceChangeListener(this);
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
// on Attch we assign parent Activity as PreferenceXchangeListener
try {
mPreferenceXchangeListener = (PreferenceXchangeListener) context;
} catch (ClassCastException e) {
Log.e(TAG, "onAttach::::: PreferenceXchangeListener must be set in parent Activity");
}
}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String preferenceKey=preference.getKey();
// only my_preference is checked in this case. Later you may add another behaviour to another preference change
if(preferenceKey.equals("my_preference")){
((CheckBoxPreference)preference).setChecked((Boolean)newValue);
// executing parent Activity's callback with the new value
mPreferenceXchangeListener.onXchange((Boolean)newValue);
return true;
}
// ... check other preferences here
return false;
}
}

最佳答案

试试这个:

public class SettingsFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {

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

//Load the Preferences from the XML file
addPreferencesFromResource(R.xml.app_preferences);

// Find appropriate preference
CheckBoxPreference mThemePreference =(CheckBoxPreference)getPreferenceManager().findPreference("pref_pref1");
// we have to set up listener in order for persisting change to new value
mThemePreference.setOnPreferenceChangeListener(this);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mThemePreference.getContext());
Boolean value=sharedPreferences.getBoolean("pref_pref1",true);
onPreferenceChange(mThemePreference, value);
}

// overriding onPreferenceChange - if we return 'true', the preference will be persisted
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String preferenceKey = preference.getKey();
// we have to check the preference type and key, maybe later we have more preferences....
if(preference instanceof CheckBoxPreference){
if(preferenceKey.equals("pref_pref1")){
// Edited this line *******
((CheckBoxPreference)preference).setChecked((Boolean)newValue);
// ... do other preference related stuff here - if necessary, for example setSummary, etc...
}
}
return true;
}

}

简而言之:在您的 PreferenceFragment 中实现 OnPreferenceChange。当您覆盖 onPreferenceChane 时返回 true。在这种情况下,旧的首选项将被覆盖。希望对您有所帮助(如果是,请不要忘记接受我的回答)!此致,铯

P.S: 不要忘记在模拟器上卸载应用

关于java - 调用 onSharedPreferenceChanged 后应用主题没有改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52084069/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com