简体   繁体   English

为什么我的SwitchPreference在方向上发生故障?

[英]Why does my SwitchPreference glitch on orientation change?

I have an activity (extends AppCompatActivity) that contains a PreferenceFragment with my app's settings. 我有一个活动(扩展了AppCompatActivity),其中包含带有我的应用程序设置的PreferenceFragment The first setting is a SwitchPreference to enable or disable notifications, followed by other preferences that depend upon that SwitchPreference. 第一个设置是用于启用或禁用通知的SwitchPreference,其后是依赖于该SwitchPreference的其他首选项。

My problem is this: I discovered that if I rotate the device (causing an orientation change) and then tap the switch, it doesn't render properly - it seems to show two overlapping switches ( here's a screencap from a Moto X ), one in the old position and one in the new position. 我的问题是这样的:我发现,如果我旋转设备(导致方向改变)然后点击开关,则无法正确渲染-似乎显示了两个重叠的开关( 这是Moto X的屏幕截图 ),其中一个处于旧位置,一个处于新位置。 Interestingly, this even happens with the older style of switches ( here's a screencap from a Nexus S running JellyBean ). 有趣的是,这甚至在较旧的开关样式中也会发生( 这是运行JellyBean的Nexus S的屏幕截图 )。

I haven't found anything about this bug around the internet, and as far as I can tell, it doesn't happen in Android OS apps (such as Settings) or in other third-party apps (such as Intent Intercept by Intrications). 据我所知,我尚未在互联网上找到有关此错误的任何信息,在Android OS应用程序(例如“设置”)或其他第三方应用程序(例如“ Intent Intercept by Intrications”)中都没有发生。 So it seems I'm just doing something wrong here. 所以看来我在这里做错了。

Here is the setup code in my SettingsFragment: 这是我的SettingsFragment中的设置代码:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);

        // Grab Preference objects
        final Preference wklyRemPref = findPreference(getString(R.string.prefkey_weekly_reminder));

        // Set up notification settings
        findPreference(getString(R.string.prefkey_allow_notifs))
                .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                    @Override
                    public boolean onPreferenceChange(Preference preference, Object newValue) {
                        if (Boolean.FALSE.equals(newValue)) {
                            // Turn off and disable "Weekly Reminder" pref
                            ((TwoStatePreference) wklyRemPref).setChecked(false);
                            // (Disabling is done by the system because the "Weekly Reminder"
                            // preference depends on the "Notifications" preference)
                        }
                        return true;
                    }
                });
        wklyRemPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                Log.d("Pref", preference + " value changed (" + newValue + ")");
                return true;
            }
        });
        ...
    }

Here is my settings.xml file: 这是我的settings.xml文件:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory android:title="Reminders">
        <SwitchPreference
            android:defaultValue="true"
            android:key="@string/prefkey_allow_notifs"
            android:title="@string/allow_notifs"/>
        <!-- Weekly reminder: -->
        <CheckBoxPreference
            android:dependency="@string/prefkey_allow_notifs"
            android:defaultValue="true"
            android:key="@string/prefkey_weekly_reminder"
            android:summary="Remind me weekly to choose a scripture"
            android:title="Weekly reminder" />
        <net.danmercer.ponderizer.settings.ReminderPreference
            android:defaultValue="sunday/17:00"
            android:dependency="@string/prefkey_weekly_reminder"
            android:key="@string/prefkey_weekly_reminder_time"
            android:title="Set weekly reminder time" />
        <!-- Notification preferences -->
        <RingtonePreference
            android:dependency="@string/prefkey_allow_notifs"
            android:key="@string/prefkey_notif_sound"
            android:title="Notification Sound"
            android:ringtoneType="notification"
            android:showDefault="true"
            android:showSilent="true"/>
        <CheckBoxPreference
            android:defaultValue="true"
            android:dependency="@string/prefkey_allow_notifs"
            android:key="@string/prefkey_notif_vibrate"
            android:title="Vibrate" />
    </PreferenceCategory>
    ...
</PreferenceScreen>

Edit: I have also tried to clean and rebuild my project, and uninstall and reinstall the app, to no avail. 编辑:我也曾尝试清理并重建我的项目,然后卸载并重新安装该应用程序,但无济于事。

Edit 2: I tried using a CheckBoxPreference instead of a SwitchPreference and experienced the same problem. 编辑2:我尝试使用CheckBoxPreference而不是SwitchPreference并遇到相同的问题。 And what's worse, I discovered that the entire fragment seems to be burned into the screen (so to speak) when I rotate the activity. 更糟糕的是,我发现旋转活动时似乎可以将整个片段烧入屏幕(可以这么说)。 I can scroll the settings fragment, but a ghost of what it was before stays behind. 我可以滚动设置片段,但是之前的影子仍然存在。 This artifact manifested earlier as two overlapping switches, but I didn't realize it was so pervasive. 该工件先前显示为两个重叠的开关,​​但我没有意识到它是如此普遍。

I found the problem. 我发现了问题。 In my SettingsActivity onCreate() method, I had code like this: 在我的SettingsActivity onCreate()方法中,我有如下代码:

FragmentManager fm = getFragmentManager();
fm.beginTransaction()
        .replace(R.id.frag_container, new SettingsFragment())
        .commit();

I changed the replace() call to an add() call, and now it works properly. 我将replace()调用更改为add()调用,现在它可以正常工作了。 It seems that the activity was adding two identical fragments to the layout when it was recreated upon orientation change. 似乎在更改方向后重新创建时, 该活动在布局中添加了两个相同的片段 Using replace solved the problem, because it wouldn't add multiple fragments to the activity. 使用replace解决了该问题,因为它不会向活动添加多个片段。 Moral of the story: when in doubt, use replace() , not add() . 故事的寓意:如有疑问,请使用replace() ,而不要使用add()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM