การกู้คืนสถานะของ TextView หลังจากการหมุนหน้าจอ?


104

ในแอปของฉันฉันมีTextViewและEditText. ทั้งสองมีข้อมูลอยู่ในนั้น เมื่อการวางแนวหน้าจอเปลี่ยนข้อมูลในส่วนที่EditTextเหลือ แต่TextViewข้อมูลจะถูกล้าง

มีใครช่วยหาวิธีเก็บรักษาข้อมูลTextViewด้วยได้ไหม

คำตอบ:


222

หากคุณต้องการบังคับTextViewให้บันทึกสถานะคุณต้องเพิ่มfreezesTextแอตทริบิวต์:

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

จากเอกสารเกี่ยวกับfreezesText:

หากตั้งค่าไว้มุมมองข้อความจะรวมข้อความที่สมบูรณ์ในปัจจุบันไว้ในไอติมที่แช่แข็งนอกเหนือจากข้อมูลเมตาเช่นตำแหน่งเคอร์เซอร์ปัจจุบัน โดยค่าเริ่มต้นจะปิดใช้งาน มันจะมีประโยชน์เมื่อเนื้อหาของมุมมองข้อความไม่ได้ถูกเก็บไว้ในที่ถาวรเช่นผู้ให้บริการเนื้อหา


13
เหตุใดข้อความจึงไม่ "ตรึง / บันทึก" โดยค่าเริ่มต้นเหมือนกับแอตทริบิวต์อื่น ๆ (การเลือกข้อความตำแหน่งเคอร์เซอร์ ฯลฯ ) กล่าวอีกนัยหนึ่งในสถานการณ์ใดที่ใครบางคนต้องการที่จะไม่บันทึกข้อความ
Gautam

3
@Gautam ฉันเดาว่าบ่อยครั้งที่ TextViews สร้างขึ้นจากสตริงแบบคงที่ที่เก็บใน XML ซึ่งในกรณีนี้ระบบจะจำค่าซ้ำซ้อน
anderspitman

3
จริงๆแล้วเมื่อคุณให้รหัส EditText หรือ TextView แล้วค่าจะยังคงอยู่ในระหว่างเหตุการณ์การหมุนหน้าจอ
DoctorFox

7
@jegesh - น่าเสียดายที่นี่ไม่ใช่กรณีของ TextViews อย่างน้อยในอุปกรณ์บางอย่าง (Jellybean)
Bö macht Blau

1
ไม่ทำงานสำหรับฉันอย่างน้อยไม่ได้บนอุปกรณ์ API 17
Ab

28

ในการเก็บรักษาข้อมูลเกี่ยวกับการเปลี่ยนแปลงการวางแนวคุณต้องใช้สองวิธี:

@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
เหตุใดจึงต้องใช้ onRestoreInstanceState เมื่อบันเดิลเดียวกันพร้อมใช้งานใน onCreate
slott

4
@slott ตรวจสอบเอกสารนี้ developer.android.com/training/basics/activity-lifecycle/…นี่เป็นการคาดเดา แต่ฉันสงสัยว่าเป็นเพราะระบบติดตามว่ากำลังสร้างกิจกรรมใหม่หรือสร้างกิจกรรมเก่าขึ้นมาใหม่ onRestorySavedInstance ถูกเรียกใช้ในสถานการณ์ที่หายากเท่านั้น - การเปลี่ยนแปลงการกำหนดค่าและการทำลายกิจกรรมเนื่องจากข้อ จำกัด ของหน่วยความจำ
Gusdor

6

1) ไม่ใช่ทุกมุมมองที่มี ID จะบันทึกสถานะ วิดเจ็ต Android ที่มี ID ซึ่งผู้ใช้สามารถเปลี่ยนสถานะได้ดูเหมือนจะบันทึกสถานะของพวกเขาในการฆ่าแบบนุ่มนวล ดังนั้น EditText จะบันทึกสถานะ แต่ TextView จะไม่บันทึกสถานะของมันในการฆ่าแบบนุ่มนวล

"AFAIK, Android จะรบกวนสถานะการบันทึกสำหรับสิ่งที่คาดว่าจะเปลี่ยนแปลงเท่านั้นนั่นคือเหตุผลว่าทำไมจึงบันทึกข้อความใน EditText (ซึ่งผู้ใช้มีแนวโน้มที่จะเปลี่ยนแปลง) และอาจไม่บันทึกสถานะสำหรับ TextView (ซึ่งโดยปกติจะคงที่ )”

มาร์คม

ดังนั้นคุณสามารถเลือกที่จะบันทึกสถานะของ textview ใน onSaveInstanceState และคุณอาจเลือกที่จะกู้คืนสถานะของ textview ใน onCreate

2) แนวทางปฏิบัติที่ดีที่สุดคือบันทึกสถานะอินสแตนซ์ที่ไม่ใช่มุมมอง "ภายใน" แม้ว่าคุณจะประกาศก็ตาม

android:configChanges= "orientation|keyboardHidden" 

จากเอกสาร:

"อย่างไรก็ตามแอปพลิเคชันของคุณควรสามารถปิดระบบและรีสตาร์ทได้ตลอดเวลาโดยที่สถานะก่อนหน้าไม่เสียหายไม่เพียงเพราะมีการเปลี่ยนแปลงการกำหนดค่าอื่น ๆ ที่คุณไม่สามารถป้องกันไม่ให้รีสตาร์ทแอปพลิเคชันของคุณได้ แต่ยังเพื่อจัดการกับเหตุการณ์ต่างๆเช่นเมื่อผู้ใช้ได้รับข้อความเข้า โทรศัพท์แล้วกลับไปที่แอปพลิเคชันของคุณ "

JAL


6

Android ไม่ได้จัดการเรื่องแบบนั้นให้คุณ คุณได้บันทึกข้อมูลทั้งหมดด้วยตนเอง

คุณสามารถใช้ในกิจกรรมเพื่อบันทึกค่า

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

และใช้สิ่งนี้ในวิธีการสร้างกิจกรรมเพื่อโหลดวัตถุที่บันทึกไว้

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

คุณยังสามารถเลือกปิดการใช้งานการเปลี่ยนแปลงการวางแนวสำหรับกิจกรรม

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

ไม่สามารถแทนที่ onRetainNonConfigurationInstance () ใน android.support.v4.app.fragmentActivity วิธีการแทนที่ถือเป็นที่สิ้นสุด !!
Akash Dubey

1

แก้ไขกิจกรรมของคุณใน AndroidManifest.xml เพื่อลบล้างพฤติกรรมการเปลี่ยนแปลงการวางแนวโดยเพิ่มสิ่งนี้ในกิจกรรม / กิจกรรมของคุณ:

android:configChanges="orientation|keyboardHidden"

ควรมีลักษณะดังนี้:

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

27
โดยทั่วไปเอกสารประกอบไม่แนะนำวิธีนี้: "ควรหลีกเลี่ยงการใช้แอตทริบิวต์นี้และใช้เป็นทางเลือกสุดท้ายเท่านั้นโปรดอ่านHandling Runtime Changes ... "
idbrii

1

เพิ่มสิ่งเหล่านี้ใน AndroidManifest.xml
ใส่ชื่อกิจกรรมของคุณในตำแหน่งของActivity_Name

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

สิ่งนี้จะใช้ได้กับการเปลี่ยนค่า TextField ด้วย



-2

เมื่อการกำหนดค่าเปลี่ยนแปลง Android จะรีสตาร์ทกิจกรรมของคุณตามค่าเริ่มต้น ในการเปลี่ยนสิ่งนี้คุณควรแทนที่onConfigurationChanged()วิธีการ นอกจากนี้คุณควรเพิ่มandroid:configChangesไฟล์รายการของคุณ

คุณสามารถอ่านเพิ่มเติมที่นี่


-7

ฉันยังใช้

android:configChanges="orientation"

และมันไม่ได้ผล

แต่แล้วฉันก็พบวิธีแก้ปัญหา

ตรวจสอบว่าคุณมีบรรทัดต่อไปนี้อย่างถูกต้องหรือไม่:

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

ตรวจสอบให้แน่ใจว่าไม่ได้อ่านสิ่งที่ชอบ

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

ฉันมีวิธีที่สองในตอนแรก แต่เมื่อฉันแก้ไขสถานะได้รับการรักษาไว้


1
นี่เป็นสิ่งที่แตกต่างอย่างสิ้นเชิง Target SDK คือการทำให้แอปของคุณเข้ากันได้กับระบบปฏิบัติการ Android ส่วนใหญ่ นี่ไม่ใช่คำตอบเนื่องจากบางวิธีอาจใช้ได้ผลในกรณีของคุณ แต่นี่ไม่ใช่วิธีแก้ปัญหาที่เหมาะสม
Rohan Kandwal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.