Fragment与Activity通信

来源:互联网 发布:南京数据恢复公司 编辑:程序博客网 时间:2024/05/16 18:44

1.概括

a、如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法

b、如果Activity中未保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。

c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。

注:如果在Fragment中需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()。

2.Fragment与Activity通信的最佳实践

因为要考虑Fragment的重复使用,所以必须降低Fragment与Activity的耦合,而且Fragment更不应该直接操作别的Fragment,毕竟Fragment操作应该由它的管理者Activity来决定。

下面我通过两种方式的代码,分别重构,FragmentOne和FragmentTwo的点击事件,以及Activity对点击事件的响应:

首先看FragmentOne

    public class FragmentOne extends Fragment implements OnClickListener      {          private Button mBtn;          /**          * 设置按钮点击的回调          * @author zhy          *          */          public interface FOneBtnClickListener          {              void onFOneBtnClick();          }          @Override          public View onCreateView(LayoutInflater inflater, ViewGroup container,                  Bundle savedInstanceState)          {              View view = inflater.inflate(R.layout.fragment_one, container, false);              mBtn = (Button) view.findViewById(R.id.id_fragment_one_btn);              mBtn.setOnClickListener(this);              return view;          }          /**          * 交给宿主Activity处理,如果它希望处理          */          @Override          public void onClick(View v)          {              if (getActivity() instanceof FOneBtnClickListener)              {                  ((FOneBtnClickListener) getActivity()).onFOneBtnClick();              }          }      }  

可以看到现在的FragmentOne不和任何Activity耦合,任何Activity都可以使用;并且我们声明了一个接口,来回调其点击事件,想要管理其点击事件的Activity实现此接口就即可。可以看到我们在onClick中首先判断了当前绑定的Activity是否实现了该接口,如果实现了则调用。

再看FragmentTwo

    public class FragmentTwo extends Fragment implements OnClickListener      {          private Button mBtn ;          private FTwoBtnClickListener fTwoBtnClickListener ;          public interface FTwoBtnClickListener          {              void onFTwoBtnClick();          }          //设置回调接口          public void setfTwoBtnClickListener(FTwoBtnClickListener fTwoBtnClickListener)          {              this.fTwoBtnClickListener = fTwoBtnClickListener;          }          @Override          public View onCreateView(LayoutInflater inflater, ViewGroup container,                  Bundle savedInstanceState)          {              View view = inflater.inflate(R.layout.fragment_two, container, false);              mBtn = (Button) view.findViewById(R.id.id_fragment_two_btn);              mBtn.setOnClickListener(this);              return view ;           }          @Override          public void onClick(View v)          {              if(fTwoBtnClickListener != null)              {                  fTwoBtnClickListener.onFTwoBtnClick();              }          }      }  

与FragmentOne极其类似,但是我们提供了setListener这样的方法,意味着Activity不仅需要实现该接口,还必须显示调用mFTwo.setfTwoBtnClickListener(this)。

最后看Activity :

    public class MainActivity extends Activity implements FOneBtnClickListener,              FTwoBtnClickListener      {          private FragmentOne mFOne;          private FragmentTwo mFTwo;          private FragmentThree mFThree;          @Override          protected void onCreate(Bundle savedInstanceState)          {              super.onCreate(savedInstanceState);              requestWindowFeature(Window.FEATURE_NO_TITLE);              setContentView(R.layout.activity_main);              mFOne = new FragmentOne();              FragmentManager fm = getFragmentManager();              FragmentTransaction tx = fm.beginTransaction();              tx.add(R.id.id_content, mFOne, "ONE");              tx.commit();          }          /**          * FragmentOne 按钮点击时的回调          */          @Override          public void onFOneBtnClick()          {              if (mFTwo == null)              {                  mFTwo = new FragmentTwo();                  mFTwo.setfTwoBtnClickListener(this);              }              FragmentManager fm = getFragmentManager();              FragmentTransaction tx = fm.beginTransaction();              tx.replace(R.id.id_content, mFTwo, "TWO");              tx.addToBackStack(null);              tx.commit();          }          /**          * FragmentTwo 按钮点击时的回调          */          @Override          public void onFTwoBtnClick()          {              if (mFThree == null)              {                  mFThree = new FragmentThree();              }              FragmentManager fm = getFragmentManager();              FragmentTransaction tx = fm.beginTransaction();              tx.hide(mFTwo);              tx.add(R.id.id_content, mFThree, "THREE");              // tx.replace(R.id.id_content, fThree, "THREE");              tx.addToBackStack(null);              tx.commit();          }      }  

虽然Fragment和Activity可以通过getActivity与findFragmentByTag或者findFragmentById,进行任何操作,甚至在Fragment里面操作另外的Fragment,但是不提倡。
Activity担任的是Fragment间类似总线一样的角色,应当由它决定Fragment如何操作。另外虽然Fragment不能响应Intent打开,但是Activity可以,Activity可以接收Intent,然后根据参数判断显示哪个Fragment。

0 0