这个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, 0);
fm.beginTransaction().add(mWorkFragment, "work").commit();
}
}
}
public class RetainFragment extends Fragment {
private ProgressBar progressBar;
// 进度条当前的进度值
private int currentPosition;
// 进度条的最大值
private int max = 100;
// 判断进度条是否准备好(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(50);
} 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 = 0;
mThread.notify();
}
}
}
}