码迷,mamicode.com
首页 > 其他好文 > 详细

Fragment 事务 回退栈

时间:2016-04-20 23:40:36      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:


一些相关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中常用API
  • transaction.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_contentnew 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
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_contentnew MyFragment(fm, 2), "Fragment--" + num);
            break;
        case 2:
            //这里我们没有使用replace,而是先隐藏了当前的Fragment,然后添加了新的Fragment实例,最后将事务添加到回退栈
            transaction.hide(this);
            //当从第三个Fragment返回时,第二个Fragment并没有更新
            transaction.add(R.id.id_contentnew 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>





Fragment 事务 回退栈

标签:

原文地址:http://www.cnblogs.com/baiqiantao/p/5414708.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!