多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
转载请标明原地址:[http://blog.csdn.net/gaolei1201/article/details/44037831 ](http://blog.csdn.net/gaolei1201/article/details/44037831) 在工作中我们经常会遇到Activity和Fragment交互。具体为什么要用Fragment,相信大家都懂的,这样可以减少Activity之间来回切换,还可以把不同模块独立化,降低耦合度。下面根据自己工作经验,详细总结一下Activity和Fragment的几种交互方式。 ## 一、使用Bundle 这种方法只能用来传递数据,且只能是Activity向Fragmeng传递。 首先我们需要在Activity中动态添加Fragment时,用Bundle封装我们需要传递的数据 ~~~ HomeFragment arg = new HomeFragment(); Bundle bundle = new Bundle(); bundle.putString("arg", edit.getText().toString()); arg.setArguments(bundle); FragmentManager fm = getFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.layout_fragment, arg); ft.commit(); 然后在Fragment的回调函数中通过Fragment提供的方法getArguments()取出Bundle对象。 text = (TextView) view.findViewById(R.id.text); Bundle bundle = getArguments(); text.setText(bundle.getString("arg")); ~~~ 这种方法比较简单就不多说了 ## 二、getActivity()、new Fragment()方式( 这种方法比较经典,简单实用) 下面是Activity代码: ~~~ public class MainActivity extends FragmentActivity { private TextView show_change_text; private Button change_fragment_bt; private HomeFragment homeFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); homeFragment=new HomeFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_content,homeFragment ).commit(); change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt); show_change_text = (TextView) findViewById(R.id.show_change_text); change_fragment_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub homeFragment.changeText(); } }); } public void changeText(){ show_change_text.setText("I am UI of activity,and I have changed"); } public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); } } ~~~ 下面是Fragment代码: ~~~ public class HomeFragment extends Fragment { private TextView show_change_text; private Button change_activity_bt; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.home_fragment, null); change_activity_bt = (Button) view .findViewById(R.id.change_activity_bt); show_change_text = (TextView) view.findViewById(R.id.show_change_text); change_activity_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub ((MainActivity) getActivity()).changeText(); } }); return view; } public void changeText(){ show_change_text.setText("I am UI of fragment,and I have changed"); } public void onAttach(Activity activity) { super.onAttach(activity); } } ~~~ [  getActivity()、new Fragment()方式源码下载地址.........................](http://download.csdn.net/detail/gaolei1201/8994197) ## 三、Handler方式 传递数据是比较容易实现,但是要用到Activity和Fragment之间互相改变彼此的UI,网上关于这个问题的解决方法还是很少的,我也没遇到合适的解决方案,自己在前人的基础上研究后创造了一种方法。使Activity和Fragment共享一个Handler,然后发送消息通知彼此更新。别的也不多说了,例子代码如下, 这是Activity的代码: ~~~ <span style="font-size:14px;color:#333333;">public class MainActivity extends FragmentActivity implements OnClickListener { private Handler mHandler; private long lastPressBack; private boolean isFirstPressBack = true; private Button change_fragment_bt; private TextView show_change_text; private HomeFragment homeFragment; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: show_change_text.setText("I am UI of activity,and I have changed"); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); change_fragment_bt=(Button)findViewById(R.id.change_fragment_bt); show_change_text=(TextView)findViewById(R.id.show_change_text); change_fragment_bt.setOnClickListener(this); getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_content, new HomeFragment()) .commit(); } public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); homeFragment=(HomeFragment) fragment; homeFragment.setHandler(handler) ; } public boolean onKeyDown(int keyCode, KeyEvent event) { super.onKeyDown(keyCode, event); //点击和Fragment交互,改变Fragment的UI if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { if(HomeFragment.changeText){ Message msg = mHandler.obtainMessage(); msg.what =0; mHandler.sendMessage(msg); HomeFragment.changeText=false; return false; } if (!isFirstPressBack) { if (System.currentTimeMillis() - lastPressBack > 2 * 1000) { lastPressBack = System.currentTimeMillis(); } else { finish(); } } lastPressBack = System.currentTimeMillis(); Toast.makeText(this,getString(R.string.exit_app),Toast.LENGTH_SHORT).show(); isFirstPressBack = false; return false; } return false; } public void setHandler(Handler handler) { mHandler = handler; } @Override public void onClick(View arg0) { // TODO Auto-generated method stub //点击和Fragment交互,改变Fragment的UI Message msg = mHandler.obtainMessage(); msg.what =0; mHandler.sendMessage(msg); HomeFragment.changeText=false; } } </span> ~~~ 这是Fragment的代码: ~~~ public class HomeFragment extends Fragment implements OnClickListener{ private TextView show_change_text; private Button change_activity_bt; private MainActivity mActivity; public static boolean changeText=true; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: show_change_text.setText("I am UI of fragment,and I have changed"); break; } } }; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.home_fragment, null); show_change_text=(TextView)view.findViewById(R.id.show_change_text); change_activity_bt=(Button)view.findViewById(R.id.change_activity_bt); change_activity_bt.setOnClickListener(this); return view; } public void onAttach(Activity activity) { super.onAttach(activity); mActivity = (MainActivity) activity; mActivity.setHandler(handler); } public void setHandler(Handler handler) { this.handler = handler; } public void onDestroy(){ super.onDestroy(); changeText=true; } @Override public void onClick(View arg0) { // TODO Auto-generated method stub //点击和Activity交互,改变ActivityUI Message msg = handler.obtainMessage(); msg.what =0; handler.sendMessage(msg); } } ~~~  [Handler方式源码下载地址....................](http://download.csdn.net/detail/gaolei1201/8929807) ## 四、接口回调方式 接口真是个好东西,条件是两个类,一个接口,两个类之间交互。任何两个类之间交互都可以用接口回调,针对接口编程能降低两个类之间的耦合度。 下面是Activity的代码: ~~~ <span style="font-size:14px;color:#333333;">public class MainActivity extends FragmentActivity implements OnActivityChangeListener{ private TextView show_change_text; private Button change_fragment_bt; public static OnFragmentChangeListener onFragmentChangeListener; public static void setOnFragmentChangeListener( OnFragmentChangeListener onFragmentChangeListener) { MainActivity.onFragmentChangeListener = onFragmentChangeListener; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_content, new HomeFragment()).commit(); change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt); show_change_text = (TextView) findViewById(R.id.show_change_text); // new HomeFragment().setOnActivityChangeListener(this); // 这样set是不行的,因为这样又重新创造了一个HomeFragment,和原来初始化的那个不是一个,回报空指针,因为HomeFragment的listener没有被set //所以应该这样 HomeFragment.setOnActivityChangeListener(this); change_fragment_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub //在这里执行接口方法 onFragmentChangeListener.onFragmentChange(); } }); } public void onAttachFragment(Fragment fragment) { super.onAttachFragment(fragment); // 除了这种方式传递子类对象,还可以在Fragment中 // setOnFragmentChangeListener,可以去那里面看一下,我已经注释过 onFragmentChangeListener = (OnFragmentChangeListener) fragment; } @Override public void onActivityChange() { // TODO Auto-generated method stub // 在子类中实现接口的方法 show_change_text.setText("I am UI of activity,and I have changed"); } }</span> ~~~ 显示Fragment的代码: ~~~ <span style="font-size:14px;color:#333333;">public class HomeFragment extends Fragment implements OnFragmentChangeListener { private TextView show_change_text; private Button change_activity_bt; public static OnActivityChangeListener onActivityChangeListener; public void setOnActivityChangeListener(OnActivityChangeListener onActivityChangeListener){ HomeFragment.onActivityChangeListener=onActivityChangeListener; } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.home_fragment, null); change_activity_bt = (Button) view .findViewById(R.id.change_activity_bt); show_change_text = (TextView) view.findViewById(R.id.show_change_text); // new MainActivity().setOnFragmentChangeListener(this); // 这样set是不行的,因为这样又重新创造了一个MainActivity,和原来初始化的那个不是一个,回报空指针,因为activity的listener没有被set //所以应该这样 MainActivity.setOnFragmentChangeListener(this); change_activity_bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub //在这里执行接口方法 onActivityChangeListener.onActivityChange(); } }); return view; } public void onAttach(Activity activity) { super.onAttach(activity); // 除了这种方式传递子类对象,还可以在Activity中 // setOnActivityChangeListener,可以去那里面看一下,我已经注释过 onActivityChangeListener=(OnActivityChangeListener) activity; } @Override public void onFragmentChange() { // 在子类中实现接口的方法 show_change_text.setText("I am UI of fragment,and I have changed"); } } </span> ~~~ [ Interface方式代码下载地址.....................](http://download.csdn.net/detail/gaolei1201/8929815)