Broadcast广播接受者可以实现所有通信;
-----------activity与activity之间的通信---------
**********传给上一个activity*********
//右侧+按钮的点击事件 public void addClick(View v){ Intent intent=new Intent(this,NextActivity.class); // startActivity(intent); //如果下一个activity关闭时,要在当前activity获取下一个的数据,就要使用给下面的方法 startActivityForResult(intent,1);//1是requestCode,用于标识请求的来源,在下面的onActivityResult中的requestCode可以区分业务 } //当开启的activity关闭时调用,也就是下一个activity关闭时,在当前的activity调用 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //requestCode 是从下一个activity关闭的时候传过来的 if(resultCode==10) { //data就是下一个页面的意图 String name = data.getStringExtra("name"); tx.setText(name); }else if(resultCode==20){ } } }
//吧数据返回给调用者 Intent intent=new Intent(); intent.putExtra("name","lambo"); setResult(10,intent);//10是resultCode,用于标识返回结果的来源,在上一个activity中的onActivityResult中区分业务;当前activity关闭时,会传给上一个activity //关闭当前activity,才会执行上一个activity中的方法onActivityResult(int requestCode, int resultCode, Intent data) finish();
*********传给下一个activity******
方法一:通过Intent传值给ACOne:
Intent inten = new Intent(getContext(), ACOne.class); inten.putExtra("f", "diyige"); startActivity(inten);/*跳转到下一个页面*/
方法二:用Bundle携带参数:
public void OpenNew(View v){ //新建一个显式意图,第一个参数为当前Activity类对象,第二个参数为你要打开的Activity类 Intent intent =new Intent(MainActivity.this,MainActivity2.class); //用Bundle携带数据 Bundle bundle=new Bundle(); //传递name参数为tinyphp bundle.putString("name", "tinyphp"); intent.putExtras(bundle); startActivity(intent); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.newtest); //新页面接收数据 Bundle bundle = this.getIntent().getExtras(); //接收name值 String name = bundle.getString("name"); Log.i("获取到的name值为",name); }
------------fragment与fragment之间的通信---------
public class Fragment1 extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.fragment1,null); // 给fragment上的按钮添加点击事件 v.findViewById(R.id.btn_change).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //拿到frgment---fragment之间的通信 Fragment2 f2= (Fragment2) getActivity().getFragmentManager().findFragmentByTag("two");//two是fragment2的tag, 切换fragmentbeginTracsaction.replace(R.id.lltwo,new Fragment2(),"two");中two是tag f2.changeStr("我要改变世界"); } }); return v; } }
_________________fragment与activity之间的通信__-----------
------activity传值给fragment-------
方法一:在activity中建一个bundle,把要传的值存入bundle,然后通过fragment的setArguments(bundle)传到fragment,在fragment中,用getArguments接收, activity中: FragmentTransaction ft=fm.beginTransaction(); OneFragment oneFragment=new OneFragment(); ft.replace(R.id.frame,oneFragment,"f1"); Bundle bundle=new Bundle(); bundle.putString("one","要传的值"); oneFragment.setArguments(bundle); ft.commit(); OneFragment中: Bundle bundle=getArguments(); String s=bundle.getString("one");
方法二:
可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach(Activity)
当Fragment与Activity发生关联时调用。
onCreateView(LayoutInflater, ViewGroup,Bundle)
创建该Fragment的视图
onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用
onDestoryView()
与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()
与onAttach相对应,当Fragment与Activity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,
在fragmentOne中:
public class FragmentOne extends Fragment { private Button btn; private TextView text; private String str; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.fragmentone,null); // 给fragment上的按钮添加点击事件 text = v.findViewById(R.id.tv_fragmentone); btn = v.findViewById(R.id.getImgae); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); text.setText(str); // return inflater.inflate(R.layout.fragmentone,container,false); return v; } @Override public void onAttach(Context context) { super.onAttach(context); str = ((MainActivity)context).toFragmentone(); Log.e("ss",str); } }
在MainActivity中:
//给FragmentOne传值 public String toFragmentone(){ return "fragmentone"; }
-----fragment传值给activity----
2.在fragment中定义属性private MyListener myListener
3.重写fragment中的onAttach()方法:listener = (MyLisener)getActivity();
4.fragment触发事件时回传值
5.Activity中实现回调接口 重写回调方法获取回传的值并显示
在fragment中:
import android.content.Context;
public class FragmentOne extends Fragment { private Button btn; private TextView text; private String str; // private MainActivity ac; private MyListener ac; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v=inflater.inflate(R.layout.fragmentone,null); // 给fragment上的按钮添加点击事件 text = v.findViewById(R.id.tv_fragmentone); btn = v.findViewById(R.id.getImgae); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //通过调用在activity中实现的接口方法,吧数据传给Mainactivity ac.sendContent("dddd"); } }); // return inflater.inflate(R.layout.fragmentone,container,false); return v; } //activity和fragment联系时候调用,fragment必须依赖activty @Override public void onAttach(Context context) { super.onAttach(context); //获取实现接口的activity ac = (MyListener) getActivity();//或者ac=(MainActivity) context; } //①定义回调接口 public interface MyListener{ public void sendContent(String info); } }在MainActivity中:
import com.example.wofu.aichi010.Fragment.FragmentOne.MyListener;//fragmentOne中的接口 public class MainActivity extends BaseActivity implements RadioGroup.OnCheckedChangeListener,MyListener{
//fragmentOne中的接口,在这实现,以实现fragmentOne传值Mainactivity public void sendContent(String info) { if (info!=null && !"".equals(info)) { Log.e("sss",info); }else { } } }
**********EventBus实现fragment向Activity传值**********
参考:https://www.jianshu.com/p/acfe78296bb5
https://blog.csdn.net/bskfnvjtlyzmv867/article/details/71480647
*****添加依赖 implimentation 'org.greenrobot:eventbus:3.0.0' ******EventBus的三要素 Event:事件,可以是任意类型的对象。 Subscriber:事件订阅者,在EventBus3.0之前消息处理的方法只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,他们分别代表四种线程模型。而在EventBus3.0之后,事件处理的方法可以随便取名,但是需要添加一个注解@Subscribe,并且要指定线程模型(默认为POSTING)。 Publisher:事件发布者,可以在任意线程任意位置发送事件,直接调用EventBus的post(Object)方法。可以自己实例化EventBus对象,但一般使用EventBus.getDefault()就好了,根据post函数参数的类型,会自动调用订阅相应类型事件的函数。 ******** EventBus的四种线程模型(ThreadMode) POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起应用程序无响应(ANR)。 MAIN:事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。 BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。 ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。
****举例*****
普通事件:
//注册成为订阅者 EventBus.getDefault().register(this);
//订阅方法,当接收到事件的时候,会调用该方法 @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent(MessageEvent messageEvent){ textView.setText(messageEvent.getMessage()); } @Override protected void onDestroy() { super.onDestroy(); //解除注册 EventBus.getDefault().unregister(this); }
在另一个activity或者fragment中post事件:
EventBus.getDefault().post(new MessageEvent("发送的消息"));
@Subscribe注解,该注解标识了当前方法为订阅方法;该注解内部有三个成员,分别是threadMode、sticky、priority。threadMode代表订阅方法所运行的线程,sticky代表是否是粘性事件,priority代表优先级。给这个三个成员赋不同的值,能使得订阅方法有着不同的效果。
*******ThreadMode是一个枚举类型,有着以下几个类型:
POSTING:表示订阅方法运行在发送事件的线程。
MAIN:表示订阅方法运行在UI线程,由于UI线程不能阻塞,因此当使用MAIN的时候,订阅方法不应该耗时过长。
BACKGROUND:表示订阅方法运行在后台线程,如果发送的事件线程不是UI线程,那么就使用该线程;如果发送事件的线程是UI线程,那么新建一个后台线程来调用订阅方法。
ASYNC:订阅方法与发送事件始终不在同一个线程,即订阅方法始终会使用新的线程来运行。
ThreadMode默认是使用POSTING的,如果需要更改设置,可以在添加注解的时候同时为threadMode赋值。 *****.priority 优先级 设置该优先级的目的是,当一个事件有多个订阅者的时候,优先级高的会优先接收到事件。
粘性事件:
注册粘性事件 EventBus.getDefault().register(this); 发送粘性事件: EventBus.getDefault().postSticky(new MessageEvent("发送粘性事件")); 接受粘性事件: @Subscribe(sticky = true) public void onEvent(MessageEvent messageEvent){ Log.d("cylog","接受到了来自EventBus的事件:"+messageEvent.getMessage()); } 取消注册 @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); }