一、ViewModel + 接口实现

1、ViewModel
  • NotifyObserver.java
public interface NotifyObserver {
    void onNotify(String message);
}
  • CommunicateFragment.java
public class SharedViewModel extends ViewModel {
    private NotifyObserver activityNotifyObserver;
    private NotifyObserver fragmentNotifyObserver;

    public void addActivityNotifyObserver(NotifyObserver activityNotifyObserver) {
        this.activityNotifyObserver = activityNotifyObserver;
    }

    public void addFragmentNotifyObserver(NotifyObserver fragmentNotifyObserver) {
        this.fragmentNotifyObserver = fragmentNotifyObserver;
    }

    public void notifyActivity(String message) {
        if (activityNotifyObserver != null) {
            activityNotifyObserver.onNotify(message);
        }
    }

    public void notifyFragment(String message) {
        if (fragmentNotifyObserver != null) {
            fragmentNotifyObserver.onNotify(message);
        }
    }
}
2、Activity
  • activity_communicate.xml
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CommunicateActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateActivity"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="show"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

    <FrameLayout
        android:id="@+id/fg_container"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateActivity.java
public class CommunicateActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_communicate);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // 动态加载 Fragment
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        supportFragmentManager.beginTransaction()
                .add(R.id.fg_container, new CommunicateFragment())
                .commit();


        // 从 ViewModelProvider 获取 SharedViewModel 实例
        SharedViewModel sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class);

        // 添加通知观察者
        sharedViewModel.addActivityNotifyObserver(message -> {
            Toast.makeText(this, "这里是 Activity,收到来自 Fragment 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        Button btnShow = findViewById(R.id.btn_show);
        btnShow.setOnClickListener(v -> {

            // 通知 Fragment
            sharedViewModel.notifyFragment("Hello Fragment");
        });
    }
}
3、Fragment
  • fragment_communicate.xml
<?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"
    tools:context=".fragment.CommunicateFragment">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateFragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="show"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateFragment.java
public class CommunicateFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_communicate, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // 从 ViewModelProvider 获取 SharedViewModel 实例
        SharedViewModel sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);

        // 添加通知观察者
        sharedViewModel.addFragmentNotifyObserver(message -> {
            Toast.makeText(getActivity(), "这里是 Fragment,收到来自 Activity 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        Button btnShow = view.findViewById(R.id.btn_show);
        btnShow.setOnClickListener(v -> {

            // 通知 Activity
            sharedViewModel.notifyActivity("Hello Activity");
        });
    }
}

二、ViewModel + LiveData 实现

1、ViewModel
  • SharedViewModel.java
public class SharedViewModel extends ViewModel {
    private MutableLiveData<String> activityLiveData;
    private MutableLiveData<String> fragmentLiveData;

    public MutableLiveData<String> getActivityLiveData() {
        if (activityLiveData == null) {
            activityLiveData = new MutableLiveData<>();
        }
        return activityLiveData;
    }

    public MutableLiveData<String> getFragmentLiveData() {
        if (fragmentLiveData == null) {
            fragmentLiveData = new MutableLiveData<>();
        }
        return fragmentLiveData;
    }

    public void notifyActivity(String message) {
        activityLiveData.setValue(message);
    }

    public void notifyFragment(String message) {
        fragmentLiveData.setValue(message);
    }
}
2、Activity
  • activity_communicate.xml
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CommunicateActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateActivity"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="show"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

    <FrameLayout
        android:id="@+id/fg_container"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateActivity.java
public class CommunicateActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_communicate);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // 动态加载 Fragment
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        supportFragmentManager.beginTransaction()
                .add(R.id.fg_container, new CommunicateFragment())
                .commit();


        // 从 ViewModelProvider 获取 SharedViewModel 实例
        SharedViewModel sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class);

        // 添加通知观察者
        sharedViewModel.getActivityLiveData().observe(this, message -> {
            Toast.makeText(this, "这里是 Activity,收到来自 Fragment 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        Button btnShow = findViewById(R.id.btn_show);
        btnShow.setOnClickListener(v -> {

            // 通知 Fragment
            sharedViewModel.notifyFragment("Hello Fragment");
        });
    }
}
3、Fragment
  • fragment_communicate.xml
<?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"
    tools:context=".fragment.CommunicateFragment">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateFragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="show"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateFragment.java
public class CommunicateFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_communicate, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // 从 ViewModelProvider 获取 SharedViewModel 实例
        SharedViewModel sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);

        // 添加通知观察者
        sharedViewModel.getFragmentLiveData().observe(getViewLifecycleOwner(), message -> {
            Toast.makeText(getActivity(), "这里是 Fragment,收到来自 Activity 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        Button btnShow = view.findViewById(R.id.btn_show);
        btnShow.setOnClickListener(v -> {

            // 通知 Activity
            sharedViewModel.notifyActivity("Hello Activity");
        });
    }
}

三、ViewModel + 接口多个观察者实现

1、ViewModel
  • NotifyObserver.java
public interface NotifyObserver {
    void onNotify(String message);
}
  • SharedMultipleViewModel.java
public class SharedMultipleViewModel extends ViewModel {
    private final Map<String, NotifyObserver> activityNotifyObserverMap = new HashMap<>();
    private final Map<String, NotifyObserver> fragmentNotifyObserverMap = new HashMap<>();

    public void addActivityNotifyObserver(String token, NotifyObserver activityNotifyObserver) {
        activityNotifyObserverMap.put(token, activityNotifyObserver);
    }

    public void addFragmentNotifyObserver(String token, NotifyObserver fragmentNotifyObserver) {
        fragmentNotifyObserverMap.put(token, fragmentNotifyObserver);
    }

    public void notifyActivity(String token, String message) {
        NotifyObserver activityNotifyObserver = activityNotifyObserverMap.get(token);
        if (activityNotifyObserver != null) {
            activityNotifyObserver.onNotify(message);
        }
    }

    public void notifyFragment(String token, String message) {
        NotifyObserver fragmentNotifyObserver = fragmentNotifyObserverMap.get(token);
        if (fragmentNotifyObserver != null) {
            fragmentNotifyObserver.onNotify(message);
        }
    }
}
2、Activity
  • activity_communicate_multiple.xml
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CommunicateMultipleActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateMultipleActivity"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

    <Button
        android:id="@+id/btn_change_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="改变文本"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show_toast" />

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_change_text" />

    <FrameLayout
        android:id="@+id/fg_container"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateMultipleActivity.java
public class CommunicateMultipleActivity extends AppCompatActivity {

    public static final String TOKEN_SHOW_TOAST = "token_show_toast";
    public static final String TOKEN_CHANGE_TEXT = "token_change_text";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_communicate_multiple);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        Button btnShowToast = findViewById(R.id.btn_show_toast);
        Button btnChangeText = findViewById(R.id.btn_change_text);
        TextView tvTest = findViewById(R.id.tv_test);

        // 动态加载 Fragment
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        supportFragmentManager.beginTransaction()
                .add(R.id.fg_container, new CommunicateMultipleFragment())
                .commit();

        // 从 ViewModelProvider 获取 SharedMultipleViewModel 实例
        SharedMultipleViewModel sharedMultipleViewModel = new ViewModelProvider(this).get(SharedMultipleViewModel.class);

        // 添加通知观察者
        sharedMultipleViewModel.addActivityNotifyObserver(TOKEN_SHOW_TOAST, message -> {
            Toast.makeText(this, "这里是 Activity,收到来自 Fragment 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        sharedMultipleViewModel.addActivityNotifyObserver(TOKEN_CHANGE_TEXT, message -> {
            tvTest.setText(message);
        });

        // 通知 Fragment
        btnShowToast.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyFragment(CommunicateMultipleFragment.TOKEN_SHOW_TOAST, "Hello Fragment 1");
        });

        btnChangeText.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyFragment(CommunicateMultipleFragment.TOKEN_CHANGE_TEXT, "Hello Fragment 2");
        });
    }
}
3、Fragment
  • fragment_communicate_multiple.xml
<?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"
    tools:context=".fragment.CommunicateMultipleFragment">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateMultipleFragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

    <Button
        android:id="@+id/btn_change_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="改变文本"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show_toast" />

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_change_text" />
</androidx.constraintlayout.widget.ConstraintLayout>
public class CommunicateMultipleFragment extends Fragment {

    public static final String TOKEN_SHOW_TOAST = "token_show_toast";
    public static final String TOKEN_CHANGE_TEXT = "token_change_text";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_communicate_multiple, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Button btnShowToast = view.findViewById(R.id.btn_show_toast);
        Button btnChangeText = view.findViewById(R.id.btn_change_text);
        TextView tvTest = view.findViewById(R.id.tv_test);

        // 从 ViewModelProvider 获取 SharedMultipleViewModel 实例
        SharedMultipleViewModel sharedMultipleViewModel = new ViewModelProvider(requireActivity()).get(SharedMultipleViewModel.class);

        // 添加通知观察者
        sharedMultipleViewModel.addFragmentNotifyObserver(TOKEN_SHOW_TOAST, message -> {
            Toast.makeText(getActivity(), "这里是 Fragment,收到来自 Activity 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        sharedMultipleViewModel.addFragmentNotifyObserver(TOKEN_CHANGE_TEXT, message -> {
            tvTest.setText(message);
        });

        // 通知 Activity
        btnShowToast.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyActivity(CommunicateMultipleActivity.TOKEN_SHOW_TOAST, "Hello Activity 1");
        });

        btnChangeText.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyActivity(CommunicateMultipleActivity.TOKEN_CHANGE_TEXT, "Hello Activity 2");
        });
    }
}

四、ViewModel + LiveData 多个观察者实现

1、ViewModel
  • SharedMultipleViewModel.java
public class SharedMultipleViewModel extends ViewModel {
    private Map<String, MutableLiveData<String>> activityLiveDataMap = new HashMap<>();
    private Map<String, MutableLiveData<String>> fragmentLiveDataMap = new HashMap<>();

    public MutableLiveData<String> getActivityLiveData(String token) {
        MutableLiveData<String> activityLiveData = activityLiveDataMap.get(token);
        if (activityLiveData == null) {
            activityLiveData = new MutableLiveData<>();
            activityLiveDataMap.put(token, activityLiveData);
        }
        return activityLiveData;
    }

    public MutableLiveData<String> getFragmentLiveData(String token) {
        MutableLiveData<String> fragmentLiveData = fragmentLiveDataMap.get(token);
        if (fragmentLiveData == null) {
            fragmentLiveData = new MutableLiveData<>();
            fragmentLiveDataMap.put(token, fragmentLiveData);
        }
        return fragmentLiveData;
    }

    public void notifyActivity(String token, String message) {
        MutableLiveData<String> activityLiveData = activityLiveDataMap.get(token);
        if (activityLiveData != null) {
            activityLiveData.setValue(message);
        }
    }

    public void notifyFragment(String token, String message) {
        MutableLiveData<String> fragmentLiveData = fragmentLiveDataMap.get(token);
        if (fragmentLiveData != null) {
            fragmentLiveData.setValue(message);
        }
    }
}
2、Activity
  • activity_communicate_multiple.xml
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CommunicateMultipleActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateMultipleActivity"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

    <Button
        android:id="@+id/btn_change_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="改变文本"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show_toast" />

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_change_text" />

    <FrameLayout
        android:id="@+id/fg_container"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateMultipleActivity.java
public class CommunicateMultipleActivity extends AppCompatActivity {

    public static final String TOKEN_SHOW_TOAST = "token_show_toast";
    public static final String TOKEN_CHANGE_TEXT = "token_change_text";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_communicate_multiple);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        Button btnShowToast = findViewById(R.id.btn_show_toast);
        Button btnChangeText = findViewById(R.id.btn_change_text);
        TextView tvTest = findViewById(R.id.tv_test);

        // 动态加载 Fragment
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        supportFragmentManager.beginTransaction()
                .add(R.id.fg_container, new CommunicateMultipleFragment())
                .commit();

        // 从 ViewModelProvider 获取 SharedMultipleViewModel 实例
        SharedMultipleViewModel sharedMultipleViewModel = new ViewModelProvider(this).get(SharedMultipleViewModel.class);

        // 添加通知观察者
        sharedMultipleViewModel.getActivityLiveData(TOKEN_SHOW_TOAST).observe(this, message -> {
            Toast.makeText(this, "这里是 Activity,收到来自 Fragment 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        sharedMultipleViewModel.getActivityLiveData(TOKEN_CHANGE_TEXT).observe(this, message -> {
            tvTest.setText(message);
        });

        // 通知 Fragment
        btnShowToast.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyFragment(CommunicateMultipleFragment.TOKEN_SHOW_TOAST, "Hello Fragment 1");
        });

        btnChangeText.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyFragment(CommunicateMultipleFragment.TOKEN_CHANGE_TEXT, "Hello Fragment 2");
        });
    }
}
3、Fragment
  • fragment_communicate_multiple.xml
<?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"
    tools:context=".fragment.CommunicateMultipleFragment">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CommunicateMultipleFragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_show_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示通知"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

    <Button
        android:id="@+id/btn_change_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="改变文本"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_show_toast" />

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_change_text" />
</androidx.constraintlayout.widget.ConstraintLayout>
  • CommunicateMultipleFragment.java
public class CommunicateMultipleFragment extends Fragment {

    public static final String TOKEN_SHOW_TOAST = "token_show_toast";
    public static final String TOKEN_CHANGE_TEXT = "token_change_text";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_communicate_multiple, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Button btnShowToast = view.findViewById(R.id.btn_show_toast);
        Button btnChangeText = view.findViewById(R.id.btn_change_text);
        TextView tvTest = view.findViewById(R.id.tv_test);

        // 从 ViewModelProvider 获取 SharedMultipleViewModel 实例
        SharedMultipleViewModel sharedMultipleViewModel = new ViewModelProvider(requireActivity()).get(SharedMultipleViewModel.class);

        // 添加通知观察者
        sharedMultipleViewModel.getFragmentLiveData(TOKEN_SHOW_TOAST).observe(getViewLifecycleOwner(), message -> {
            Toast.makeText(getActivity(), "这里是 Fragment,收到来自 Activity 的消息:" + message, Toast.LENGTH_SHORT).show();
        });

        sharedMultipleViewModel.getFragmentLiveData(TOKEN_CHANGE_TEXT).observe(getViewLifecycleOwner(), message -> {
            tvTest.setText(message);
        });

        // 通知 Activity
        btnShowToast.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyActivity(CommunicateMultipleActivity.TOKEN_SHOW_TOAST, "Hello Activity 1");
        });

        btnChangeText.setOnClickListener(v -> {
            sharedMultipleViewModel.notifyActivity(CommunicateMultipleActivity.TOKEN_CHANGE_TEXT, "Hello Activity 2");
        });
    }
}
Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐