andyxialm/SmoothCheckBox

一个bug

Opened this issue · 2 comments

错误日志
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)

修正代码
@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);
}

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

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

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