Activity和Fragment相互通信或者改变UI
来源:互联网 发布:linux proc 编辑:程序博客网 时间:2024/06/03 13:36
转载请标明原地址:http://blog.csdn.net/gaolei1201/article/details/44037831
在工作中我们经常会遇到Activity和Fragment交互。具体为什么要用Fragment,相信大家都懂的,可以使UI更灵活,还可以把不同模块独立化,降低耦合度。Activity和Fragment之间传值还是比较常见,但是要互相改变彼此UI还是有一定技巧的。下面根据自己工作经验,详细总结一下Activity和Fragment的几种交互方式。
一、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()方式源码下载地址.........................
二、Handler方式
传递数据是比较容易实现,但是要用到Activity和Fragment之间互相改变彼此的UI,网上关于这个问题的解决方法还是很少的,我也没遇到合适的解决方案,自己在前人的基础上研究后创造了一种方法。使Activity和Fragment共享一个Handler,然后发送消息通知彼此更新。别的也不多说了,例子代码如下,
这是Activity的代码:
- 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;
- }
- }
这是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方式源码下载地址....................
三、接口回调方式(这个尽量不要用,因为会创建static对象,而static对象不会被回收,很占内存)
接口真是个好东西,条件是两个类,一个接口,两个类之间交互。任何两个类之间交互都可以用接口回调,针对接口编程能降低两个类之间的耦合度。
下面是Activity的代码:
- 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");
- }
- }
显示Fragment的代码:
- 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");
- }
- }
Interface方式代码下载地址.....................
四、使用startActivityForResult(Fragment和Activity、两个Activity之间交互都行)
下面是Fragment的代码
- public class HomeFragment extends Fragment {
- private TextView fragment_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);
- fragment_text = (TextView) view.findViewById(R.id.fragment_text);
- change_activity_bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // TODO Auto-generated method stub
- Intent intent = new Intent(getActivity(), SecondActivity.class);
- startActivityForResult(intent, 0);
- }
- });
- return view;
- }
- public void onActivityResult(int requestCode, int resultCode, Intent intent) {
- if (intent == null)
- return;
- String change01 = intent.getStringExtra("change01");
- // 根据上面发送过去的请求吗来区别
- switch (requestCode) {
- case 0:
- fragment_text.setText(change01);
- break;
- default:
- break;
- }
- }
- }
下面是SecondActivity代码
- public class SecondActivity extends FragmentActivity {
- private Button change_fragment_bt;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.second_activity);
- change_fragment_bt = (Button) findViewById(R.id.change_fragment_bt);
- change_fragment_bt.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // TODO Auto-generated method stub
- Intent mIntent = new Intent();
- mIntent.putExtra("change01", "Change HomeFragment By SecondActivity");
- mIntent.putExtra("change02", "Change MainActivity By SecondActivity");
- // 设置结果,并进行传送
- setResult(0, mIntent);
- finish();
- }
- });
- }
- }
stratActivityForResult方式源码,点击下载......
五、万能的BroadCastReceiver(Fragment和Activity、两个Activity之间交互都行)
虽然广播比较万能,但是它是由系统决定,且有优先级,可能会造成延迟。
下面是MainActivity 代码:
- public class MainActivity extends Activity {
- TextView textView;
- Button sButton;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- textView = (TextView) findViewById(R.id.show);
- sButton = (Button) findViewById(R.id.startAnother);
- sButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- startActivity(new Intent(MainActivity.this,AnotherActivity.class));
- }
- });
- IntentFilter filter = new IntentFilter(AnotherActivity.action);
- registerReceiver(broadcastReceiver, filter);
- }
- BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // TODO Auto-generated method stub
- textView.setText(intent.getExtras().getString("data"));
- }
- };
- protected void onDestroy() {
- unregisterReceiver(broadcastReceiver);
- };
- }
- public class AnotherActivity extends Activity {
- public static final String action = "jason.broadcast.action";
- Button update;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.another);
- update = (Button) findViewById(R.id.updateMain);
- update.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Intent intent = new Intent(action);
- intent.putExtra("data", "yes i am data");
- sendBroadcast(intent);
- finish();
- }
- });
- }
- }
- Activity和Fragment相互通信或者改变UI
- Fragment和Activity之间的相互通信
- Fragment和Activity之间的相互通信
- android中fragment和activity之间相互通信
- android中fragment和activity之间相互通信
- android中fragment和activity之间相互通信
- android中fragment和activity之间相互通信
- Activity和Fragment的五种交互方式(Activity可以改变Fragment的UI,Fragment也可以改变ActivityUI)
- fragment和activity通信
- Activity和Fragment通信
- Fragment与Activity相互通信研究总结
- Fragment与Activity的相互通信(一)
- Fragment与Activity的相互通信(二)
- Activity 与 Fragment 之间相互通信
- Fragment与Activity之间的相互通信
- Fragment与Activity之间的相互通信
- Adapter 更新UI Activity 或者fragment
- Activity和Service相互通信
- SQL基本使用语句整理
- 实现搜索需求各个阶段
- [DP]486. Predict the Winner
- Navicat premium将oracle数据表迁移至mysql
- ES6
- Activity和Fragment相互通信或者改变UI
- haproxy监控页面添加及参数简介
- linux centos 7开启特定端口防火墙
- caffe源码——Euclidean Loss是怎么实现的
- 软件设计师考试笔记:UML统一建模语言
- Java生成二维码(zxing方式)
- ES6 -- Proxy搭档:Reflect
- Spark学习—RDD编程
- Redis 更新缓存问题解决