Android学习笔记11——用户界面之Fragments(3)

来源:互联网 发布:全息瞄准镜 知乎 编辑:程序博客网 时间:2024/05/29 11:34

如何管理我们的Fagment呢?

为了管理我们Activity中的Fragments,我们需要用到FragmentManager。我们可以在我们的Activity中调用getFragmentManager()方法来得到这个FragmentManager这个对象。

我们可以使用FragmentManager做一下几件事情:

1、我们可以用findFragmentById或者findFragmentByTag方法获取到Activity中的fragments;

2、可以用popBackStack方法来模拟用户的回退按钮操作,从回退栈中中弹出fragments;

3、用addOnBackStackChangedListener()方法为回退栈的改变注册一个监听器。

如何进行Fragment的事务处理呢?

在我们的Activity中使用fragment的一个优点是我们可以用他们动态的添加、移除、替换和表现一些其他的动作来相应用户的交互。我们的每一把这样的改变提交给Activity成为一个事务。我们也可以把每一个fragment保存到activity所管理的回退栈中,这样就会使得用户回退这些fragment的改变。

ragmentManager fragmentManager = getFragmentManager();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
每一次事务是同时进行的你想进行的一系列的改变。我们可以设置我们想要进行的所有改变操作用一个被给予的Transaction对象,然后如果我们想要把这些改变应用到activity中,我们必须调用commit()方法。

然而,可能在我们调用commit方法之前,为了把这次事务添加到fragment的回退栈中,我们可能想要调用addToBackStack方法。这个回退栈被这个fragment所在的Activity管理,允许用户可以通过回退按钮返回到上一个fragment状态。

// Create new fragment and transactionFragment newFragment = new ExampleFragment();FragmentTransaction transaction = getFragmentManager().beginTransaction();// Replace whatever is in the fragment_container view with this fragment,// and add the transaction to the back stacktransaction.replace(R.id.fragment_container, newFragment);transaction.addToBackStack(null);// Commit the transactiontransaction.commit();
如果我们一次提交事务多个改变,并且调用了addToBackStack方法把所有的改变当作一次事务保存到回退栈中,那么我们点击回退按钮时将会一次性恢复多个改变。

我们添加这些改变到FragmentTransaction的顺序是无关紧要的,除了两种情况:第一种是我们必须最后调用commit方法;第二种是如果我们添加多个fragments到相同的容器中,我们添加的fragment的顺序决定了他们在视图成次显示的顺序。

当时如果我们在进行移除fragment事务的时候没有调用addToBackStack方法,这个fragment在我们提交的时候会被销毁掉,并且用户也不能返回到这个fragment。

注意:我们可以在每一次事务提交commit方法之前调用setTransition方法来设置一个事务动画。

调用commit方法并不能立即执行这些事务。相反,这些事务是在Activity的UI线程中执行的,当这个UI线程能够执行这些事务的时候。然而,如果有需要,我们可以调用executePendingTransaction方法使得我们的Activity的UI线程能够立即执行这些提交的事务。但是尽量不要这样做,除非这个事务是独立于其他线程中的工作的,这可能中断其他工作。

Fragment与Activity之间是如何通信的呢?

尽管Fragment被作为独立于Activity的一个对象来实现,能够被应用在多个Activity中,并且一个被给予的fragment实例能够直接绑定到包含它的Activity中。

在特殊的时候,我们可以在fragment中调用getActivity方法访问到Activity实例,很容易进行一些操作,例如获得到activity布局中的一个视图组件。

View listView = getActivity().findViewById(R.id.list);
同样的,我们的Activity中也可以通过FragmentManager中的Fragment的引用调用fragment中的方法。例如

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
创建activity的事件回调函数

在某些情况下,我们可能需要一个fragment和

例如,如果在一个Activity中有两个fragement,一个展示文章列表A,一个展示文章详情B。当用户选中文章中的一项时fragment A必须告诉这个Activity,然后这个Activity在通知fragment B 去在展示文章。

public static class FragmentA extends ListFragment {    ...    // Container Activity must implement this interface    public interface OnArticleSelectedListener {        public void onArticleSelected(Uri articleUri);    }    ...}
然后操作这个Fragment的Activity实现OnArticleSelectedListener接口并且重载onArticleSelected方法通知fragmentB 在fragmentA中发生的事件。为了确保这个主Activity实现这个接口,在Fragment A中的onAttach方法中的activity参数转为OnArticleSelected来实例化一个OnArticleSelected实例。

public static class FragmentA extends ListFragment {    OnArticleSelectedListener mListener;    ...    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        try {            mListener = (OnArticleSelectedListener) activity;        } catch (ClassCastException e) {            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");        }    }    ...}
但是如果这个主Activity没有实现这个接口,在上面这个方法中就会抛出一个ClassCastException。如果成功的话,mListener就会拥有OnArticleSelectedListener接口在Activity实现的引用。

public static class FragmentA extends ListFragment {    OnArticleSelectedListener mListener;    ...    @Override    public void onListItemClick(ListView l, View v, int position, long id) {        // Append the clicked item's row ID with the content provider Uri        Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);        // Send the event and Uri to the host activity        mListener.onArticleSelected(noteUri);    }    ...}

0 0
原创粉丝点击