您的位置:首页 > 其它

Fragment 事务 回退栈

2016-04-20 22:13 459 查看
一些相关API
1、Fragment常用的三个类:
android.app.Fragment 定义
android.app.FragmentManager 用于在Activity中操作Fragment
android.app.FragmentTransaction 保证一些列Fragment操作的原子性。事务2、FragmentManager可以做的事情: 使用findFragmentById (适用于在静态fragment,不常用)或 findFragmentByTag (适用于动态加载的fragment,常用)获取activity中存在的fragment

使用 popBackStack()将fragment从后台堆栈中弹出 (模拟用户按下BACK 命令)

使用 addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener

开启一个事务 FragmentTransaction transaction = fm.benginTransatcion()

3、FragmentTransaction中常用APItransaction.add() 往Activity中添加一个Fragment

transaction.remove() 从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁

transaction.replace() 使用另一个Fragment替换当前的Fragment,实际上就是remove()+add()

transaction.hide() 隐藏当前的Fragment,仅仅是设为不可见,并不会销毁

transaction.show() 显示之前隐藏的Fragment,在使用之前要判断是否为空以及是否隐藏

detach() 会将【view】从【UI】中移除,和remove()不同,此时fragment的【状态】依然由FragmentManager维护

attach()  重建【view】视图,附加到【UI】上并显示

transatcion.commit() 提交一个事务,注意:commit方法一定要在Activity.onSaveInstance()之前调用。
4、几个API的区别
比如:我在FragmentA中的EditText填了一些数据,当切换到FragmentB时,如果希望回到A还能看到数据,则适合你的就是hide和show,当然了不要使劲在那new实例,进行下非null判断;而如果不希望保留用户操作,你可以使用remove() + add(),或者replace()。
在不考虑回退栈的情况下,remove会销毁整个Fragment实例,而detach则只是销毁其【视图】结构,【实例】并不会被销毁。那么二者怎么取舍使用呢?如果你的当前Activity一直存在,那么在不希望保留用户操作的时候,你可以优先使用detach。

Fragment回退栈-Activity
类似于Android系统为Activity维护一个任务栈,我们也可以通过Activity维护一个回退栈来保存每次Fragment事务发生的变化。如果你将Fragment任务添加到回退栈,当用户点击后退按钮时,将看到上一次的保存的Fragment。一旦Fragment完全从后退栈中弹出,用户再次点击后退键,则退出当前Activity。
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); FragmentManager fm = getFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); transaction.add(R.id.id_content, new MyFragment(fm, 1), "ONE"); //注意第一个Fragment若加入回退栈,当点击Back键后仅仅是把此Fragment干掉了,并不会退出应用。实际将会出现白板! //transaction.addToBackStack("");//如果不加这句,点击后会直接退出应用 transaction.commit(); }}
<RelativeLayout 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" > <FrameLayout android:id="@+id/id_content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#fff" > </FrameLayout></RelativeLayout>

Fragment回退栈-Fragment[/b][/b]
public class MyFragment extends Fragment implements OnClickListener {    private FragmentManager fm;    private int num;    /**     * 请设置num=1     */    public MyFragment(FragmentManager fm, int num) {        this.fm = fm;        this.num = num;    }    private Button mBtn;    private TextView tv;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment, container, false);        tv = (TextView) view.findViewById(R.id.tv);        //若onCreateView被调用了,TextView的数值也会跟着变        tv.setText(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.CHINA).format(new Date()));        mBtn = (Button) view.findViewById(R.id.btn);        mBtn.setText("Fragment--" + num);        mBtn.setOnClickListener(this);        return view;    }    @Override    public void onClick(View v) {        FragmentTransaction transaction = fm.beginTransaction();        switch (num) {        case 1:            //添加到了回退栈后Fragment的实例虽然不会被销毁,但是视图层次依然会被销毁,即会重新调用onDestoryView和onCreateView            transaction.replace(R.id.id_content, new MyFragment(fm, 2), "Fragment--" + num);            break;        case 2:            //这里我们没有使用replace,而是先隐藏了当前的Fragment,然后添加了新的Fragment实例,最后将事务添加到回退栈            transaction.hide(this);            //当从第三个Fragment返回时,第二个Fragment并没有更新            transaction.add(R.id.id_content, new MyFragment(fm, 3), "Fragment--" + num);            break;        case 3:            Toast.makeText(getActivity(), "最后一个了", Toast.LENGTH_SHORT).show();            return;//这里使用return        }        //如果不添加事务到回退栈,前一个Fragment实例会被销毁,点击后会直接退出应用        transaction.addToBackStack("");        transaction.commit();    }}
<?xml version="1.0" encoding="UTF-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <Button        android:id="@+id/btn"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:background="#ccf"        android:gravity="center"        android:text="点击进入下一个Fragment"        android:textColor="#000"        android:textSize="18sp" />    <TextView        android:id="@+id/tv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/btn"        android:layout_centerHorizontal="true"        android:ellipsize="end"        android:gravity="center"        android:singleLine="true"        android:text="内容"        android:textColor="#f00"        android:textSize="18sp" /></RelativeLayout>


来自为知笔记(Wiz)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: