1, an overview of the
First, if you want to implement communication between activities and other fragments, the Fragment needs to have a separate Layout file that can be reused and added to the Activity as code. The advantage of this is that we can write the relevant business logic in the Fragment, reducing the code in the Activity that it is attached to.
In the official document, it is recommended that we use the ViewModel when implementing fragments to communicate with other activities/fragments, and store our model data in the ViewModel. Data communication is achieved by sharing the ViewModel between the Fragment and Activity that we want to establish a relationship with (one Fragment/Activity updates the ViewModel, Other fragments/activities associated with the ViewModel will also change).
But instead of going through the ViewModel, you can go through the official documentation if you’re interested. Let’s talk about communicating between activities and other fragments using interfaces. This approach requires a lot more work than using the ViewModel.
2. Preparation: Add Fragment to Activity
Before a Fragment can interact with an Activity, they need to be ‘connected’ together.
(1) Create a new project, the main activity isMainActivity
, we changed its layout to the following:
activity_main.xml
<? The XML version = "1.0" encoding = "utf-8"? > <FrameLayout 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" tools:context=".MainActivity" android:id="@+id/fragment_container"> </FrameLayout>Copy the code
There is only one FrameLayout in the main activity layout and you give it an ID.
Create a Fragment
public class BFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_b_layout, container, false);
Button sendMsgBtn = rootView.findViewById(R.id.send_msg_btn);
sendMsgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Send a message to the Activity}});returnrootView; }}Copy the code
Create a layout file for the Fragment fragment_b_layout.xml
<?xml version="1.0" encoding="utf-8"? >
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BUTTON"
android:id="@+id/send_msg_btn"/>
</RelativeLayout>
Copy the code
There is only one Button in the Fragment layout, and we will implement transferring data from the Fragment to the Activity by clicking on the Button.
(3) Display the Fragment on the Activity
You need the FragmentManager to manage your fragments and display them on your Activity.
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = newBFragment(); transaction.add(R.id.fragment_container, fragment); transaction.commit(); }}}Copy the code
OK, now that we’re ready, let’s run it. The page should look like this:
3. Realize communication
(1), define the interface
We define an interface in the BFragment,
public class BFragment extends Fragment {... Callback mCallback;public interface Callback{
public void onBtnClickListener(String str);
}
public void setCallback(Callback callback) { mCallback = callback; }... }Copy the code
There is only one method in the interface and it takes a String parameter.
For button, set a click event: when the button is clicked, call the interface’s methods:
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {... sendMsgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mCallback ! =null ) {
mCallback.onBtnClickListener("I'm from Fragment B"); }}}); . }Copy the code
We pass the data we want to pass to the Activity into the interface method.
(2) to realize the interface
We have MainActivity implement the interface Callback we just defined in the BFragment and call the BFragment’s setCallback(Callback Callback). Because the MainActivity class implements the Callback interface, parameters can be passed to the MainActivity itself. In the onBtnClickListener(String STR) method that implements Callback, we pop up a toast with information.
public class MainActivity extends AppCompatActivity implements BFragment.Callback{...@Override
public void onBtnClickListener(String str) {
Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); }...@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); .// omit the code you just wrote
if (fragment == null) {
fragment = new BFragment();
((BFragment) fragment).setCallback(this); transaction.add(R.id.fragment_container, fragment); transaction.commit(); }}}Copy the code
Run, see the effect:
As expected, by clicking on the Button in the Fragment, we managed to make the Activity generate a Toast as a response and get the string data passed.
(~)