参考博客:
1、通过构造器
2、通过广播
3、通过EventBus
4、通过接口回调
5、通过ViewModel
6、通过Handler
Activity与Fragment之间通信的多种方式_东东旭huster的博客-CSDN博客_activity与fragment如何通信
一.通过Bundle通信的方式实现:
实现功能:Activity向Fragment传递数据
1.在Activity中利用Bundle将数据放进Fragment之中
package com.example.myapplication.Activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.myapplication.R;
import com.example.myapplication.fragment.FirstFragment;
public class MainActivity extends AppCompatActivity {
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//动态加载Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FirstFragment firstFragment = new FirstFragment();
//添加数据到Bundle中
Bundle bundle = new Bundle();
bundle.putString("messenger","Activity向Fragment传递的数据");
firstFragment.setArguments(bundle);
//提交修改
fragmentTransaction.add(R.id.linearlayout, firstFragment);
fragmentTransaction.commit();
}
});
}
}
2.Activity对应的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Activity.MainActivity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="通信方向:Activity到Fragment"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.Fragment中接收Bundle中的数据,并且设置到TextView中
package com.example.myapplication.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import com.example.myapplication.R;
public class FirstFragment extends Fragment {
private View mRootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_first, container, false);
TextView mTextView = mRootView.findViewById(R.id.textview);
//获取数据
Bundle arguments = getArguments();
String messenger = arguments.getString("messenger");
//将数据设置到TextView中去
mTextView.setText(messenger);
return mRootView;
}
}
4.Fragment对应的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一个Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
5.最终实现的功能:点击Activity中的按钮,可以向Fragment中添加Bundle数据,并且动态添加Fragment,最后在Fragment中可以将获取的数据显示在Fragment中的TextView中。
二.通过接口回调的方式实现:
实现功能:Fragment向Activity传递数据
1.首先定义一个回调接口
package com.example.myapplication.CallBack;
public interface FirstCallBack {
void onFirstCallBack(String text);
}
2.在Activity中实现接口,并且在回调方法中实现自己想要的功能(利用回调传入的String设置TextView的值)
package com.example.myapplication.Activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.TextView;
import com.example.myapplication.CallBack.FirstCallBack;
import com.example.myapplication.R;
import com.example.myapplication.fragment.FirstFragment;
public class MainActivity extends AppCompatActivity implements FirstCallBack {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态加载Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FirstFragment firstFragment = new FirstFragment();
fragmentTransaction.add(R.id.fragment1, firstFragment);
fragmentTransaction.commit();
mTextView = findViewById(R.id.textview);
}
//实现接口里面的方法
@Override
public void onFirstCallBack(String text) {
mTextView.setText(text);
}
}
3.Activity对应的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Activity.MainActivity">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是主界面的初始值"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
4.在Fragment中调用回调方法(调用activity中实现的回调方法)
package com.example.myapplication.fragment;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.myapplication.CallBack.FirstCallBack;
import com.example.myapplication.R;
public class FirstFragment extends Fragment {
private View mRootView;
private FirstCallBack mFirstCallBack;
//两个onAttach都要重写,防止别人调用不同的onAttach方法
@Override
public void onAttach(@NonNull Activity activity) {
super.onAttach(activity);
if (!(activity instanceof FirstCallBack)) {
throw new IllegalStateException("FirstFragment对应的Activity没有实现FirstCallBack接口!");
} else {
mFirstCallBack = (FirstCallBack) activity;
}
}
//两个onAttach都要重写,防止别人调用不同的onAttach方法
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (!(context instanceof FirstCallBack)) {
throw new IllegalStateException("FirstFragment对应的Activity没有实现FirstCallBack接口!");
} else {
mFirstCallBack = (FirstCallBack) context;
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_first, container, false);
//点击事件
Button button = mRootView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//调用activity中的回调方法onFirstCallBack
mFirstCallBack.onFirstCallBack("这是Fragment修改的值");
}
});
return mRootView;
}
}
5.Fragment对应的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一个Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
android:textAllCaps="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
6.最终实现的效果(点击Fragment中的button,可以将想要发送的String数据传给Activity并且设置在Activity上的TextView上):
三.通过广播的方式实现:
实现功能:Fragment向Activity传递数据(Activity向Fragment传递数据也可以,同理,这里不做介绍了)
1.Fragment中点击Button发送广播,携带相应的数据信息
package com.example.myapplication.fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.example.myapplication.R;
public class FirstFragment extends Fragment {
private View mRootView;
private Button mButton;
private LocalBroadcastManager mLocalBroadcastManager;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_first, container, false);
mButton = mRootView.findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发送广播
Intent intent = new Intent();
intent.setAction("com.example.myapplication.MyLocalBroadCast");
intent.putExtra("messenger", "这是Fragment传递过来的数据");
mLocalBroadcastManager = LocalBroadcastManager.getInstance(getContext());
mLocalBroadcastManager.sendBroadcast(intent);
}
});
return mRootView;
}
}
2.Fragment相应的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一个Fragment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
android:textAllCaps="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.对应的Activity中接收广播中传递过来的数据,并且将数据设置在Activity中的Textview中
package com.example.myapplication.Activity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.TextView;
import com.example.myapplication.R;
import com.example.myapplication.fragment.FirstFragment;
public class MainActivity extends AppCompatActivity {
private LocalBroadcastManager mLocalBroadcastManager;
private FirstBroadCastReceiver mFirstBroadCastReceiver;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//接收广播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.myapplication.MyLocalBroadCast");
mFirstBroadCastReceiver = new FirstBroadCastReceiver();
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mLocalBroadcastManager.registerReceiver(mFirstBroadCastReceiver, intentFilter);
//动态加载Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FirstFragment firstFragment = new FirstFragment();
fragmentTransaction.add(R.id.linearlayout, firstFragment);
fragmentTransaction.commit();
mTextView = findViewById(R.id.textview);
}
//广播接收器的类
class FirstBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String messenger = intent.getStringExtra("messenger");
mTextView.setText(messenger);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//广播的解注册
mLocalBroadcastManager.unregisterReceiver(mFirstBroadCastReceiver);
}
}
4.Activity对应的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Activity.MainActivity">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是主界面的初始值"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
5.最终实现的功能:点击Fragment上面的Button发送广播,在Activity中接收广播,并将接收到的数据设置在TextView中