gpt4 book ai didi

Android 偏好 - 在 SettingsActivity 中滚动到屏幕外时 SwtichPrefrence 发生变化

转载 作者:行者123 更新时间:2023-11-30 01:35:42 37 4
gpt4 key购买 nike

我有一个很奇怪的问题。当我在我的设置- Activity 中滚动时,一些复选框在不再显示时会发生变化。例如:我取消选中广告复选框,然后向下滚动,当复选框完全消失时,复选框会重置。只有当我取消选中默认值没有任何影响的复选框时才会发生这种情况。

我的 Activity :

public class SettingsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
/**
* Determines whether to always show the simplified settings UI, where
* settings are presented in a single list. When false, settings are shown
* as a master/detail two-pane view on tablets. When true, a single pane is
* shown on tablets.
*/
private static final boolean ALWAYS_SIMPLE_PREFS = false;
private SharedPreferences prefs;

private Tracker mTracker;

private void analytics() {
if(prefs.getBoolean(Tags.PREF_GOOGLEANALYTICS, true)) {
// Obtain the shared Tracker instance.
AnalyticsApplication application = (AnalyticsApplication) getApplication();
mTracker = application.getDefaultTracker();

mTracker.setScreenName("SettingsActivity");
mTracker.send(new HitBuilders.ScreenViewBuilder().build());
}
}

private void analytics(String category, String action) {
if(prefs.getBoolean(Tags.PREF_GOOGLEANALYTICS, true)) {
if (mTracker == null) {
AnalyticsApplication application = (AnalyticsApplication) getApplication();
mTracker = application.getDefaultTracker();
}

mTracker.send(new HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.build());

}
}

private void setLocale(String lang) {
/*Locale myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);*/

Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());

Intent refresh = new Intent(this, MainActivity.class);
startActivity(refresh);
finish();
}

@Override
protected void onResume() {
super.onResume();
prefs.registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
super.onPause();
prefs.unregisterOnSharedPreferenceChangeListener(this);
}

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

prefs = PreferenceManager.getDefaultSharedPreferences(this);
analytics();

Toolbar bar;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent();
bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
root.addView(bar, 0); // insert at top
} else {
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
ListView content = (ListView) root.getChildAt(0);

root.removeAllViews();

bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);


int height;
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}else{
height = bar.getHeight();
}

content.setPadding(0, height, 0, 0);

root.addView(content);
root.addView(bar);
}

bar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});

setupSimplePreferencesScreen();
}

/**
* Shows the simplified settings UI if the device configuration if the
* device configuration dictates that a simplified, single-pane UI should be
* shown.
*/
private void setupSimplePreferencesScreen() {
if (!isSimplePreferences(this)) {
return;
}

// In the simplified UI, fragments are not used at all and we instead
// use the older PreferenceActivity APIs.

// Add 'general' preferences.
addPreferencesFromResource(R.xml.pref_general);


// Add 'notifications' preferences, and a corresponding header.
PreferenceCategory fakeHeader = new PreferenceCategory(this);
fakeHeader.setTitle(getResources().getString(R.string.pref_notifications));
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_notification);

PreferenceCategory fakeHeaderAudio = new PreferenceCategory(this);
fakeHeaderAudio.setTitle(getResources().getString(R.string.pref_audio));
getPreferenceScreen().addPreference(fakeHeaderAudio);
addPreferencesFromResource(R.xml.pref_audio);


// Bind the summaries of EditText/List/Dialog/Ringtone preferences to
// their values. When their values change, their summaries are updated
// to reflect the new value, per the Android Design guidelines.
// bindPreferenceSummaryToValue(findPreference(getString(R.string.key_checkbox)));
}

/**
* {@inheritDoc}
*/
@Override
public boolean onIsMultiPane() {
return isXLargeTablet(this) && !isSimplePreferences(this);
}

/**
* Helper method to determine if the device has an extra-large screen. For
* example, 10" tablets are extra-large.
*/
private static boolean isXLargeTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}

/**
* Determines whether the simplified settings UI should be shown. This is
* true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device
* doesn't have newer APIs like {@link PreferenceFragment}, or the device
* doesn't have an extra-large screen. In these cases, a single-pane
* "simplified" settings UI should be shown.
*/
private static boolean isSimplePreferences(Context context) {
return ALWAYS_SIMPLE_PREFS
|| (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
|| !isXLargeTablet(context);
}

/**
* {@inheritDoc}
*/
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List<Header> target) {
if (!isSimplePreferences(this)) {
loadHeadersFromResource(R.xml.pref_headers, target);
}
}

@Override
protected boolean isValidFragment(String fragmentName) {
return NotificationPreferenceFragment.class.getName().equals(fragmentName)
|| GeneralPreferenceFragment.class.getName().equals(fragmentName)
|| AudioPreferenceFragment.class.getName().equals(fragmentName);
}

@Override
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
if(key.equals(Tags.PREF_NOTIFICATION)
|| key.equals(Tags.PREF_NOTIFICATIONTIME)
|| key.equals(Tags.PREF_AUDIO_AUTODOWNLOAD)) {

if(sharedPreferences.getBoolean(Tags.PREF_NOTIFICATION, true)
|| sharedPreferences.getBoolean(Tags.PREF_AUDIO_AUTODOWNLOAD, true)) {
long time = sharedPreferences.getLong(Tags.PREF_NOTIFICATIONTIME, 60 * 7);
Notifications.setNotifications(this, time * 60 * 1000);
} else
Notifications.removeNotifications(this);
}

if(key.equals(Tags.PREF_NOTIFICATION) || key.equals(Tags.PREF_ADS)
|| key.equals(Tags.PREF_GOOGLEANALYTICS) || key.equals(Tags.PREF_SHOWNOTES)) {

//This toast is shown when I scroll down
Toast.makeText( getApplicationContext(), "Notification || Analytics", Toast.LENGTH_SHORT).show();

analytics("Settings", "Settings: " + key + ", " + sharedPreferences.getBoolean(key, true));
}

//Language change
if(key.equals(Tags.PREF_LANGUAGE)) {
try {
setLocale(sharedPreferences.getString(key, "en"));
} catch (Exception e) {
Log.e("Losungen", "Error changing language: " + e.getMessage());
e.printStackTrace();
}
}

//SD-Card change
if(key.equals(Tags.PREF_AUDIO_EXTERNAL_STORGAE)) {
boolean sd_card = sharedPreferences.getBoolean(key, false);

if(sd_card)
MainActivity.toast(this, this.getString(R.string.still_in_internal), Toast.LENGTH_LONG);
else
MainActivity.toast(this, this.getString(R.string.still_in_external), Toast.LENGTH_LONG);
}

}

/**
* This fragment shows general preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
}
}

/**
* This fragment shows notification preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class NotificationPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_notification);
}
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class AudioPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_audio);
}
}
}

还有我的 xml 文件:pref_general.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="show_notes"
android:title="@string/pref_notes_title"
android:defaultValue="true" />

<SwitchPreference
android:key="show_ads"
android:title="@string/pref_ads_title"
android:summary="@string/pref_ads_summary"
android:defaultValue="false"
/>

<SwitchPreference
android:key="google_analytics"
android:title="@string/pref_google_title"
android:summary="@string/pref_google_summary"
android:defaultValue="true" />

<ListPreference
android:key="language"
android:title="@string/pref_language"
android:summary="@string/pref_language_summary"
android:entries="@array/pref_language_list_titles"
android:entryValues="@array/pref_language_list_values"
android:negativeButtonText="@null"
android:positiveButtonText="@null" />

</PreferenceScreen>

pref_notification.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- A 'parent' preference, which enables/disables child preferences (below)
when checked/unchecked. -->
<SwitchPreference
android:key="notifications_losung"
android:title="@string/pref_notifications"
android:defaultValue="true" />

<ListPreference
android:key="notifications_art"
android:dependency="notifications_losung"
android:title="@string/pref_notification_art"
android:defaultValue="0"
android:entries="@array/pref_notifications_list_titles"
android:entryValues="@array/pref_notifications_list_values"
android:negativeButtonText="@null"
android:positiveButtonText="@null" />

<de.schalter.losungen.preferences.TimePreference
android:key="notification_time"
android:defaultValue="420"
android:title="@string/pref_time"
android:dependency="notifications_losung"
/>

</PreferenceScreen>

pref_audio.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- oder stream -->
<SwitchPreference
android:key="audio_download"
android:title="@string/pref_audio_download_title"
android:summaryOn="@string/pref_audio_download_summary_on"
android:summaryOff="@string/pref_audio_download_summary_off"
android:defaultValue="true" />

<!-- oder erst bei Nutzer interaktion -->
<SwitchPreference
android:key="audio_autodownload"
android:dependency="audio_download"
android:title="@string/pref_audio_autodownload_title"
android:summaryOn="@string/pref_audio_autodownload_summary_on"
android:summaryOff="@string/pref_audio_autodownload_summary_off"
android:defaultValue="true" />

<ListPreference
android:key="audio_autodownload_network"
android:dependency="audio_autodownload"
android:title="@string/pref_audio_autodownload_network_title"
android:defaultValue="0"
android:entries="@array/pref_audio_autodownload_network_entries"
android:entryValues="@array/pref_audio_autodownload_network_values"
android:negativeButtonText="@null"
android:positiveButtonText="@null" />


<SwitchPreference
android:key="audio_external_storage"
android:dependency="audio_download"
android:title="@string/pref_audio_externalstorage_title"
android:summaryOff="@string/pref_audio_externalstorage_summary_off"
android:summaryOn="@string/pref_audio_externalstorage_summary_on"
android:defaultValue="false" />
</PreferenceScreen>

我不知道为什么会这样。有些评论是德语的,但我想你什么都能听懂。有什么想法吗?

这是一个类似的问题,但没有有用的答案:Android Preferences - On/Off Switch Icons Reset When Scrolled Offscreen

最佳答案

引用Preference items being automatically re-set?上的回答,它建议您仅使用调用 super 的构造函数对 SwitchPreference 进行子类化,然后使用它代替标准 SwitchPreference。我注意到这发生在早期版本的 Android 上(在我们的例子中特别是 4.x),但不是 5+。

我怀疑这是因为 Preference 的构造函数中的这些行:

来自 API 17(需要此修改):

if (!getClass().getName().startsWith("android.preference")) {
// For subclasses not in this package, assume the worst and don't cache views
mHasSpecifiedLayout = true;
}

或来自 API 23(无需修改即可正常工作):

if (!getClass().getName().startsWith("android.preference")
&& !getClass().getName().startsWith("com.android")) {
// For non-framework subclasses, assume the worst and don't cache views.
mCanRecycleLayout = false;
}

通过 PreferenceGroupAdapter 进行跟踪,看起来当它回收 View 时它会设置一些东西,然后通知监听器首选项已更改。我找不到它实际上在哪里/为什么更改了首选项,所以我也不确定为什么更新的 API 中的更改修复了它,但这似乎就是正在发生的事情。

关于Android 偏好 - 在 SettingsActivity 中滚动到屏幕外时 SwtichPrefrence 发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35140581/

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