11

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

EditText 背后的魔力是什么,它可以保留这些值?

如果有人能说出它在内部是如何工作的。

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

它是如何在内部工作的,请指出解释这种情况的那部分代码。

4

5 回答 5

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变量持有错误值。要使其在方向更改时保留其内容,请将属性textIsSelectable设置为 true。

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

注意:默认情况下freezesText是禁用的。因此mFreezesText价值是假的。

于 2014-11-01T02:46:30.353 回答
5

默认情况下,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);
            }
        }

……

于 2014-11-07T04:03:33.493 回答
5

引用这篇文章:https ://tekeye.uk/android/examples/saving-activity-state

“将设备从纵向切换到横向会导致 Android 停止并重新启动 Activity,从而使 Activity 有机会为不同尺寸重新绘制屏幕。通过停止和启动 Activity,如果输入不断丢失,用户会很恼火。Android活动有一对名为 onSaveInstanceState(Bundle) 和 onRestoreInstanceState(Bundle) 的方法,输入视图自动使用它们来保存它们的数据。这些方法只有在可以识别获取数据的视图时才有效,因此需要 EditText (和所有屏幕项目)都有一个 id。一个好处是这个方法对可以在一个活动中被覆盖,这样与输入字段无关的状态变量也可以被保存和恢复。

从编辑文本中删除 id 并尝试:)

于 2013-03-21T11:02:20.840 回答
2

试试这个为你的 textview 我认为它可以帮助你

<TextView 
 ... 
 android:freezesText="true" />
于 2014-11-07T05:33:40.523 回答
0

Android View 类具有受保护的方法

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

因此任何视图都可以覆盖这些方法并与它们一起保存视图的状态信息。

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

让我们看看 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. 如您所见,保存功能取决于单个标志“保存”,因此如果用户明确指定 mFreezesText = true 那么它将保存文本
  2. 另一种可能性,如果有选择光标,那么它至少会返回 getSelectionStart() = 0 而不是 -1 这将导致 TextView 使 save=true 保存 TextView 的状态,这就是 EditText 发生的事情,因为 EditText 有选择光标并且它确实扩展文本视图。
于 2014-11-07T08:58:56.593 回答