android中fragment demo举例
好的我来给你一个完整的Fragment Demo从简单到复杂并详细讲解每个部分。一、最简单的Fragment Demo1. 创建Fragment布局文件res/layout/fragment_demo.xml?xml version1.0 encodingutf-8?LinearLayoutxmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticalandroid:padding16dpandroid:gravitycenterTextViewandroid:idid/tv_titleandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:text这是Fragmentandroid:textSize24spandroid:textColorandroid:color/black/Buttonandroid:idid/btn_clickandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_marginTop16dpandroid:text点击我//LinearLayout2. 创建Fragment类DemoFragment.javapublicclassDemoFragmentextendsFragment{// 1. 创建Fragment实例的方法推荐写法publicstaticDemoFragmentnewInstance(){returnnewDemoFragment();}// 2. Fragment创建时调用最早执行OverridepublicvoidonCreate(NullableBundlesavedInstanceState){super.onCreate(savedInstanceState);// 初始化数据不涉及UI}// 3. 创建视图最重要的方法NullableOverridepublicViewonCreateView(NonNullLayoutInflaterinflater,NullableViewGroupcontainer,NullableBundlesavedInstanceState){// 加载布局文件returninflater.inflate(R.layout.fragment_demo,container,false);}// 4. 视图创建完成后调用OverridepublicvoidonViewCreated(NonNullViewview,NullableBundlesavedInstanceState){super.onViewCreated(view,savedInstanceState);// 找到控件并设置点击事件TextViewtvTitleview.findViewById(R.id.tv_title);ButtonbtnClickview.findViewById(R.id.btn_click);btnClick.setOnClickListener(v-{tvTitle.setText(按钮被点击了);});}}3. 在Activity中使用Fragmentactivity_main.xml?xml version1.0 encodingutf-8?LinearLayoutxmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationvertical!-- 方式1通过标签静态添加Fragment --fragmentandroid:idid/fragment_staticandroid:namecom.example.DemoFragmentandroid:layout_widthmatch_parentandroid:layout_height0dpandroid:layout_weight1/!-- 方式2FrameLayout作为Fragment容器 --FrameLayoutandroid:idid/fragment_containerandroid:layout_widthmatch_parentandroid:layout_height0dpandroid:layout_weight1/Buttonandroid:idid/btn_add_fragmentandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:text动态添加Fragment//LinearLayoutMainActivity.javapublicclassMainActivityextendsAppCompatActivity{OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 动态添加FragmentButtonbtnAddfindViewById(R.id.btn_add_fragment);btnAdd.setOnClickListener(v-{// 开始Fragment事务getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,newDemoFragment())// 替换容器内容.addToBackStack(null)// 加入返回栈.commit();// 提交事务});}}二、带参数传递的Fragment Demo实际开发常用1. 带参数的FragmentUserDetailFragment.javapublicclassUserDetailFragmentextendsFragment{privateTextViewtvUserName,tvUserAge;// 定义参数keyprivatestaticfinalStringARG_USER_NAMEuser_name;privatestaticfinalStringARG_USER_AGEuser_age;// 推荐通过newInstance传递参数publicstaticUserDetailFragmentnewInstance(Stringname,intage){UserDetailFragmentfragmentnewUserDetailFragment();// 使用Bundle传递参数BundleargsnewBundle();args.putString(ARG_USER_NAME,name);args.putInt(ARG_USER_AGE,age);fragment.setArguments(args);// 设置参数returnfragment;}NullableOverridepublicViewonCreateView(NonNullLayoutInflaterinflater,NullableViewGroupcontainer,NullableBundlesavedInstanceState){returninflater.inflate(R.layout.fragment_user_detail,container,false);}OverridepublicvoidonViewCreated(NonNullViewview,NullableBundlesavedInstanceState){super.onViewCreated(view,savedInstanceState);tvUserNameview.findViewById(R.id.tv_user_name);tvUserAgeview.findViewById(R.id.tv_user_age);// 获取传递的参数if(getArguments()!null){StringnamegetArguments().getString(ARG_USER_NAME);intagegetArguments().getInt(ARG_USER_AGE);tvUserName.setText(姓名name);tvUserAge.setText(年龄age);}}}2. 使用方式// 在Activity或其他Fragment中UserDetailFragmentfragmentUserDetailFragment.newInstance(张三,25);getSupportFragmentManager().beginTransaction().replace(R.id.container,fragment).commit();三、Fragment与Activity通信的Demo1. Fragment定义接口CommunicationFragment.javapublicclassCommunicationFragmentextendsFragment{privateEditTextetInput;privateButtonbtnSend;privateOnDataSendListenerlistener;// 定义通信接口publicinterfaceOnDataSendListener{voidonDataSend(Stringdata);}// 绑定Activity时调用OverridepublicvoidonAttach(NonNullContextcontext){super.onAttach(context);// 检查Activity是否实现了接口if(contextinstanceofOnDataSendListener){listener(OnDataSendListener)context;}else{thrownewRuntimeException(Activity必须实现OnDataSendListener);}}NullableOverridepublicViewonCreateView(NonNullLayoutInflaterinflater,NullableViewGroupcontainer,NullableBundlesavedInstanceState){Viewviewinflater.inflate(R.layout.fragment_communication,container,false);etInputview.findViewById(R.id.et_input);btnSendview.findViewById(R.id.btn_send);btnSend.setOnClickListener(v-{StringdataetInput.getText().toString();if(listener!null){listener.onDataSend(data);// 发送数据给Activity}});returnview;}}2. Activity实现接口MainActivity.javapublicclassMainActivityextendsAppCompatActivityimplementsCommunicationFragment.OnDataSendListener{privateTextViewtvReceived;OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tvReceivedfindViewById(R.id.tv_received);// 添加Fragmentif(savedInstanceStatenull){getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,newCommunicationFragment()).commit();}}OverridepublicvoidonDataSend(Stringdata){// 接收Fragment发送的数据tvReceived.setText(收到data);// 可以Toast提示Toast.makeText(this,收到data,Toast.LENGTH_SHORT).show();}}四、Fragment生命周期详解完整生命周期DemopublicclassLifecycleDemoFragmentextendsFragment{privatestaticfinalStringTAGLifecycleDemo;OverridepublicvoidonAttach(NonNullContextcontext){super.onAttach(context);Log.d(TAG,1. onAttach - Fragment与Activity绑定);}OverridepublicvoidonCreate(NullableBundlesavedInstanceState){super.onCreate(savedInstanceState);Log.d(TAG,2. onCreate - 创建Fragment初始化数据);}OverridepublicViewonCreateView(NonNullLayoutInflaterinflater,NullableViewGroupcontainer,NullableBundlesavedInstanceState){Log.d(TAG,3. onCreateView - 创建视图);returninflater.inflate(R.layout.fragment_demo,container,false);}OverridepublicvoidonViewCreated(NonNullViewview,NullableBundlesavedInstanceState){super.onViewCreated(view,savedInstanceState);Log.d(TAG,4. onViewCreated - 视图已创建可以操作UI);}OverridepublicvoidonStart(){super.onStart();Log.d(TAG,5. onStart - Fragment可见);}OverridepublicvoidonResume(){super.onResume();Log.d(TAG,6. onResume - Fragment获得焦点可交互);}OverridepublicvoidonPause(){super.onPause();Log.d(TAG,7. onPause - Fragment失去焦点);}OverridepublicvoidonStop(){super.onStop();Log.d(TAG,8. onStop - Fragment不可见);}OverridepublicvoidonDestroyView(){super.onDestroyView();Log.d(TAG,9. onDestroyView - 销毁视图);}OverridepublicvoidonDestroy(){super.onDestroy();Log.d(TAG,10. onDestroy - 销毁Fragment);}OverridepublicvoidonDetach(){super.onDetach();Log.d(TAG,11. onDetach - Fragment与Activity解绑);}}生命周期流程图Activity创建 ↓ onAttach() ← Fragment与Activity绑定 ↓ onCreate() ← 初始化数据 ↓ onCreateView() ← 创建视图返回View ↓ onViewCreated()← 视图创建完成操作UI ↓ onStart() ← Fragment可见 ↓ onResume() ← Fragment可交互 ↓ 【运行中】 ↓ onPause() ← 失去焦点如另一个Activity弹窗 ↓ onStop() ← 完全不可见 ↓ onDestroyView()← 销毁视图 ↓ onDestroy() ← 销毁Fragment ↓ onDetach() ← 与Activity解绑五、实际使用建议1. Fragment最佳实践模板publicclassBestPracticeFragmentextendsFragment{// 1. 使用newInstance传递参数publicstaticBestPracticeFragmentnewInstance(Stringparam){BestPracticeFragmentfragmentnewBestPracticeFragment();BundleargsnewBundle();args.putString(param,param);fragment.setArguments(args);returnfragment;}// 2. 声明View变量privateViewrootView;privateTextViewtvContent;NullableOverridepublicViewonCreateView(NonNullLayoutInflaterinflater,NullableViewGroupcontainer,NullableBundlesavedInstanceState){// 缓存Viewif(rootViewnull){rootViewinflater.inflate(R.layout.fragment_best,container,false);}returnrootView;}OverridepublicvoidonViewCreated(NonNullViewview,NullableBundlesavedInstanceState){super.onViewCreated(view,savedInstanceState);// 初始化控件tvContentview.findViewById(R.id.tv_content);// 获取参数if(getArguments()!null){StringparamgetArguments().getString(param);tvContent.setText(param);}}// 提供更新UI的方法publicvoidupdateContent(StringnewContent){if(tvContent!null){tvContent.setText(newContent);}}}2. Fragment事务注意事项// ✅ 正确使用tag标记Fragment避免重复添加Stringtagdemo_fragment;FragmentfragmentgetSupportFragmentManager().findFragmentByTag(tag);if(fragmentnull){fragmentnewDemoFragment();getSupportFragmentManager().beginTransaction().add(R.id.container,fragment,tag).commit();}// ✅ 正确使用commitAllowingStateLoss()避免状态丢失异常getSupportFragmentManager().beginTransaction().replace(R.id.container,newFragment).commitAllowingStateLoss();// ❌ 错误不要在onCreateView中操作FragmentTransaction// ✅ 正确在Activity的onCreate中或使用post延迟执行rootView.post(()-{getChildFragmentManager().beginTransaction()...});总结要点创建Fragment继承Fragment实现onCreateView使用Fragment通过FragmentTransaction的add/replace方法传递参数使用setArguments(Bundle)不要用构造方法与Activity通信定义接口在onAttach中绑定生命周期理解11个生命周期方法知道什么时候做什么返回栈addToBackStack(null)可以让用户按返回键回到上一个Fragment