andyxialm / SmoothCheckBox

:dango: A custom CheckBox with animation for Android.
1.62k stars 299 forks source link

一个bug #33

Open lishangwl opened 5 months ago

lishangwl commented 5 months ago

错误日志 java.lang.ClassCastException: java.lang.Boolean cannot be cast to android.os.Parcelable at android.os.Bundle.getParcelable(Bundle.java:1008) at com.xxx.ui.widget.SmoothCheckBox.onRestoreInstanceState(SmoothCheckBox.java:153) at android.view.View.dispatchRestoreInstanceState(View.java:21441) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4077) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4077) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4077) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4077) at android.view.View.restoreHierarchyState(View.java:21419) at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:641) at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:3042) at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:3033) at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:578) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:264) at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1758) at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1670) at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:323) at androidx.fragment.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:249) at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244) at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092) at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622) at android.view.View.measure(View.java:26392) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7095) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26392) at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1638) at android.view.View.measure(View.java:26392) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7095) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26392) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7095) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26392) at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1638) at android.view.View.measure(View.java:26392) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7095) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26392) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7095) at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) at android.view.View.measure(View.java:26392) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7095) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552) at android.widget.LinearLayout.measureVertical(LinearLayout.java:842) at android.widget.LinearLayout.onMeasure(LinearLayout.java:721) at android.view.View.measure(View.java:26392)

lishangwl commented 5 months ago

修正代码 @Override protected Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); bundle.putParcelable("superState", super.onSaveInstanceState()); bundle.putBoolean(KEY_INSTANCE_STATE, isChecked()); return bundle; }

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {
        Bundle bundle = (Bundle) state;
        boolean isChecked = bundle.getBoolean(KEY_INSTANCE_STATE);
        setChecked(isChecked);
        // 修正:使用正确的方式恢复父类状态
        Parcelable superState = bundle.getParcelable("superState");
        super.onRestoreInstanceState(superState);
        return;
    }
    super.onRestoreInstanceState(state);
}
lishangwl commented 5 months ago

在您的代码中,您使用 KEY_INSTANCE_STATE 作为键来保存和恢复 isChecked 状态。这是合理的,因为它是您自定义控件的特定状态。然而,当您同时保存父类的状态和自定义状态时,您需要确保这些键是唯一的,以避免它们相互覆盖。

使用不同的键(如 superState)来保存父类的状态是为了避免与自定义状态的键冲突。这样,您就可以在 onRestoreInstanceState 方法中分别恢复父类状态和自定义状态,而不会混淆它们。如果您使用相同的键 KEY_INSTANCE_STATE 来保存父类状态,它可能会覆盖或被您自定义状态的值覆盖,导致状态恢复不正确。

总之,使用不同的键(如 superState)来保存父类状态是为了确保状态的唯一性和正确恢复。