***Broadcast广播接受者可以实现所有通信;
-----------activity与activity之间的通信---------
当下一个activity关闭时传值给上一个activity,主要用得到startActivityForResult和onActivityResult方法。
oneActivity //按钮的点击事件
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){
}
}
}
nextActivity
//吧数据返回给调用者
Intent intent=new Intent();
intent.putExtra("name","lambo");
setResult(10,intent);//<span style="color:#ff0000;">10是resultCode,用于标识返回结果的来源,在上一个activity中的onActivityResult中区分业务;当前activity关闭时,会传给上一个activity</span>
//关闭当前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----
******通过在fragment中实现接口的方式,Fragment向Activity传值的步骤 接口回调传递(5部曲)
1.fragment中准备回调接口 接口中声明传值的回调方法
-
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事件:
与观察者模式对应的,当有事件发生,需要通知观察者的时候,被观察者会调用notifyObservers()方法来通知所有已经注册的观察者,在EventBus中,对观察者模式底层进行了封装,我们只需要调用以下代码就能把事件发送出去:
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);
}