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重建,因此對于【語言】【時區(qū)】的調(diào)整可能需要重新啟動Activity才能更新。
注意:
語言的變化需要配置為
android:configChanges="locale|layoutDirection"
屏幕旋轉(zhuǎn)需要配置為
android:configChanges="orientation|keyboard|screenSize"
③onRetainNonConfigurationInstance
此方法是3.0版本的Android系統(tǒng)中提供了代替方式②的一種方式,使用場景是允許屏幕旋轉(zhuǎn)、時區(qū)和語言調(diào)整及時反應(yīng)。但是對于當(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),因此可以成為后臺Fragment。
要實(shí)現(xiàn)后臺Fragment,必須做到在Activity重建的時候不被銷毀,原理就是通過setRetainInstance方法實(shí)現(xiàn)。
public class WorkFragment extends Fragment {
NetWorkTask netWorkTask = null;
/**
* 重建之后這里的Context會自動替換成新的Activity
* @param context
*/
@Override
public void onAttach(Context context) {
super.onAttach(context);
//第一次啟動的時候,這里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); //重建之后不再會調(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+"%");
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android編程設(shè)計(jì)模式之模板方法模式詳解
這篇文章主要介紹了Android編程設(shè)計(jì)模式之模板方法模式,結(jié)合實(shí)例形式詳細(xì)分析了Android模板方法模式的概念、功能、使用場景、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2017-12-12
Android自定義View實(shí)現(xiàn)拖動自動吸邊效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)拖動自動吸邊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06
Android使用Service實(shí)現(xiàn)簡單音樂播放實(shí)例
這篇文章主要為大家詳細(xì)介紹了Android使用Service實(shí)現(xiàn)簡單音樂播放實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android流式布局實(shí)現(xiàn)歷史搜索記錄功能
最近在開發(fā)項(xiàng)目的時候,有一個需求是展示歷史搜索記錄 ,展示的樣式是流式布局(就是根據(jù)內(nèi)容自動換行)。接下來通過本文給大家分享android流式布局實(shí)現(xiàn)歷史搜索記錄功能,感興趣的的小伙伴參考下2017-05-05
Android沉浸式狀態(tài)欄實(shí)現(xiàn)
這篇文章主要介紹了Android沉浸式狀態(tài)欄實(shí)現(xiàn),即一體化狀態(tài)欄實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2016-01-01
android:layout_gravity和android:gravity的區(qū)別
本篇文章主要介紹了android中g(shù)iavity和layout_gravity的區(qū)別。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04
Android實(shí)現(xiàn)購物車整體頁面邏輯詳解
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)購物車的整體頁面邏輯,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-11-11
Android實(shí)現(xiàn)完整游戲循環(huán)的方法
這篇文章主要介紹了Android實(shí)現(xiàn)完整游戲循環(huán)的方法,以實(shí)例代碼形式較為詳細(xì)的分析了Android游戲循環(huán)的實(shí)現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10

