【问题标题】:Custom DialogPreference disappears after orientation change方向更改后自定义 DialogPreference 消失
【发布时间】:2014-12-01 17:12:49
【问题描述】:

首先,对不起我的英语。

我正在尝试在我的偏好屏幕上创建一个自定义的“日期选择器”对话框。我从 Android 开发者网站和 Stackoverflow 获得了代码。

对话框运行良好,它保存并加载值(布局包含 NumberPicker 和 TextView)。问题是:对话框在设备旋转时消失。

我已经阅读了这个论坛和其他网站上的几篇帖子,但没有运气。你能帮助我吗 ?到目前为止,我已经花了几个小时来寻找问题,但我不知道如何解决它。谢谢。

代码:

package hu.test.android.demo.ui;

import hu.test.android.demo.AMdtApplication;
import hu.test.android.demo.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.NumberPicker;

public class DayPreference extends DialogPreference {

private NumberPicker picker = null;
private static int day;

public static int getDay () {
    return day;
}

public DayPreference(Context ctxt, AttributeSet attrs) {
    super(ctxt, attrs);

    setDialogLayoutResource(R.layout.day_preference);

    setPositiveButtonText (TestApplication.getContext().getResources().getString( R.string.save ));
    setNegativeButtonText (TestApplication.getContext().getResources().getString( R.string.cancel ));
}

@Override
protected void onBindDialogView(View v) {
    super.onBindDialogView (v);

    picker = (NumberPicker) v.findViewById (R.id.day_preference_number_picker);

    picker.setMinValue (1);
    picker.setMaxValue (30);
    picker.setValue (day);
}

@Override
protected void onDialogClosed(boolean positiveResult) {
    super.onDialogClosed(positiveResult);

    if (positiveResult) {
        if (callChangeListener (day)) {
            day = picker.getValue();
            persistInt (day);
        }

        setSummary(getSummary());
    }

}

@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
    return (a.getString(index));
}

@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {

    if (restoreValue) {
        if (defaultValue == null) {
            day = getPersistedInt (30);
        }
        else {
            day = getPersistedInt ((Integer) defaultValue);
        }
    }
    else {
        day = (Integer) defaultValue;
    }

    setSummary (getSummary());
}

@Override
public CharSequence getSummary() {
    return String.valueOf ( day ) + " " + TestApplication.getContext().getResources().getString( R.string.label_day );
}

// state save & restore
@Override
protected Parcelable onSaveInstanceState () {
    final Parcelable superState = super.onSaveInstanceState();

    if (isPersistent()) {
        return superState;
    }

    final SavedState myState = new SavedState (superState);
    myState.value = day;

    return myState;
}

@Override
protected void onRestoreInstanceState (Parcelable state) {

    if (state == null || !state.getClass().equals(SavedState.class)) {
        super.onRestoreInstanceState(state);

        return;
    }

    SavedState myState = (SavedState) state;
    super.onRestoreInstanceState(myState.getSuperState());

    // set the value to the picker
    picker.setValue (myState.value);
}

private static class SavedState extends BaseSavedState {
    public int value;

    public SavedState (Parcelable superState) {
        super(superState);
    }

    public SavedState (Parcel source) {
        super(source);
        value = source.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeInt(value);
    }

    // Standard creator object using an instance of this class
    @SuppressWarnings( "unused" )
    public static final Parcelable.Creator <SavedState> CREATOR = new Parcelable.Creator <SavedState> () {

        public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
        }

        public SavedState[] newArray (int size) {
            return new SavedState[size];
        }
    };
}

}

【问题讨论】:

    标签: android savestate dialog-preference


    【解决方案1】:

    更新:

    请注意,以下解决方案只是一种快速破解(不是推荐的方法),正确的解决方案是在 onSaveInstanceState 期间保留值,然后在重新创建活动后获取这些值。

    This post 是必须阅读以优雅地处理配置更改。

    原始答案:

    也许这会有所帮助,在清单文件的相关活动标签中添加这一行:

    android:configChanges="orientation|screenSize"
    

    这将确保在屏幕旋转时不会调用 onCreate,你对 android 操作系统说,嘿,我将自己处理这个活动的旋转内容,你不需要从 onCreate 重新开始。

    【讨论】:

    • 谢谢...非常完美。 :) 并感谢您的解释。奇怪的是,'state.getClass()...' 方法返回的是 'android.preference.DialogPreference&SavedState' 而不是 'hu.test.android.demo.ui.DayPreference&SavedState'。也许这就是原因?
    • @NicolasMaltais 是的,我知道 :) 我应该更新我的答案 :) 谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多