更新!!!
目前的Fragment使用最新的Androidx库,因此需要添加依赖
dependencies {
def fragment_version = "1.2.5"
// Java language implementation
implementation "androidx.fragment:fragment:$fragment_version
}
一:Fragment简介
Fragment最初的作用是为了适应大屏幕的平板电脑,开发者可以使用Fragment对UI组件进行分组,模块化管理,可以更方便的在运行过程中动态更新Activity的用户界面。
1. Fragment的特点:
- 必须嵌入到Activity中使用,受activity的生命周期控制
- Fragment可以被多个activity复用
- Fragment拥有自己的生命周期,可以相应自己的输入事件
2. Fragment 与 Activity的交互
- Fragment可以调用
getActivity()
获取它所在的activity。Activity可以调用FragmentManager.findFragmentById()
或者FragmentManager.findFragmentByTag()
的方法来获取Fragment - 在Activity运行过程中,可以调用
FragmentManager.add().remove().replace()
方法来动态的添加,删除或者替换Fragment
3. Fragment的继承体系
4. 使用的注意事项
- 除了生命周期的回调方法根据自己需要重写之外,一般都要重写
onCreateView()
方法,返回的view作为显示的view组件。当Fragment绘制界面组件时将回调该方法。 - 目前应使用最新的
androidx.fragment.app.Fragment
二:Fragment的简单使用
最简单的使用方法是:新建两个Frament的布局文件,以及两个继承Fragment的类。并在Activity_main的xml文件中引入的标签来添加fragment。
示例代码:
fragment_1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#AB8ED6">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fragment1_text"
/>
</LinearLayout>
fragment_2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fragment2_text"/>
</LinearLayout>
Fragment1
public class Fragment1 extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_1,container,false); //这里要做修改,否则无法加载布局,会报错
}
}
Fragment2
public class Fragment2 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_2,container,false);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="horizontal">
<fragment
android:id="@+id/fragment_1"
android:name="com.lwl.FragmentDemo.Fragment1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<fragment
android:id="@+id/fragment_2"
android:name="com.lwl.FragmentDemo.Fragment2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
效果图:
三:Fragment进阶
1. 重要方法分析
onAttach(Context context) //当该Fragment被添加,显示到它所在的context时回调该方法
onDetach() //当该Fragment从它所属的activity中删除时回调该方法
2. Fragment与Activity通信问题
添加Fragment到Activity有两种方式
- 在布局文件中使用<fragment … />元素添加,其中的
android:name
属性指定Fragment实现类- 在代码中通过
FragmentTransaction
对象的add()
方法来添加,至于activity是否一定要使用FragmentActivity,目前有待继续观察
Fragment fragment = new Fragment(); //需要继承androidx.fragment.app.Fragment
getSupportFragmentManager().beginTransaction().replace(R.id.layout_main,fragment).commit();
//使用getSupportFragmentManager()获得FragmentManager
//beginTransaction()方法开启并返回FragmentTransaction()对象
// R.id.layout_main为容器的id,某一个layout
Activity与Fragment传递数据
- Activity向Fragment传递数据:在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法即可将bundle数据包传给fragment
- fragment向activity传递数据或activity需要在fragment运行中进行实时通信:在fragment中定义一个内部回调接口,再让包含该Fragment的Activitt实现该回调接口,这样即可调用该回调方法将数据传给Activity
Fragment之间的通信问题:
通过getActivity这个方法实现的。getActivity方法可以让Fragment获取到关联的Activity,然后再调用Activity的findViewById方法,就可以获取到和这个Activity关联的其它Fragment的视图了。
3. Fragment的生命周期
public class Fragment1 extends Fragment {
public static final String TAG = "Fragment1";
//为Fragment加载布局时调用。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
return inflater.inflate(R.layout.fragment1, container, false);
}
//Fragment和Activity建立关联的时候调用。
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(TAG, "onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
//当Activity中的onCreate方法执行完后调用。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");d就已经将ActivityGroup废弃掉了,并且官方推荐的替代方式就是使用Fragment,因为它使用起来更加的灵活。那么剩下的问题就是如何借助Fragment来完成类似于TabHost一般的效果了,因此我们自然要动起手来了。
在开始之前,首先你必须已经了解Fragment的用法了,如果你对Fragment还比较陌生的话,建议先去阅读我前面的一篇文章 Android Fragment完全解析,关于碎片你所需知道的一切 。
另外,我们还应该准备好程序所需要的资源,比如说每一个Tab项中所用到的图片。我已经事先从QQ里截好了几张图作为这个项目的资源,稍后会连同源码一起给出。
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
//Fragment中的布局被移除时调用。
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
//Fragment和Activity解除关联的时候调用。
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "onDetach");
}