Android RetainFragment狀態(tài)保存的方法
一、常見的狀態(tài)保存恢復(fù)方式
①onSaveInstance + onRestoreInstance
這種方式是最通用的實(shí)現(xiàn)狀態(tài)保存與恢復(fù),在Android生態(tài)種,組件和View大量使用了此方式。
②android:configChanges+onConfigurationChanged
這種情況適用于屏幕旋轉(zhuǎn)和配置變化,只要作用是阻止Activity重建,因此對(duì)于【語(yǔ)言】【時(shí)區(qū)】的調(diào)整可能需要重新啟動(dòng)Activity才能更新。
注意:
語(yǔ)言的變化需要配置為
android:configChanges="locale|layoutDirection"
屏幕旋轉(zhuǎn)需要配置為
android:configChanges="orientation|keyboard|screenSize"
③onRetainNonConfigurationInstance
此方法是3.0版本的Android系統(tǒng)中提供了代替方式②的一種方式,使用場(chǎng)景是允許屏幕旋轉(zhuǎn)、時(shí)區(qū)和語(yǔ)言調(diào)整及時(shí)反應(yīng)。但是對(duì)于當(dāng)前系統(tǒng)的狀態(tài)或者進(jìn)行的任務(wù)需要進(jìn)行保存。
如線程任務(wù)
public class NetWorkTask extends Thread { private volatile ProgressUpdateLinster progressUpdateLinster; private Handler handler = new Handler(Looper.getMainLooper()); public NetWorkTask(ProgressUpdateLinster progressUpdateLinster) { this.progressUpdateLinster = progressUpdateLinster; } private int progress = 0; @Override public void run() { while (progress <= 100) { if(progressUpdateLinster != null) { handler.post(new Runnable() { @Override public void run() { progressUpdateLinster.updateProgress(progress); } }); } try { Thread.sleep(200); } catch (InterruptedException e) { return; } progress += 2; } } public interface ProgressUpdateLinster { void updateProgress(int progress); } public void cacel() { interrupt(); } public void setProgressUpdateLinster(ProgressUpdateLinster progressUpdateLinster) { this.progressUpdateLinster = progressUpdateLinster; } }
在Activity中保存狀態(tài)
private ProgressBar progressBar; private TextView textView; private static final String TAG = "MainActivity"; NetWorkTask netWorkTask = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressbar); textView = (TextView) findViewById(R.id.tv_progroess); if(getLastCustomNonConfigurationInstance() != null && getLastCustomNonConfigurationInstance() instanceof NetWorkTask) { this.netWorkTask = (NetWorkTask) getLastCustomNonConfigurationInstance(); //獲取保存的任務(wù) this.netWorkTask.setProgressUpdateLinster(linster); }else { this.netWorkTask = new NetWorkTask(); netWorkTask.setProgressUpdateLinster(linster); netWorkTask.start(); } } private NetWorkTask.ProgressUpdateLinster linster = new NetWorkTask.ProgressUpdateLinster() { @Override public void updateProgress(int progress) { progressBar.setProgress(progress); textView.setText(progress+"%"); Log.d(TAG,MainActivity.this.toString()); } }; /** * 保存任務(wù) */ @Override public Object onRetainCustomNonConfigurationInstance() { return netWorkTask; }
④RetainFragment
所謂RetainFragment并不是多么高大上的Fragment,和DialogFragment一樣本身都是比較普通的,這里的RetainFragment更注重【用途】,而非Fragment的名稱。
Fragment同樣是Android 3.0 版本的API,不過support-v4中也提供了補(bǔ)充方式。這種保存狀態(tài)的原理是將Fragment加入FragmentManager的事務(wù)中,但是并不顯示到界面中(也不需要實(shí)現(xiàn)view),因此可以成為后臺(tái)Fragment。
要實(shí)現(xiàn)后臺(tái)Fragment,必須做到在Activity重建的時(shí)候不被銷毀,原理就是通過setRetainInstance方法實(shí)現(xiàn)。
public class WorkFragment extends Fragment { NetWorkTask netWorkTask = null; /** * 重建之后這里的Context會(huì)自動(dòng)替換成新的Activity * @param context */ @Override public void onAttach(Context context) { super.onAttach(context); //第一次啟動(dòng)的時(shí)候,這里network還沒有初始化 //Activity重建之后,更新回調(diào) if(netWorkTask != null) { netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster) context); } } @Override public void onDetach() { super.onDetach(); netWorkTask.setProgressUpdateLinster(null); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //重建之后不再會(huì)調(diào)用此方法 //設(shè)置為retain instance Fragment setRetainInstance(true); netWorkTask = new NetWorkTask(); netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster) getActivity()); netWorkTask.start(); } }
Activity中的使用方式
public class MainActivity extends AppCompatActivity implements NetWorkTask.ProgressUpdateLinster { private ProgressBar progressBar; private TextView textView; private static final String TAG = "MainActivity"; private static final String TAG_TASK_FRAGMENT = "work"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressbar); textView = (TextView) findViewById(R.id.tv_progroess); //如果已經(jīng)有了work fragment,那就不需要再新建了 if(getSupportFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT) == null) { getSupportFragmentManager().beginTransaction().add(new WorkFragment(),TAG_TASK_FRAGMENT).commit(); } } @Override public void updateProgress(int progress) { progressBar.setProgress(progress); textView.setText(progress+"%"); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解析Android開發(fā)優(yōu)化之:對(duì)界面UI的優(yōu)化詳解(一)
在Android應(yīng)用開發(fā)過程中,屏幕上控件的布局代碼和程序的邏輯代碼通常是分開的。界面的布局代碼是放在一個(gè)獨(dú)立的xml文件中的,這個(gè)文件里面是樹型組織的,控制著頁(yè)面的布局2013-05-05android activity設(shè)置無(wú)標(biāo)題實(shí)現(xiàn)全屏
本文將詳細(xì)介紹Android如何設(shè)置Activity全屏和無(wú)標(biāo)題的實(shí)現(xiàn)方法,需要的朋友可以參考下2012-12-12淺談Android Studio 4.1 更新內(nèi)容
這篇文章主要介紹了淺談Android Studio 4.1 更新內(nèi)容,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Kotlin協(xié)程啟動(dòng)createCoroutine及創(chuàng)建startCoroutine原理
這篇文章主要為大家介紹了Kotlin協(xié)程啟動(dòng)createCoroutine及創(chuàng)建startCoroutine原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Android模擬實(shí)現(xiàn)華為系統(tǒng)升級(jí)進(jìn)度條
這篇文章主要介紹了如何通過Android模擬實(shí)現(xiàn)華為在系統(tǒng)升級(jí)時(shí)顯示的進(jìn)度條。文中的實(shí)現(xiàn)過程講解詳細(xì),感興趣的小伙伴可以動(dòng)手試一試2022-01-01Android?無(wú)障礙服務(wù)?performAction?調(diào)用過程分析
這篇文章主要介紹了Android?無(wú)障礙服務(wù)?performAction?調(diào)用過程分析,無(wú)障礙服務(wù)可以模擬一些用戶操作,無(wú)障礙可以處理的對(duì)象,通過類?AccessibilityNodeInfo?表示,通過無(wú)障礙服務(wù),可以通過它的performAction方法來觸發(fā)一些action2022-06-06android異步加載圖片并緩存到本地實(shí)現(xiàn)方法
圖片過多造成內(nèi)存溢出,這個(gè)是最不容易解決的,要想一些好的緩存策略,比如大圖片使用LRU緩存策略或懶加載緩存策略。今天首先介紹一下本地緩存圖片2013-01-01