2017-08-13 69 views
1

我在Android Studio中创建了一个示例应用程序,以了解Android应用程序的生命周期。我知道方向改变完全重新开始活动(即再次调用OnCreate方法)。 据我所知,方向改变应该已经破坏了上下文,并在设备旋转后显示一个空白文本。但不知怎的,没有重写onSaveInstanceState和onRestoreInstanceState方法,它保存了上下文。EditText自动保存设备旋转后的值

我没有任何碎片。它只是Android Studio提供的基本模板,几乎没有重载的生命周期方法。 这里是我的MainActivity类别:

package com.example.android.a2_screen_orientation_change; 

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 

public class MainActivity extends AppCompatActivity { 

    private static final String TAG = MainActivity.class.getSimpleName(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     Log.i(TAG, "in method onStart"); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     Log.i(TAG, "in method onResume"); 
    } 

    @Override 
    protected void onRestart() { 
     super.onRestart(); 
     Log.i(TAG, "in method onRestart"); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     Log.i(TAG, "in method onPause"); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     Log.i(TAG, "in method onStop"); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     Log.i(TAG, "in method onDestroy"); 
    } 
} 

布局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.android.a2_screen_orientation_change.MainActivity"> 

    <EditText 
     android:id="@+id/editText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

AbdroidManifest:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.android.a2_screen_orientation_change"> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:roundIcon="@mipmap/ic_launcher_round" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

图片: Text got saved even after device orientation change

+0

这个活动怎么样是导致您认为国家是不会回到原点?请在你的问题中列出这样的状态。 –

+0

等待,我将添加截图 –

+0

'EditText's自动保存/恢复保存状态包中的文本。你不需要做任何事情就可以发生。 https://developer.android.com/reference/android/widget/TextView.html#setFreezesText(boolean)(注意“冰柱”是保存状态包的旧术语。) –

回答

2

由于EditText是一个聚焦视图,所以在PhoneWindow中,它的状态将自动保存在saveHierarchyState()方法中。你可以看到代码:

@Override 
public Bundle saveHierarchyState() { 
    Bundle outState = new Bundle(); 
    if (mContentParent == null) { 
     return outState; 
    } 
    SparseArray<Parcelable> states = new SparseArray<Parcelable>(); 
    mContentParent.saveHierarchyState(states); 
    outState.putSparseParcelableArray(VIEWS_TAG, states); 
    // save the focused view id 
    View focusedView = mContentParent.findFocus(); 
    if (focusedView != null) { 
     if (focusedView.getId() != View.NO_ID) { 
      outState.putInt(FOCUSED_ID_TAG, focusedView.getId()); 
     } else { 
      if (false) { 
       Log.d(TAG, "couldn't save which view has focus because the focused view " 
         + focusedView + " has no id."); 
      } 
     } 
    } 
    // save the panels 
    SparseArray<Parcelable> panelStates = new SparseArray<Parcelable>(); 
    savePanelState(panelStates); 
    if (panelStates.size() > 0) { 
     outState.putSparseParcelableArray(PANELS_TAG, panelStates); 
    } 
    if (mActionBar != null) { 
     outState.putBoolean(ACTION_BAR_TAG, mActionBar.isOverflowMenuShowing()); 
    } 
    return outState; 
} 

和代码TextView

@Override 
public Parcelable onSaveInstanceState() { 
    Parcelable superState = super.onSaveInstanceState(); 
    // Save state if we are forced to 
    final boolean freezesText = getFreezesText(); 
    boolean hasSelection = false; 
    int start = -1; 
    int end = -1; 
    if (mText != null) { 
     start = getSelectionStart(); 
     end = getSelectionEnd(); 
     if (start >= 0 || end >= 0) { 
      // Or save state if there is a selection 
      hasSelection = true; 
     } 
    } 
    if (freezesText || hasSelection) { 
     SavedState ss = new SavedState(superState); 
     if (freezesText) { 
      if (mText instanceof Spanned) { 
       final Spannable sp = new SpannableStringBuilder(mText); 
       if (mEditor != null) { 
        removeMisspelledSpans(sp); 
        sp.removeSpan(mEditor.mSuggestionRangeSpan); 
       } 
       ss.text = sp; 
      } else { 
       ss.text = mText.toString(); 
      } 
     } 
     if (hasSelection) { 
      // XXX Should also save the current scroll position! 
      ss.selStart = start; 
      ss.selEnd = end; 
     } 
     if (isFocused() && start >= 0 && end >= 0) { 
      ss.frozenWithFocus = true; 
     } 
     ss.error = getError(); 
     if (mEditor != null) { 
      ss.editorState = mEditor.saveInstanceState(); 
     } 
     return ss; 
    } 
    return superState; 
} 

所以,如果你删除EditTextView的ID在XML文件中:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.android.a2_screen_orientation_change.MainActivity"> 

    <EditText 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

你会看你想要什么! (从@Mike M.坦克的补充)

+0

谢谢,我试过,它的工作。 有趣的行为! –

+0

的确,删除ID会导致EditText不保存它的文本,但你所引用的saveHierarchyState()方法与此无关。所有该方法正在做 - 就EditText而言 - 正在保存其ID,因此当层次结构恢复时,同一个ID将被赋予焦点。它与文本无关。 –

+0

@MikeM。这是真的,谢谢你的正确! – vesper

1

Android是在默认情况下,恢复了一些状态视图。 在Layout xml中,将android:saveEnabled="false"添加到EditText。而EditText的值将不会被保留。

+0

我看到一些教程,其中文字在方向更改后丢失。 在较新版本的Android中添加了此默认行为吗? –

+0

根据Android参考,此行为似乎没有从默认更改。但是,如果要刷新(清除)视图的数据,则必须将此属性设置为false。 https://developer.android.com/reference/android/R.attr.html#saveEnabled –

1

Android的自动处理节电状态&恢复,直到你明确指定

android:configChanges="orientation" 
在mainifest

在情况下,你没有一个id

对于UI元素,Android将无法恢复元素的状态。

请参考这里的答案 https://stackoverflow.com/a/19234974/1099156