Khôi phục trạng thái của TextView sau khi xoay màn hình?


104

Trong ứng dụng của tôi, tôi có TextViewEditText. Cả hai đều có dữ liệu trong đó. Khi hướng màn hình thay đổi, dữ liệu trong phần EditTextcòn lại, nhưng TextViewdữ liệu bị xóa.

Ai đó có thể giúp tôi tìm cách giữ lại dữ liệu TextViewkhông?

Câu trả lời:


221

Nếu bạn muốn buộc bạn TextViewlưu trạng thái của nó, bạn phải thêm freezesTextthuộc tính:

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

Từ tài liệu trên freezesText:

Nếu được đặt, chế độ xem văn bản sẽ bao gồm văn bản hoàn chỉnh hiện tại của nó bên trong biểu tượng đóng băng của nó cùng với siêu dữ liệu như vị trí con trỏ hiện tại. Theo mặc định, điều này bị tắt; nó có thể hữu ích khi nội dung của dạng xem văn bản không được lưu trữ ở một nơi lâu dài chẳng hạn như trình cung cấp nội dung


13
Tại sao văn bản không được 'cố định / lưu' theo mặc định giống như các thuộc tính khác (lựa chọn văn bản, vị trí con trỏ, v.v.)? Nói cách khác, một người nào đó thực sự muốn văn bản không được lưu trong trường hợp nào?
Gautam

3
@Gautam dự đoán của tôi là thường thì các TextView được xây dựng từ các chuỗi tĩnh được lưu trữ trong XML, trong trường hợp đó, nó là thừa để hệ thống ghi nhớ các giá trị.
anderspitman

3
Trên thực tế, khi bạn cung cấp id cho EditText hoặc TextView, giá trị sẽ tồn tại trong sự kiện xoay màn hình.
DoctorFox

7
@jegesh - không may đây không phải là trường hợp cho TextView ít nhất là trên một số thiết bị (Jellybean)
Bo Macht Blau

1
Không làm việc cho tôi, ít nhất là không phải trên một thiết bị API 17
Ab

28

Để giữ lại dữ liệu về sự thay đổi hướng, bạn cần thực hiện hai phương pháp:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Read values from the "savedInstanceState"-object and put them in your textview
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save the values you need from your textview into "outState"-object
    super.onSaveInstanceState(outState);
}

5
Tại sao lại sử dụng onRestoreInstanceState khi cùng một gói có sẵn trong onCreate?
slott

4
@slott Kiểm tra tài liệu này. developer.android.com/training/basics/activity-lifecycle/… Đây là phỏng đoán nhưng tôi nghi ngờ đó là do hệ thống theo dõi xem nó đang tạo một hoạt động mới hay tạo lại một hoạt động cũ. onRestorySavedInstance chỉ được gọi trong những trường hợp hiếm hơn - thay đổi cấu hình và hủy hoạt động do giới hạn bộ nhớ.
Gusdor

6

1) Không phải tất cả các chế độ xem có ID đều lưu trạng thái của chúng. Các widget Android, với một ID, người dùng có thể thay đổi trạng thái của nó, có vẻ như để lưu trạng thái của chúng dưới dạng soft kill. Vì vậy, EditText lưu trạng thái của nó, nhưng TextView không lưu trạng thái của nó khi giết mềm.

"AFAIK, Android chỉ làm phiền trạng thái lưu cho những thứ dự kiến ​​sẽ thay đổi. Đó là lý do tại sao nó lưu văn bản trong một EditText (mà người dùng có thể thay đổi) và có lẽ không lưu trạng thái cho TextView (thường vẫn ở trạng thái tĩnh ) "

Đánh dấu M

Vì vậy, bạn có thể chọn lưu trạng thái của chế độ xem văn bản trong onSaveInstanceState và bạn có thể chọn khôi phục trạng thái của chế độ xem văn bản trong onCreate.

2) Phương pháp hay nhất là lưu trạng thái phiên bản "nội bộ" không xem ngay cả khi bạn khai báo

android:configChanges= "orientation|keyboardHidden" 

Từ các tài liệu:

"Tuy nhiên, ứng dụng của bạn phải luôn có thể tắt và khởi động lại với trạng thái nguyên vẹn trước đó. Không chỉ vì có những thay đổi cấu hình khác mà bạn không thể ngăn việc khởi động lại ứng dụng của mình mà còn để xử lý các sự kiện chẳng hạn như khi người dùng nhận được thư đến gọi điện thoại và sau đó quay lại ứng dụng của bạn. "

JAL


6

Android không xử lý loại nội dung đó cho bạn. Bạn đã lưu tất cả dữ liệu theo cách thủ công.

Bạn có thể sử dụng trong một hoạt động để lưu các giá trị

@Override
    public Object onRetainNonConfigurationInstance() {
        HashMap<String, Object> savedValues = new HashMap<String, Object>();
        savedValues.put("someKey", someData);           
        return savedValues;
    }

và sử dụng một cái gì đó như thế này trong phương thức oncreate của một hoạt động để tải các đối tượng đã lưu

HashMap < String, Object> savedValues 
     = (HashMap<String, Object>)this.getLastNonConfigurationInstance();

bạn cũng có thể chọn thay đổi hướng tắt cho một hoạt động

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>

không thể ghi đè onRetainNonConfigurationInstance () trong android.support.v4.app.fragmentActivity; phương thức ghi đè là cuối cùng !!
Akash Dubey

1

Sửa đổi các hoạt động của bạn trong AndroidManifest.xml để ghi đè hành vi thay đổi định hướng bằng cách thêm điều này vào hoạt động / hoạt động của bạn:

android:configChanges="orientation|keyboardHidden"

Nó sẽ giống như sau:

    <activity android:name=".activity.LoginActivity"
              android:configChanges="orientation|keyboardHidden"
              android:label="@string/app_name">
    </activity>

27
Nói chung, phương pháp này không được khuyến khích bởi các tài liệu : "Sử dụng thuộc tính này nên tránh và chỉ được sử dụng như một last-resort Vui lòng đọc. Xử lý Runtime thay đổi ..."
idbrii

1

Thêm những thứ này vào AndroidManifest.xml
Đặt Tên hoạt động của bạn vào vị trí của Activity_Name

<activity android:name="Activity_Name"
        android:screenOrientation="sensor"
        ...
        android:configChanges="orientation|keyboardHidden|screenSize">

Điều này cũng sẽ hoạt động với TextField thay đổi giá trị.


1

chỉ cần thêm

android:configChanges="orientation|screenSize"

vào Hoạt động của bạn trong AndroidManifest.xml.


-2

Khi cấu hình thay đổi, Android sẽ khởi động lại hoạt động của bạn theo mặc định. Để thay đổi điều này, bạn nên ghi đè onConfigurationChanged()phương thức. Ngoài ra, bạn nên thêm android:configChangesvào tệp kê khai của mình.

Bạn có thể đọc thêm ở đây .


-7

Tôi cũng đã sử dụng

android:configChanges="orientation"

và nó đã không hoạt động.

Nhưng sau đó tôi đã tìm ra giải pháp.

Xác minh xem bạn có dòng sau đúng trong ý muốn của bạn không:

<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="11" />

đảm bảo rằng nó không đọc một cái gì đó như

<uses-sdk android`:minSdkVersion="11" android:targetSdkVersion="15" />`

Tôi đã có nó theo cách thứ hai ở vị trí đầu tiên nhưng khi tôi sửa nó, trạng thái vẫn được giữ nguyên.


1
Đây là một điều hoàn toàn khác. Mục tiêu SDK là làm cho ứng dụng của bạn tương thích với hầu hết các phạm vi hệ điều hành Android. Đây không phải là một câu trả lời, theo một số nghĩa là điều này có thể đã hoạt động trong trường hợp của bạn nhưng đây không phải là một giải pháp phù hợp.
Rohan Kandwal
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.