目录
- 基础夯实:
- 一、Activity与Fragment的关系
- 二、通信场景
- 三、通信方式
- 1. 通过接口回调
- 2. 通过Bundle
- 3. 其他方式
- 四、注意事项
- 效果展示:
- 实现功能:
- 核心代码:
- MainActivity
- BlankFragment
基础夯实:
Activity与Fragment通信是Android开发中非常基础且重要的一个环节。以下是对Activity与Fragment通信基础理论的详细解释:
一、Activity与Fragment的关系
Activity是Android应用中的一个单独屏幕,可以包含布局和多个Fragment。
Fragment代表了Activity用户界面的一部分,可以嵌入到Activity中或者在多个Activity之间进行复用。
Fragment的生命周期与Activity绑定,但它也有自己独立的生命周期。
二、通信场景
Activity与Fragment之间的通信通常包括数据传递、状态变化通知、生命周期控制等多种情形,以实现整个UI界面的协调和交互。例如,当实现一个图文分享功能时,点击分享按钮会弹出ShareDialogFragment的弹窗页面,此时ShareDialogFragment需要获取当前图文的内容进行分享,这就需要Activity将图文内容传递给Fragment。
三、通信方式
1. 通过接口回调
定义接口:在Fragment中定义一个接口,包含将要被通信双方实现和调用的方法。
实现接口:Activity实现这个接口,并在适当的时候调用Fragment中的方法。
实例化接口:在Fragment的onAttach()方法中,通过将作为参数传入onAttach()的Activity做类型转换来实例化一个接口实例。
调用接口方法:Fragment通过调用接口中的方法来进行通信。
这种方式允许Fragment在不直接依赖Activity的情况下进行通信,提高了代码的解耦性和Fragment的可复用性。
2. 通过Bundle
当Activity需要向Fragment传递数据时,可以将数据放入Bundle中,然后在创建Fragment时通过setArguments()方法将Bundle传递给Fragment。
Fragment通过getArguments()方法获取传递过来的Bundle,并从中提取数据。
这种方式适用于在创建Fragment时传递数据,且这些数据在Fragment的生命周期内不会改变。
3. 其他方式
除了接口回调和Bundle外,还可以通过广播(Broadcast)、EventBus、ViewModel等方式实现Activity与Fragment之间的通信。这些方式各有优缺点,开发者可以根据具体需求选择合适的通信方式。
四、注意事项
在进行Fragment与Activity通信时,要确保Fragment已经正确附加到Activity上,否则可能会引发空指针异常。
为了保证Fragment的可复用性,应避免在Fragment中直接调用其他Fragment或Activity的方法。
在使用Bundle传递数据时,要注意数据的大小和类型限制。
总之,Activity与Fragment之间的通信是Android开发中非常基础且重要的一个环节。掌握多种通信方式并灵活运用,可以构建出更加高效和可复用的Android应用。
效果展示:
实现功能:
Activity 通过Bundle与Fragment通信,实现点击change,fragment中打印你好的功能
核心代码:
MainActivity
package com.example.application1;import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 设置活动的内容视图setContentView(R.layout.activity_main);// 初始化按钮并设置点击监听器Button button = findViewById(R.id.btn);button.setOnClickListener(this);Button button2 = findViewById(R.id.btn_2);button2.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.btn:// 当按钮被点击时,替换 FragmentBundle bundle = new Bundle();bundle.putString("message","你好");BlankFragment1 bf = new BlankFragment1();bf.setArguments(bundle);replaceFragment(bf);break;case R.id.btn_2:// 当按钮被点击时,替换 FragmentreplaceFragment(new ItemFragment());break;}}// 动态切换 Fragment 的方法private void replaceFragment(Fragment fragment) {// 获取 FragmentManagerFragmentManager fragmentManager = getSupportFragmentManager();// 开始事务FragmentTransaction transaction = fragmentManager.beginTransaction();// 替换 Fragmenttransaction.replace(R.id.framelayout, fragment);transaction.addToBackStack(null);// 提交事务transaction.commit();}
}
BlankFragment
package com.example.application1;import android.os.Bundle;import androidx.fragment.app.Fragment;import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;/*** A simple {@link Fragment} subclass.* Use the {@link BlankFragment1#newInstance} factory method to* create an instance of this fragment.*/
public class BlankFragment1 extends Fragment {private static final String TAG = "BlankFragment1";// TODO: Rename parameter arguments, choose names that match// the fragment initialization parameters, e.g. ARG_ITEM_NUMBERprivate static final String ARG_PARAM1 = "param1";private static final String ARG_PARAM2 = "param2";// TODO: Rename and change types of parametersprivate String mParam1;private String mParam2;public BlankFragment1() {// Required empty public constructor}/*** Use this factory method to create a new instance of* this fragment using the provided parameters.** @param param1 Parameter 1.* @param param2 Parameter 2.* @return A new instance of fragment BlankFragment1.*/// TODO: Rename and change types and number of parameterspublic static BlankFragment1 newInstance(String param1, String param2) {BlankFragment1 fragment = new BlankFragment1();Bundle args = new Bundle();args.putString(ARG_PARAM1, param1);args.putString(ARG_PARAM2, param2);fragment.setArguments(args);return fragment;}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Bundle bundle = this.getArguments();String string = bundle.getString("message");Log.d(TAG,"onCreate"+ string);if (getArguments() != null) {mParam1 = getArguments().getString(ARG_PARAM1);mParam2 = getArguments().getString(ARG_PARAM2);}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_blank1, container, false);}
}