为了能重复使用碎片UI组件,你需要创建一个完全独立,模块化的组件,这个组件可以定义自己的样式和行为。一旦你定义了一个可重用的碎片,你可以使用一个activity关联它们,通过程序逻辑链接它们成为一个完整的组合UI。
为了实现碎片和activity的通信,你可以在碎片类中定义一个接口,然后在activity中实现这个接口。碎片可以在onAttach()生命周期函数中取得接口的实现,然后调用接口方法实现通信。
为了从碎片中接收事件回调,拥有这个碎片的activity必须实现定义在碎片类中的接口。
通过findFragmentById()取得Fragment实例,然后activity就可以直接调用碎片的公共函数发送信息给这个fragment。
通常你希望碎片间可以通信,比如基于用户事件改变内容。所有碎片间的通信都是通过activity实现,两个碎片不能直接通信。
定义一个接口
为了实现碎片和activity的通信,你可以在碎片类中定义一个接口,然后在activity中实现这个接口。碎片可以在onAttach()生命周期函数中取得接口的实现,然后调用接口方法实现通信。
这里是一个碎片和activity通信的例子:
public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; // Activity容器必须实现这个接口 public interface OnHeadlineSelectedListener { public void onArticleSelected(int position); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // 确保activity实现了接口回调,不然抛出一个异常 try { mCallback = (OnHeadlineSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener"); } } ... }
现在碎片可以使用OnHeadloneSelectedListener接口的mCallback实例调用onArticleSelected()函数(或者接口中其他函数)发送信息给activity了。
例如,当用户点击list选项时,碎片中的下面这个方法会被调用。碎片使用回调接口发送事件给父类activity。
@Override public void onListItemClick(ListView l, View v, int position, long id) { // Send the event to the host activity mCallback.onArticleSelected(position); }
实现接口
为了从碎片中接收事件回调,拥有这个碎片的activity必须实现定义在碎片类中的接口。
例如,下面的代码实现了上面例子中定义的接口:
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(Uri articleUri) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article } }
发送一个信息给碎片
通过findFragmentById()取得Fragment实例,然后activity就可以直接调用碎片的公共函数发送信息给这个fragment。
例如,上面的函数让activity显示了一个碎片选项的数据,activity也可以通过信息接收函数去显示其他碎片数据:
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // 用户从文章标题碎片选择标题 // 这里可以写一些显示文章的代码 ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) { // 如果是文章显示页面碎片 // 呼叫一个更新内容的方法 articleFrag.updateArticleView(position); } else { // 否则我们在第一个布局页面 // 创建一个碎片,给选择项传递一个参数 ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // 替换碎片的内容, // 添加改变到回退堆栈,以便用户返回 transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // 提交更改 transaction.commit(); } } }