目录

一、Fragment是什么

二、Fragment的生命周期

三、添加Fragment的方式

3.1 静态添加fragment

3.2 动态添加Fragment:


一、Fragment是什么

Android3.0以后引进了新的控件Fragment(碎片),Fragment相较于Activity更灵活,Fragment有自己的类和xml配置文件,因此一个Fragment可以被多个Activity复用。而且Activity是需要在Androidmanifest.xml上声明的,Fragment则只需要在调用该Fragment的Activity的配置文件中声明即可。

Fragment主要是为了给更大的屏幕(如平板电脑)上更加动态和灵活的 UI 设计提供支持。由于平板屏幕比手机的屏幕大得多,也能显示更多的布局和组件。

例如,新闻应用可以使用一个片段在左侧显示文章列表,使用另一个片段在右侧显示文章 — 两个片段并排显示在一个 Activity 中,每个片段都具有自己的一套生命周期回调方法,并各自处理自己的用户输入事件。 因此,用户不需要使用一个 Activity 来选择文章,然后使用另一个 Activity 来阅读文章,而是可以在同一个 Activity 内选择文章并进行阅读,如图 1 中的平板电脑布局所示。(可以通过判断屏幕窗口尺寸来决定fragment的布局)

fstrim工具在android上使用 fragment android_配置文件

 

二、Fragment的生命周期

fstrim工具在android上使用 fragment android_fstrim工具在android上使用_02

可以看到,Fragment的生命周期其实和Activity很相似,只不过多了几个方法:

  • onAttached() —— 当fragment被加入到activity时调用(在这个方法中可以获得所在的activity)。
  • onCreateView() —— 当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)。
  • onActivityCreated() —— 当activity的onCreated()方法返回后调用此方法
  • onDestroyView() —— 当fragment中的视图被移除的时候,调用这个方法。
  • onDetach() —— 当fragment和activity分离的时候,调用这个方法。

 

三、添加Fragment的方式

3.1 静态添加fragment

步骤:

1.新建Fragment类

2.新建步骤1中Fragment的对应xml 

3.在调用Fragment的Activity的配置文件中声明要调用的Fragment

例子:

运行效果:

左边和右边分别是两个不同的Fragment,然后主Activity(MainActivity)调用这两个Fragment:

fstrim工具在android上使用 fragment android_配置文件_03

项目目录如下:

只需要关注红框内的文件即可。

fstrim工具在android上使用 fragment android_配置文件_04

代码:

新建leftFragment和rightFragment两个Fragment的类:

leftFragment.java:

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class leftFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left_fragment,container,false);
        return view;
    }
}

rightFragment.java

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class rightFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.right_fragment,container,false);
        return view;
    }
}

然后创建leftFragment和righFragment的布局文件 left_fragment.xml 和 right_fragment.xml :

left_fragment.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="@android:color/darker_gray">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button" />
</LinearLayout>

right_fragment.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="@android:color/holo_purple">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="20sp"
        android:text="this is Fragment" />

</LinearLayout>

在调用Fragment的Activity配置文件中声明Fragment:

activity_main.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=".MainActivity">

    <fragment
        android:id="@+id/fragment01"
        android:name="com.example.fragmenttest.leftFragment" //leftFragment的全限定名
        android:layout_width="215dp"
        android:layout_height="741dp"
        android:layout_weight="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <fragment
        android:id="@+id/fragment02"
        android:name="com.example.fragmenttest.rightFragment"
        android:layout_width="198dp"
        android:layout_height="739dp"
        android:layout_weight="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

3.2 动态添加Fragment:

跟静态不同的是,动态可以通过与用户交互的方式,动态改变Fragment ,例如增加,删除,切换Fragment,而静态添加则不行。静态添加的方式在activity的配置文件就把Fragment写死了,而动态添加的方式则不需要在activity的配置文件中声明Fragment,(使用起来更加的解耦)而是使用事务的方式,更换Fragment。具体代码如下:

效果:

点击ONE和TWO按钮都会动态地调出各自的Fragment

fstrim工具在android上使用 fragment android_fstrim工具在android上使用_05

fstrim工具在android上使用 fragment android_配置文件_06

代码:

先定义 Fragment01和Fragment02的布局文件:

fragment01.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:layout_gravity="center"
    android:background="@android:color/holo_blue_light"
    >

    <LinearLayout
        android:layout_width="446dp"
        android:layout_height="462dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Fragment01" />
    </LinearLayout>
</LinearLayout>

fragment02.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="@android:color/holo_orange_light">

    <LinearLayout
        android:layout_width="459dp"
        android:layout_height="550dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="This is Fragment02" />
    </LinearLayout>
</LinearLayout>

定义好fragment的布局文件后,创建对应fragment的类文件:

fragment01.java:

package com.example.dynamicfragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import android.app.Fragment;
public class Fragment01 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment01,null);
    }
}

fragment02.java:

package com.example.dynamicfragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.app.Fragment;

public class Fragment02 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment02,null);
    }
}

定义完fragment组建的相关代码后,开始准备用Activity调用这些fragment。

我们使用MainActivity进行对fragment的调用,因此先改写一下MainActivity的配置文件

activity_main.xml:

值得注意的是:我们在此布局的配置文件中,创建一个 LinearLayout布局来装fragment,并把这个LinearLayout布局命名为frame_id。

<?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=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="One"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.297"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.812" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Two"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.467"
        app:layout_constraintStart_toEndOf="@+id/button"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.812" />

    <LinearLayout
        android:id="@+id/frame_id"
        android:layout_width="352dp"
        android:layout_height="476dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.102"></LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

最后写MainActivity调用 fragment的逻辑

MainActivity.java:

package com.example.dynamicfragment;

import androidx.appcompat.app.AppCompatActivity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button b1,b2;
    private FragmentManager fm;
    private FragmentTransaction ft;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button b1 = (Button)findViewById(R.id.button);
        Button b2 = (Button)findViewById(R.id.button2);
        b1.setOnClickListener(this);
        b2.setOnClickListener(this);

        fm = getFragmentManager();
        ft = fm.beginTransaction();
        ft.add(R.id.frame_id,new Fragment01());
        ft.commit();   //提交事务 
    }


    @Override
    public void onClick(View v) {
        ft = fm.beginTransaction();
        switch (v.getId()){
            case R.id.button:
                ft.replace(R.id.frame_id,new Fragment01());
                ft.addToBackStack(null);//把Fragment01 放到栈中,等以后按下返回键时,可以返回到Fragment01中
                break;
            case R.id.button2:
                ft.replace(R.id.frame_id,new Fragment02());
                ft.addToBackStack(null);
                break;
            default:break;
        }
        ft.commit();

    }
}