008 Android Fragment原理及应用

1.Fragment简介

  Fragment(片段) 表示 Activity 中的行为或用户界面部分。您可以将多个片段组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个片段您可以将片段视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或移除片段(有点像您可以在不同 Activity 中重复使用的“子 Activity”)。

  Fragment(片段)必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。 例如,当 Activity 暂停时,其中的所有片段也会暂停;当 Activity 被销毁时,所有片段也会被销毁。 不过,当 Activity 正在运行(处于已恢复生命周期状态)时,您可以独立操纵每个片段,如添加或移除它们。 当您执行此类片段事务时,您也可以将其添加到由 Activity 管理的返回栈 — Activity 中的每个返回栈条目都是一条已发生片段事务的记录。 返回栈让用户可以通过按返回按钮撤消片段事务(后退)。

  当您将Fragment(片段)作为 Activity 布局的一部分添加时,它存在于 Activity 视图层次结构的某个 ViewGroup 内部,并且片段会定义其自己的视图布局。您可以通过在 Activity 的布局文件中声明片段,将其作为 <fragment>元素插入您的 Activity 布局中,或者通过将其添加到某个现有 ViewGroup,利用应用代码进行插入。不过,片段并非必须成为 Activity 布局的一部分;您还可以将没有自己 UI 的片段用作 Activity 的不可见工作线程。

  注意:Fragment(片段)通常用作 Activity 用户界面的一部分,将其自己的布局融入 Activity。

2.Fragment(片段的创建)

  要想创建片段,您必须创建 Fragment 的子类(或已有其子类)。Fragment 类的代码与 Activity 非常相似。它包含与 Activity 类似的回调方法,如onCreate()onStart()onPause() 和 onStop()。实际上,如果您要将现有 Android 应用转换为使用片段,可能只需将代码从 Activity 的回调方法移入片段相应的回调方法中。

  通常,您至少应实现以下生命周期方法:

  (1)onCreate()系统会在创建Fragment(片段)时调用此方法。您应该在实现内初始化您想在片段暂停或停止后恢复时保留的必需片段组件。
  (2)onCreateView()系统会在Fragment(片段)首次绘制其用户界面时调用此方法。 要想为您的Fragment(片段)绘制 UI,您从此方法中返回的 View 必须是片段布局的根视图。如果片段未提供 UI,您可以返回 null。通过onCreateView()方法,Fragment可以加载自己的布局。
  (3)onPause():系统将此方法作为用户离开片段的第一个信号(但并不总是意味着此片段会被销毁)进行调用。 您通常应该在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。

  大多数应用都应该至少为每个片段实现这三个方法,但您还应该使用几种其他回调方法来处理片段生命周期的各个阶段。

  注意:实际开发中,必须重写onCreateView()方法,另外也可以重写onDestroy方法,进行一些回收内存的操作。

3.向 Activity 添加片段

  要想在您的 Activity 中执行Fragment(片段)事务(如添加、移除或替换片段),您必须使用FragmentTransaction 中的 API。您可以像下面这样从 Activity 获取一个 FragmentTransaction 实例:

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

(1)将一个片段替换成另一个片段,以及如何在返回栈中保留先前状态;

//动态替换fragment
//1.获取Fragment的管理者
FragmentManager fragmentManager=getSupportFragmentManager();
//2.开启事务
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//3.替换Fragment
beginTransaction.replace(R.id.ll_layout,new WeixinFragment());
beginTransaction.commit();

(2)fragment之间传递值

//1.获取fragment管理者
FragmentManager fragmentManager=getActivity().getSupportFragmentManager();
//2.开启一个事务
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
//3.将ll_textshow线性布局替换为fragment,fragment之间传递值
fragmentTransaction.replace(R.id.ll_textshow,TextShowFragment.newInstance(textList),"f1"); //注意:第3个参数用于fragment之间相互传递参数
//4.提交事务
fragmentTransaction.commit();

4.Fragment的生命周期

(1)周期运行框图

(2)Fragment各个方法运行顺序测试代码

package com.example.administrator.test57wechat;


import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class WeixinFragment extends Fragment {
    @Override
    public void onAttach(Context context) {
        System.out.println("-----------onAttach");
        super.onAttach(context);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        System.out.println("-----------onCreate");
        super.onCreate(savedInstanceState);
    }

    //系统第一次画ui的时候调用
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_weixin,null);

        //测试fragment中的组件是否可以被点击
        Button bt_weixin=view.findViewById(R.id.bt_weixin);
        bt_weixin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("hello weixin");
            }
        });
        System.out.println("-----------onCreateView");
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        System.out.println("-----------onActivityCreated");
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        System.out.println("-----------onStart");
        super.onStart();
    }

    @Override
    public void onResume() {
        System.out.println("-----------onResume");
        super.onResume();
    }

    @Override
    public void onPause() {
        System.out.println("-----------onPause");
        super.onPause();
    }

    @Override
    public void onStop() {
        System.out.println("-----------onStop");
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        System.out.println("-----------onDestroyView");
        super.onDestroyView();
    }

    //fragment销毁
    @Override
    public void onDestroy() {
        System.out.println("-----------onDestroy");
        super.onDestroy();
    }

    //取消依附
    @Override
    public void onDetach() {
        System.out.println("-----------onDetach");
        super.onDetach();
    }
}

(3)测试结果

(1)初次进入一个fragment,会执行的内容

(2)离开一个fragment,进入另一个fragment

5.fragment应用实例

(1)XML代码

<1>主界面布局

采用RelativeLayout相对布局。

 android:layout_alignParentBottom="true"

设置组件对齐于父容器的底部。

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">


    <LinearLayout
        android:id="@+id/ll_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/btmain_weixin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="微信" />

        <Button
            android:id="@+id/btmain_tongxunlu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="通讯录" />

        <Button
            android:id="@+id/btmain_discover"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="发现" />

        <Button
            android:id="@+id/btmain_wo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="我" />
    </LinearLayout>

</RelativeLayout>

<2>fragment_weixin.xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是weixin模块" />

    <Button
        android:id="@+id/bt_weixin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="测试weixin内容传递" />

    <LinearLayout
        android:id="@+id/ll_textshow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

    </LinearLayout>

</LinearLayout>

<3>fragment_textshow.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_textshowfragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView" />
</LinearLayout>

(2)java后台代码

<1>MainActivity.java

package com.example.administrator.test57wechat;

import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btmain_weixin=findViewById(R.id.btmain_weixin);
        Button btmain_tongxunlu=findViewById(R.id.btmain_tongxunlu);
        Button btmain_wo=findViewById(R.id.btmain_wo);
        Button btmain_discover=findViewById(R.id.btmain_discover);
        btmain_weixin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //动态替换fragment
                //1.获取Fragment的管理者
                FragmentManager fragmentManager=getSupportFragmentManager();
                //2.开启事务
                FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
                //3.替换Fragment
                beginTransaction.replace(R.id.ll_layout,new WeixinFragment());
                beginTransaction.commit();
            }
        });

        btmain_tongxunlu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //1.获取Fragment的管理者
                FragmentManager fragmentManager=getSupportFragmentManager();
                //2.开启事务
                FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
                //3.替换Fragment
                beginTransaction.replace(R.id.ll_layout,new TongxunluFragment());
                beginTransaction.commit();
            }
        });

        btmain_wo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //1.获取Fragment的管理者
                FragmentManager fragmentManager=getSupportFragmentManager();
                //2.开启事务
                FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
                //3.替换Fragment
                beginTransaction.replace(R.id.ll_layout,new WoFragment());
                beginTransaction.commit();
            }
        });

        btmain_discover.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //1.获取Fragment的管理者
                FragmentManager fragmentManager=getSupportFragmentManager();
                //2.开启事务
                FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
                //3.替换Fragment
                beginTransaction.replace(R.id.ll_layout,new DiscoverFragment());
                beginTransaction.commit();
            }
        });
    }
}

 

<2>WeixinFragment.java

package com.example.administrator.test57wechat;


import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import java.util.ArrayList;
import java.util.List;

public class WeixinFragment extends Fragment {

    ArrayList<String> textList=new ArrayList<>();

    //系统第一次画ui的时候调用
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_weixin,null);

        //测试fragment中的组件是否可以被点击
        Button bt_weixin=view.findViewById(R.id.bt_weixin);
        bt_weixin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textList.add("hello");
                textList.add("world");
                textList.add("android");
                //1.获取fragment管理者
                FragmentManager fragmentManager=getActivity().getSupportFragmentManager();
                //2.开启一个事务
                FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
                //3.将ll_textshow线性布局替换为fragment
                fragmentTransaction.replace(R.id.ll_textshow,TextShowFragment.newInstance(textList),"f1"); //注意:第3个参数用于fragment之间相互传递参数
                //4.提交事务
                fragmentTransaction.commit();
            }
        });
        System.out.println("-----------onCreateView");
        return view;
    }


}

<3>TextShowFragment.java

package com.example.administrator.test57wechat;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class TextShowFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_textshow,null);
        if (getArguments() != null) {
            String mParam1 ="";
            ArrayList<String> textlist=getArguments().getStringArrayList("param");
            for (int i = 0; i <textlist.size() ; i++) {
                mParam1=mParam1+"----"+textlist.get(i);
            }
            TextView tv =view.findViewById(R.id.tv_textshowfragment);
            tv.setText(mParam1);
        }
        return view;
    }

    public static TextShowFragment newInstance(ArrayList<String> textList) {
        TextShowFragment fragment = new TextShowFragment();
        Bundle args = new Bundle();
        //args.putString("param", String.valueOf(textList));
        args.putStringArrayList("param",textList);
        fragment.setArguments(args);
        return fragment;
    }
}

(3)效果图

 

posted @ 2019-04-10 18:17  雨后观山色  阅读(761)  评论(0编辑  收藏  举报