前言
Fragment基础知识
Fragment碎片
- 自定义的Fragment必须继承Fragment类或其子类
创建Fragment
- 通常在创建Fragment时,需要实现方法:
- 将Fragment加载到Activity中主要有两种方式:
- 把Fragment添加到Activity的布局文件中
- 在Activity的代码中动态添加Fragment
管理Fragment
1 2
| FragmentManager fragmentManager=getFragmentManager(); FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
|
ps:FragmentTransaction被称作Fragment事务,与数据库事务类似,Fragment事务代表了Activity对Fragment执行的多个改变操作。
1 2 3 4 5 6 7 8 9 10
| Fragment newFragment=new ExampleFragment();
FragmentTransaction transaction=getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container,newFragment);
transaction.addToBackStack(null);
transaction.commit();
|
事务中动作的执行顺序可以随意,但需注意以下两点:
- 程序的最后必须调用commit()方法
- 程序中添加了多个Fragment对象,显示的顺序跟添加顺序一致
- 当删除Fragment对象时,在没有调用addToBackStack()方法情况下,Fragment对象会被销毁
ps:调用commit()后,事务并不会马上提交,而是会在Activity的UI线程中等待直到线程能执行的时候才执行。
与Activity通讯
- Fragment获取其所在的Activity中的组件
1
| View listView=getActivity().findViewById(R.id.list);
|
1 2
| ExampleFragment fragment = (ExampleFragment)getFragmentManager() .findFragmentById(R.id.example_fragment)
|
1 2 3 4 5 6 7 8 9
| public static class FragmentA extends ListFragment { ......省略 public interface OnNewsSelectedListener{ public void onNewsSelected(long id); } ......省略 }
|
- 使用onAttach()方法检查Activity是否实现回调接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static class FragmentA extends ListFragment { OnNewsSelectedListener mListener; ......省略 @Override public void onAttach(Activity activity){ super.onAttach(activity); try{ mListener =(OnNewsSelectedListener)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString() +"必须继承接口 OnNewsSelectedListener"); } } ......省略 }
|
Fragment的生命周期
Fragment的生命周期状态
- Fragment的生命周期具有以下四个状态:
- 活动状态: onResume()
- 暂停状态: onPause()
- 停止状态: onStop()
- 销毁状态: onDestroyView() || onDestroy()
ps: onActivityCreated()方法已经过期
方法 |
功能描述 |
onAttach() |
当一个Fragment对象关联到一个Activity时被调用 |
onCreate() |
初始化创建Fragment对象时被调用 |
onCreateView() |
当Activity获得Fragment的布局时调用此方法 |
onActivityCreated() |
当Activity对象完成自己的onCreate()方法时调用 (该方法已经过期) |
onStart() |
Fragment对象在UI界面可见时调用 |
onResume() |
Fragment对象的UI可以与用户交互时调用 |
onPause() |
由Activity对象转为onPause状态时调用 |
onStop() |
有组件完全遮挡,或者宿主Activity对象转为onStop状态时调用 |
onDestroyView() |
Fragment对象清理View资源时调用,即移除Fragment中的视图 |
onDestroy() |
Fragment对象完成对象清理View资源时调用 |
onDetach() |
当Fragment被从Activity中删掉时被调用 |
Fragment和Activity两者之间生命周期的关系
Activity直接影响其所包含的Fragment的生命周期
Fragment的回调方法要比Activity多,多出的方法主要用于与Activity的交互
当Activity进入运行状态时(即running状态),才允许添加或删除Fragment
有当Activity处于resumed状态时,Fragment的生命周期才能独立运转
其他阶段依赖于Activity的生命周期
静态方式
1 2 3 4 5 6
| <fragment android:name="com.gallifrey.todayapplication.fragment.MessageFragment" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:id="@+id/fl_container"/>
|
动态方式
- 通过重写Fragment生命周期的方法
- 在Activity代码中动态使用Fragment
测试样例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| package com.gallifrey.todayapplication;
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.widget.RadioGroup;
import com.gallifrey.todayapplication.fragment.DiscoverFragment; import com.gallifrey.todayapplication.fragment.MeFragment; import com.gallifrey.todayapplication.fragment.MessageFragment; import com.gallifrey.todayapplication.fragment.PhoneFragment;
import java.util.ArrayList; import java.util.List;
public class FragmentActivity extends AppCompatActivity implements PhoneFragment.IPhoneCallBack{ private FragmentManager fragmentManager; private FragmentTransaction fragmentTransaction; private PhoneFragment phoneFragment; private MessageFragment messageFragment;
private MeFragment meFragment; private DiscoverFragment discoverFragment; private RadioGroup mRg; private List<Fragment> fragmentList=new ArrayList<>();
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment);
mRg=findViewById(R.id.fl_rg);
fragmentManager=getSupportFragmentManager();
messageFragment =new MessageFragment(); fragmentList.add(messageFragment);
hideOtherFragment(messageFragment,true); mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int i) { switch (i){ case R.id.fl_rb_message: hideOtherFragment(messageFragment,false); break; case R.id.fl_rb_phone: if(phoneFragment==null){ phoneFragment=PhoneFragment.newInstance("phone 12315"); fragmentList.add(phoneFragment); hideOtherFragment(phoneFragment,true); }else { hideOtherFragment(phoneFragment,false); } break; case R.id.fl_rb_me: if(meFragment==null){ meFragment=new MeFragment(); fragmentList.add(meFragment); hideOtherFragment(meFragment,true); }else { hideOtherFragment(meFragment,false); } break; case R.id.fl_rb_discover: if(phoneFragment==null){ discoverFragment=new DiscoverFragment(); fragmentList.add(discoverFragment); hideOtherFragment(discoverFragment,true); }else { hideOtherFragment(discoverFragment,false); } break; } } });
} private void hideOtherFragment(Fragment currentFragment,boolean b){ fragmentTransaction=fragmentManager.beginTransaction(); if(b) { fragmentTransaction.add(R.id.fl_container, currentFragment); }
for(Fragment tempFragment:fragmentList){ if(tempFragment.equals(currentFragment)){ fragmentTransaction.show(tempFragment); }else { fragmentTransaction.hide(tempFragment); } } fragmentTransaction.commitAllowingStateLoss(); }
@Override public void setData(String str) { setTitle(str); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout 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=".FragmentActivity"> <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:id="@+id/fl_container"/> <View android:layout_width="match_parent" android:layout_height="2dp" android:background="#E4E3E3"/> <RadioGroup android:checkedButton="@id/fl_rb_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:id="@+id/fl_rg"> <RadioButton style="@style/flRadioButton" android:paddingVertical="5dp" android:id="@+id/fl_rb_message" android:text="消息" android:drawableTop="@drawable/fl_rb_message_bg" /> <RadioButton style="@style/flRadioButton" android:paddingVertical="5dp" android:id="@+id/fl_rb_phone" android:text="通信录" android:drawableTop="@drawable/fl_rb_phone_bg" /> <RadioButton style="@style/flRadioButton" android:paddingVertical="5dp" android:id="@+id/fl_rb_discover" android:text="发现" android:drawableTop="@drawable/fl_rb_discover_bg" /> <RadioButton style="@style/flRadioButton" android:paddingVertical="5dp" android:id="@+id/fl_rb_me" android:text="我" android:drawableTop="@drawable/fl_rb_me_bg" /> </RadioGroup> </LinearLayout>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| package com.gallifrey.todayapplication.fragment;
import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment;
import com.gallifrey.todayapplication.R;
public class PhoneFragment extends Fragment { private static final String ARG_PARAM="param1"; private static final String TAG="PhoneFragment"; private String param; private IPhoneCallBack iPhoneCallBack; public PhoneFragment(){ Log.i(TAG, "PhoneFragment: "); } public static PhoneFragment newInstance(String param1){ Log.i(TAG, "newInstance: into"); PhoneFragment phoneFragment=new PhoneFragment(); Bundle args=new Bundle(); args.putString(ARG_PARAM,param1); phoneFragment.setArguments(args); Log.i(TAG, "newInstance: out"); return phoneFragment; }
@Override public void onAttach(@NonNull Context context) { Log.i(TAG, "onAttach: "); super.onAttach(context); iPhoneCallBack= (IPhoneCallBack) context; }
@Override public void onCreate(@Nullable Bundle savedInstanceState) { Log.i(TAG, "onCreate: "); super.onCreate(savedInstanceState); if(getArguments()!=null){ param=getArguments().getString(ARG_PARAM); } }
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.i(TAG, "onCreateView: "); View view=inflater.inflate(R.layout.fragment_phone,container,false); TextView textView=view.findViewById(R.id.fl_tv); textView.setText(param); iPhoneCallBack.setData("通讯录Activity"); return view; }
@Override public void onDestroyView() { Log.i(TAG, "onDestroyView: "); super.onDestroyView(); }
@Override public void onDestroy() { Log.i(TAG, "onDestroy: "); super.onDestroy(); }
@Override public void onDetach() { Log.i(TAG, "onDetach: "); super.onDetach(); }
public interface IPhoneCallBack{ void setData(String str); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools" tools:context=".fragment.PhoneFragment"> <TextView android:id="@+id/fl_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:text="我是通讯录" android:textSize="32sp" android:gravity="center"/> </FrameLayout>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?xml version="1.0" encoding="utf-8"?> <resources> <style name="blue_textview"> <item name="android:textSize">30sp</item> <item name="android:textColor">#673AB7</item> <item name="android:textStyle">bold|italic</item> </style>
<style name="flRadioButton"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">match_parent</item> <item name="android:layout_weight">1</item> <item name="android:textSize">24sp</item> <item name="android:gravity">center</item> <item name="android:button">@null</item> <item name="android:textColor">@drawable/fl_rb_textcolor</item> </style> </resources>
|