当电话方向改变时,EditText如何保留其值但不保留textview?

时间:2013-03-21 10:41:40

标签: android android-edittext textview android-orientation

Edittext有什么特别之处,它可以保留值,但不能保留Textview和其他一些小部件,我们必须为它们使用onSavedInstance()方法。

EditText背后的特殊之处在于它可以保留这些值吗?

如果有人能说出它在内部如何运作。

< ---- ----更新>

它如何在内部工作,请指向解释此方案的代码部分。

5 个答案:

答案 0 :(得分:8)

  

EditText背后的特殊之处在于它可以保留   值?它是如何在内部工作的,请指向代码的那一部分   这解释了这种情况。

这是带来差异的可选属性。 TextView.onSaveInstanceState中的以下if条件负责处理。

@Override
public Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();

    // Save state if we are forced to
    boolean save = mFreezesText;
    int start = 0;
    int end = 0;

    if (mText != null) {
        start = getSelectionStart();
        end = getSelectionEnd();
        if (start >= 0 || end >= 0) {
            // Or save state if there is a selection
            save = true;
        }
    }

    ...
}

默认情况下,无法选择TextView。因此,getSelectionStart()getSelectionEnd()会返回-1save变量会保存false值。要使其在方向更改时保留其内容,请将属性textIsSelectable设置为true。

由于默认情况下EditText是可选的,getSelectionStart()getSelectionEnd()始终返回值> = 0,因此save变量保存真值并保存内容。

注意:默认情况下,freezesText处于禁用状态。因此mFreezesText值为false。

答案 1 :(得分:5)

引用本文:https://tekeye.uk/android/examples/saving-activity-state

“将设备从纵向切换到横向会导致Android停止并重新启动活动,允许活动有机会重新绘制不同维度的屏幕。停止和启动活动是一种常见的情况,如果输入保持不变,用户会感到恼火Android活动有一对叫做onSaveInstanceState(Bundle)和onRestoreInstanceState(Bundle)的方法,它们被输入视图自动用来保存它们的数据。这些方法只有在可以识别获取数据的视图时才有效,因此需要EditText(以及所有屏幕项)具有id。奖励是可以在Activity中覆盖此方法对,以便也可以保存和恢复与输入字段无关的状态变量。“

从edittext中删除id并尝试:)

答案 2 :(得分:4)

默认情况下,EditText视图保存其状态 - 这是通过在代码中设置标志来实现的,该视图告诉视图在视图不可见或失去焦点时保存状态。旋转设备后,文本会自动保存并恢复。通过将android:saveEnabled属性设置为false,可以在XML布局文件中禁用EditText视图状态的自动保存:

 android:saveEnabled="false"

或以编程方式,致电view.setSaveEnabled(false)

saveEnabled控制是否启用此视图状态的保存(即,是否将调用其onSaveInstanceState()方法)。请注意,即使启用了冻结,视图仍必须为其分配一个id(通过setId())以保存其状态。此标志只能禁用此视图的保存;任何子视图仍可保存其状态。 saveEnabled属性是android View的一部分 - View Code。以下是代码的相关部分:

public boolean isSaveEnabled() {
        return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED;
    }

...

 public void setSaveEnabled(boolean enabled) {
        setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
    }

...

 void setFlags(int flags, int mask) {
        int old = mViewFlags;
        mViewFlags = (mViewFlags & ~mask) | (flags & mask);

        int changed = mViewFlags ^ old;
        if (changed == 0) {
            return;
        }
        int privateFlags = mPrivateFlags;

        /* Check if the FOCUSABLE bit has changed */
        if (((changed & FOCUSABLE_MASK) != 0) &&
                ((privateFlags & HAS_BOUNDS) !=0)) {
            if (((old & FOCUSABLE_MASK) == FOCUSABLE)
                    && ((privateFlags & FOCUSED) != 0)) {
                /* Give up focus if we are no longer focusable */
                clearFocus();
            } else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
                    && ((privateFlags & FOCUSED) == 0)) {
                /*
                 * Tell the view system that we are now available to take focus
                 * if no one else already has it.
                 */
                if (mParent != null) mParent.focusableViewAvailable(this);
            }
        }

...

答案 3 :(得分:2)

尝试使用此文本视图我认为它可能对您有所帮助

<TextView 
 ... 
 android:freezesText="true" />

答案 4 :(得分:0)

Android View类有受保护的方法

protected Parcelable onSaveInstanceState ()
protected void onRestoreInstanceState (Parcelable state)

所以任何视图都可以覆盖这些方法并用它们保存View的状态信息。

TextView扩展了View类,并在其中实现了受保护的Parcelable onSaveInstanceState()和protected void onRestoreInstanceState(Parcelable state)。

让我们看看onSaveInstanceState()

的实现
@Override
public Parcelable onSaveInstanceState()
{
    Parcelable superState = super.onSaveInstanceState();

    // Save state if we are forced to
    boolean save = mFreezesText;
    int start = 0;
    int end = 0;

    if (mText != null) 
    {
        start = getSelectionStart();
        end = getSelectionEnd();
        if (start >= 0 || end >= 0)
        {
            // Or save state if there is a selection
            save = true;
        }
    }
    ...
}
  1. 正如您在此处所见,保存功能取决于单个标记&#34;保存&#34; 因此,如果用户明确指定mFreezesText = true,那么它将保存 文字
  2. 另一种可能性如果有选择光标那么它至少会返回getSelectionStart()= 0而不是-1会导致TextView使save = true保存TextView的状态,这就是EditText发生的事情,因为EditText有选择光标它确实扩展了TextView。