這個Demo示範了如何從另一個Fragment中擷取資料,用到的方法是setTargetFragment方法,該方法允許為fragment設定一個目标fragment,該fragment就可以把目标fragment所需要的結果傳回給目标fragment。
同時示範了fragment另一個強大的功能:儲存fragment執行個體的功能。就是可以在Activity重新建立時可以不完全銷毀Fragment,以便Fragment可以恢複。在onCreate()方法中調用setRetainInstance(true/false)方法是最佳位置。
特别需要注意的是:當在onCreate()方法中調用了setRetainInstance(true)後,Fragment恢複時會跳過onCreate()和onDestroy()方法,是以不能在onCreate()中放置一些初始化邏輯,切忌!
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/hello_world" />
<ProgressBar
android:id="@+id/progress"
android:layout_width="240dp"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:max="100"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/restart"
android:text="restart"/>
</LinearLayout>
MainActivity
public class MainActivity extends Activity {
private RetainFragment mWorkFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
UiFragment ui = new UiFragment();
getFragmentManager().beginTransaction()
.add(android.R.id.content, ui).commit();
}
}
public class UiFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
Button restart = (Button) v.findViewById(R.id.restart);
restart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mWorkFragment.restart();
}
});
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getFragmentManager();
mWorkFragment = (RetainFragment) fm.findFragmentByTag("work");
// 判斷如果RetainFragment沒有被保留,或者是第一次運作,則建立
// RetainFragment的執行個體
if (mWorkFragment == null) {
mWorkFragment = new RetainFragment();
// 設定目标Fragmnet,設定後目标Fragment就可以直接使用該Fragment運作的結果了。
mWorkFragment.setTargetFragment(this, );
fm.beginTransaction().add(mWorkFragment, "work").commit();
}
}
}
public class RetainFragment extends Fragment {
private ProgressBar progressBar;
// 進度條目前的進度值
private int currentPosition;
// 進度條的最大值
private int max = ;
// 判斷進度條是否準備好(Ui界面是否準備完畢)
private boolean mReady = false;
// 判斷應用是否已經退出
private boolean mQuited = false;
Thread mThread = new Thread() {
@Override
public void run() {
super.run();
while (true) {
synchronized (this) {
// 如果UI沒有準備好或者進度條已經達到最大值,則讓線程處于等待狀态
while (!mReady || currentPosition >= max) {
// 如果應用已經退出則結束循環
if (mQuited) {
return;
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 更新進度條
max = progressBar.getMax();
currentPosition++;
progressBar.setProgress(currentPosition);
}
synchronized (this) {
// 每隔50毫秒更新一次進度
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
// 開啟線程用以完成我們要處理的資料,在這裡隻是簡單地示範了一個更新進度條的例子
// 當進度條達到最大值後停止并使線程處于等待狀态
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
* Fragment有一個非常強大的功能——就是可以在Activity重新建立時可以
* 不完全銷毀Fragment,以便Fragment可以恢複。在onCreate()方法中
* 調用setRetainInstance(true/false)方法是最佳位置。
*/
setRetainInstance(true);
mThread.start();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// activity建立後,從目标fragment中擷取進度條
progressBar = (ProgressBar) getTargetFragment().getView()
.findViewById(R.id.progress);
// Ui界面準備完畢,喚醒程序
synchronized (mThread) {
mReady = true;
mThread.notify();
}
}
@Override
public void onDestroy() {
super.onDestroy();
synchronized (mThread) {
mReady = false;
mQuited = true;
mThread.notify();
}
}
@Override
public void onDetach() {
super.onDetach();
// 當fragment與activity分離時,将進度條置空
synchronized (mThread) {
progressBar = null;
mReady = false;
mThread.notify();
}
}
public void restart() {
synchronized (mThread) {
currentPosition = ;
mThread.notify();
}
}
}
}