7

Edittext有什麼特別的地方,它可以保留值,但不是Textview和其他一些小部件,我們必須爲它們使用onSavedInstance()方法。EditText如何在電話方向更改時保留其值而不是textview?

EditText的特殊之處在於它可以保留這些值嗎?

如果有人能說出它是如何在內部工作的。

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

它的內部工作原理,請指向這也解釋了此方案中的那部分代碼。

+0

是你通過代碼設置TextView的值嗎? – Atrix1987 2013-03-21 10:44:56

+0

我不問如何保留它,但它是如何由android自動處理的? – 2013-03-21 10:46:28

+0

其實它會...或者你試圖說點別的嗎?/ – Kiran 2013-03-21 10:46:38

回答

5

從這篇文章中引用:http://tekeye.biz/2012/saving-activity-state

「從縱向切換設備爲橫向導致Android的停止和重新啓動的活動,使活動的機會,重繪屏幕爲不同尺寸隨着停止和啓動一個活動。如果輸入保持丟失,常見的用戶會感到惱火Android有一對叫做onSaveInstanceState(Bundle)和onRestoreInstanceState(Bundle)的方法,View自動使用它們來保存它們的數據。因此需要EditText有一個id,這個方法對可以在一個Activity中重寫,這樣也可以保存和恢復與輸入字段無關的狀態變量。 「

從一個EditText刪除ID和嘗試:)

+0

Textview和edittext都是最初的mFreeze爲false。但Edittext保持狀態。但Textview不維護狀態。這是怎麼發生的? – 2016-01-11 10:18:38

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()返回-1,由save變量保存假值。要使其在方向更改時保留其內容,請將屬性textIsSelectable設置爲true。

EditText由於是默認選擇的,getSelectionStart()getSelectionEnd()總是由save變量的返回值> = 0,有保持真值和該內容被保存。

注意:默認情況下,freezesText已禁用。因此mFreezesText值是錯誤的。

+0

你能解釋爲什麼當'textIsSelectable'爲true時,getSelectionStart()和getSelectionEnd()總是返回值> = 0嗎?我的意思是,如果文本是可選的,但沒有選擇,兩個方法都不應該返回-1嗎? – curioustechizen 2014-11-03 11:26:50

+0

@curioustechizen如果未選擇文本,則選擇開始和結束將爲0,這表示未選擇任何文本。這與將光標置於第0個索引處相同,如EditText的情況。這是[place](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/android/text/method/ArrowKeyMovementMethod.java?av = f#302)它被設置爲0. – 2014-11-03 12:46:32

+0

嗯..這是令人困惑的。你鏈接的代碼似乎與javadocs相矛盾。具體來說,'TextView#getSelectionStart()'指向'android.text.Selection#getSelectionStart()'。 javadocs爲後者狀態:'返回選擇錨點或遊標的偏移量,如果沒有選擇或遊標,則返回-1。' – curioustechizen 2014-11-03 13:06:05

3

默認情況下,EditText視圖保存其狀態 - 這是通過在代碼中設置標誌來告訴視圖在視圖不可見或失去焦點時保存狀態來實現的。旋轉設備後,文本會自動保存並恢復。鑑於的EditText狀態的自動保存可以在XML佈局文件中設置了android禁用:saveEnabled屬性設置爲false:

android:saveEnabled="false" 

或以編程方式,調用view.setSaveEnabled(false)

saveEnabled控制是否啓用保存此視圖的狀態(即,是否調用其onSaveInstanceState()方法)。請注意,即使啓用了凍結,視圖仍然必須爲其狀態分配一個ID(通過setId())以保存其狀態。這個標誌只能禁止保存這個視圖;任何子視圖可能仍保存其狀態。 saveEnabled屬性是android查看 - 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); 
      } 
     } 

....

1

試試這個你TextView的,我認爲它可以幫到你

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

Android設備上查看課堂上所保護的方法

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

所以任何視圖可以覆蓋這些方法和保存視圖狀態的信息與他們。

TextView擴展View類並實現受保護的Parcelable onSaveInstanceState()並保護其中的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時發生的事情選擇下載或者它確實擴展了TextView。
相關問題