【潘大吼】の技术博客

在使用fragment的时候,通常的用法都是使用一个activity来管理不同的fragment,所以每个fragment与activity的及时通讯就很重要。

1、Fragment可以调用getActivity()方法很容易的得到它所在的activity的对象,然后就可以查找activity中的控件们(findViewById())。例如:

Viewlist View =getActivity().findViewById(R.id.list);同样的,activity也可以通过FragmentManager的方法查找它所包含的frament们。例如:ExampleFragment fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment)

但是这个并不是最好的办法,根据fragmen的定义,我们可以在fragment里面定义一个回调接口,在activity中实现它。举个谷歌官方给的例子,这是一个新闻程序的例子,它有一个activity,activity中含有两个fragment。fragmentA显示新闻标题,fragmentB显示标题对应的内容。fragmentA必须在用户选择了某个标题时告诉activity,然后activity再告诉fragmentB,fragmentB就显示出对应的内容(为什么这么麻烦?直接fragmentA告诉fragmentB不就行了?也可以啊,但是你的fragment就减少了可重用的能力。现在我只需把我的事件告诉宿主,由宿主决定如何处置,这样是不是重用性更好呢?)。如下例:

public class PersionListFragment extends ListFragment {private static final String STATE_ACTIVATED_POSITION = "activated_position";private Callbacks mCallbacks = sDummyCallbacks;private int mActivatedPosition = ListView.INVALID_POSITION;public interface Callbacks {public void onItemSelected(String id);}private static Callbacks sDummyCallbacks = new Callbacks() {@Overridepublic void onItemSelected(String id) {}};我们在PersionListFragment中定义了mCallbacks这个接口,当然了我们自己实现了一个空的接口内容sDummyCallbacks,当作mCallbacks的默认接口。下面就是我们要到Activity中去实现这个接口:public class PersionListActivity extends FragmentActivity implements PersionListFragment.Callbacks {private boolean mTwoPane;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_persion_twopane);if (findViewById(R.id.persion_detail_container) != null) {mTwoPane = true;((PersionListFragment) getSupportFragmentManager().findFragmentById(R.id.persion_list)).setActivateOnItemClick(false);}}@Overridepublic void onItemSelected(String id) {if (mTwoPane) {Bundle arguments = new Bundle();arguments.putString(PersionDetailFragment.ARG_ITEM_ID, id);PersionDetailFragment fragment = new PersionDetailFragment();fragment.setArguments(arguments);getSupportFragmentManager().beginTransaction().replace(R.id.persion_detail_container, fragment).commit();} else {Intent detailIntent = new Intent(this, PersionDetailActivity.class);detailIntent.putExtra(PersionDetailFragment.ARG_ITEM_ID, id);startActivity(detailIntent);}}}那么实现完了接口怎么传给刚才的fragment呢?当fragment添加到activity中时,会调用fragment的方法onAttach(),这个方法中适合检查activity是否实现了OnArticleSelectedListener接口,检查方法就是对传入的activity的实例进行类型转换,,然后赋值给我们在fragment中定义的接口。 @Overridepublic void onAttach(Activity activity) {super.onAttach(activity);if (!(activity instanceof Callbacks)) {throw new IllegalStateException("Activity must implement fragment’s callbacks.");}mCallbacks = (Callbacks) activity;}@Overridepublic void onDetach() {super.onDetach();mCallbacks = sDummyCallbacks;}@Overridepublic void onListItemClick(ListView listView, View view, int position, long id) {super.onListItemClick(listView, view, position, id);mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);}在一个fragment从activity中剥离的时候,就会调用onDetach方法,这个时候正好可以把它的接口恢复为默认接口。防止不必要的错误。注意看onAttach方法中的代码,在赋值之前要做一个判断,看看Activity中有没有实现了这个接口,用到了instanceof。如果没有实现接口,我们就抛出异常。这个时候我们就实现了Fragment与Activity之间的通讯,把主要的事情还是都交给管理员Activity做比较好。代码下载在评论上

离开之后,我想你不要忘记一件事:不要忘记想念我。

【潘大吼】の技术博客

相关文章:

你感兴趣的文章:

标签云: