Fragment详解

一、什么是Fragment,为什么它会被称为第五大组件

Fragment是一个模块化和可重用的组件, 目的是为了解决不同屏幕分辩率的动态和灵活UI设计。 

Fragment之所以被称为第五大组件是因为它比Activity更节省内存,其切换模式也更加舒适,使用频率不低于四大组件,且有自己的生命周期,但是必须依附于Activity。

Fragment的优点可以具体整理为如下几点:

  1. Fragment 可以将 Activity 分离成多个可重用的组件,每个都有它自己的生命周期和 UI。
  2. Fragment可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑,在不同的安卓设备上统一你的UI。
  3. Fragment是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。
  4. Fragment解决Activity之间的切换不流畅,轻量切换。
  5. Fragment替换TabActivity做导航性能更好。

二、Fragment静态加载怎么用

首先我们需要先创建一个Fragment:


我们要注意,上图中标记的两个方框不要勾选

Fragment创建好了之后,使用方法在下图:


我们只需要在activity的xml文件中用fragment这样写,那么创建出来的fragment就被静态加载到了activity了

图中的name后面写的就是创建的fragment的名字,然后我们还需要给它起一个id,这样简单的fragment的静态加载就算完成了

三、Fragment的动态加载

你已经学会了如何在XML中使用Fragment,但是这仅仅是Fragment最简单的功能而已。Fragment真正的强大之处在于可以动态地添加到Activity当中,因此这也是你必须要掌握的东西。当你学会了在程序运行时向Activity添加Fragment,程序的界面就可以定制的更加多样化。下面我们立刻来看看,如何动态添加Fragment。
       首先,我创建了三个背景颜色不同的fragment:

<FrameLayout 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"
    android:background="#66bb99"
    tools:context="com.example.paopao.fragment.DianhuaFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>
<FrameLayout 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"
    android:background="#00aa88"
    tools:context="com.example.paopao.fragment.DuanxinFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>
<FrameLayout 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"
    android:background="#33bb44"
    tools:context="com.example.paopao.fragment.LianxirenFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/联系人" />

</FrameLayout>
MainActivity的xml文件:

<?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="com.example.paopao.fragment.Main3Activity">

    <FrameLayout
        android:id="@+id/frame"
        android:layout_margin="5dp"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9">
    </FrameLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:id="@+id/lainxiren"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="联系人"/>
        <Button
            android:id="@+id/dianhua"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="电话"/>
        <Button
            android:id="@+id/duanxin"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="短信"/>
    </LinearLayout>
</LinearLayout>
主界面上有三个按钮和一个FrameLayout布局,这三个按钮分别用于FrameLayout加载三个Fragment的实例。
效果图如下:

MainActivity里面是这样的:

package com.example.paopao.fragment;

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

import com.example.paopao.R;

public class Main3Activity extends AppCompatActivity implements View.OnClickListener{
    private Button lianxiren;
    private Button duanxin;
    private Button dianhua;

    private FragmentManager fragmentManager;
    private FragmentTransaction fragmentTransaction;
    private LianxirenFragment lianxirenFragment;
    private DianhuaFragment dianhuaFragment;
    private DuanxinFragment duanxinFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        bind();
        fragmentManager=getFragmentManager();
    }

    private void bind() {
        lianxiren=findViewById(R.id.lainxiren);
        duanxin=findViewById(R.id.duanxin);
        dianhua=findViewById(R.id.dianhua);
        lianxiren.setOnClickListener(this);
        duanxin.setOnClickListener(this);
        dianhua.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        fragmentTransaction=fragmentManager.beginTransaction();
        switch (view.getId()){
            case R.id.lainxiren:
                if(lianxirenFragment==null){
                    lianxirenFragment=new LianxirenFragment();
                }
                fragmentTransaction.replace(R.id.frame,lianxirenFragment);
                break;
            case R.id.dianhua:
                if(dianhuaFragment==null){
                    dianhuaFragment=new DianhuaFragment();
                }
                fragmentTransaction.replace(R.id.frame,dianhuaFragment);
                break;
            case R.id.duanxin:
                if(duanxinFragment==null){
                    duanxinFragment=new DuanxinFragment();
                }
                fragmentTransaction.replace(R.id.frame,duanxinFragment);
                break;
                default:
                    break;
        }
        fragmentTransaction.commit();
    }
}

看上面的代码很容易明白,在点击按钮时主要做了这样的操作的操作:

FragmentManager manager = getSupportFragmentManager();  
FragmentTransaction transaction = manager.beginTransaction();  
Fragment1 fragment1 = new Fragment1();  
transaction.add(R.id.fragment_container, fragment1);  
transaction.commit(); 

动态添加Fragment主要分为4步:

  1. .获取到FragmentManager,在V4包中通过getSupportFragmentManager,在系统中原生的Fragment是通过getFragmentManager获得的。
  2. 开启一个事务,通过调用beginTransaction方法开启。
  3. .向容器内加入Fragment,一般使用add或者replace方法实现,需要传入容器的id和Fragment的实例。
  4. 提交事务,调用commit方法提交。

四、ViewPager+Fragment实现页卡滑动

首先我先创建三个fragment

chatfragment:

<FrameLayout 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"
    android:background="#9999"
    tools:context="com.example.paopao.vp.ChatFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

FriendFragment:


<FrameLayout 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"
    android:background="#654321"
    tools:context="com.example.paopao.vp.FriendFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

HelloFragment:

<FrameLayout 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"
    android:background="#ba4561"
    tools:context="com.example.paopao.vp.HelloFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>
MyviewpagerActivity:
package com.example.paopao.vp;


import android.graphics.Color;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import com.example.paopao.R;

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

public class MyviewpagerActivity extends AppCompatActivity implements View.OnClickListener{

    private ChatFragment chatFragment;
    private FriendFragment friendFragment;
    private HelloFragment oFragment;
    private List<Fragment> fragmentList=new ArrayList<>();
    private MyvpAdapater adapater;
    private ViewPager viewPager;

    private TextView one;
    private TextView two;
    private TextView three;

    private TextView one_view;
    private TextView two_view;
    private TextView three_view;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_myviewpager);

        viewPager=findViewById(R.id.my_vp);
        one=findViewById(R.id.one);
        two=findViewById(R.id.two);
        three=findViewById(R.id.three);
        one_view=findViewById(R.id.one_view);
        two_view=findViewById(R.id.two_view);
        three_view=findViewById(R.id.three_view);

        one.setOnClickListener(this);
        two.setOnClickListener(this);
        three.setOnClickListener(this);



        chatFragment=new ChatFragment();
        friendFragment=new FriendFragment();
        oFragment=new HelloFragment();

        fragmentList.add(friendFragment);
        fragmentList.add(chatFragment);
        fragmentList.add(oFragment);
        adapater=new MyvpAdapater(getSupportFragmentManager(),fragmentList);

        viewPager.setAdapter(adapater);
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {


            }

            @Override
            public void onPageSelected(int position) {
                one_view.setBackgroundColor(Color.WHITE);
                two_view.setBackgroundColor(Color.WHITE);
                three_view.setBackgroundColor(Color.WHITE);
                switch (position){
                    case 0:
                        one_view.setBackgroundColor(Color.BLACK);
                        break;
                    case 1:
                        two_view.setBackgroundColor(Color.BLACK);
                        break;
                    case 2:
                        three_view.setBackgroundColor(Color.BLACK);
                        break;
                        default:
                            break;
                }
            }
            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    @Override
    public void onClick(View view) {

        switch (view.getId()){
            case R.id.one:
                viewPager.setCurrentItem(0);
                break;
            case R.id.two:
                viewPager.setCurrentItem(1);
                break;
            case R.id.three:
                viewPager.setCurrentItem(2);
                break;
                default:
                    break;
        }
    }
}

下面一个是PagerAdapater适配器:

package com.example.paopao.vp;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

/**
 * Created by 龙波 on 2018/6/5.
 */

public class MyvpAdapater extends FragmentPagerAdapter{
    private List<Fragment> fragmentList;

    public MyvpAdapater(FragmentManager fm,List<Fragment> fragmentList) {
        super(fm);
        this.fragmentList=fragmentList;
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }
}

五、Fragment生命周期

Fragment每个生命周期方法的意义及作用:
setUserVisibleHint():设置Fragment可见或者不可见时会调用此方法。在该方法里面可以通过调用getUserVisibleHint()获得Fragment的状态是可见还是不可见的,如果可见则进行懒加载操作。
onAttach():执行该方法时,Fragment与Activity已经完成绑定,该方法有一个Activity类型的参数,代表绑定的Activity,这时候你可以执行诸如mActivity = activity的操作。
onCreate():初始化Fragment。可通过参数savedInstanceState获取之前保存的值。
onCreateView():初始化Fragment的布局。加载布局和findViewById的操作通常在此函数内完成,但是不建议执行耗时的操作,比如读取数据库数据列表。
onActivityCreated():执行该方法时,与Fragment绑定的Activity的onCreate方法已经执行完成并返回,在该方法内可以进行与Activity交互的UI操作,所以在该方法之前Activity的onCreate方法并未执行完成,如果提前进行交互操作,会引发空指针异常。
onStart():执行该方法时,Fragment由不可见变为可见状态。
onResume():执行该方法时,Fragment处于活动状态,用户可与之交互。
onPause():执行该方法时,Fragment处于暂停状态,但依然可见,用户不能与之交互。
onSaveInstanceState():保存当前Fragment的状态。该方法会自动保存Fragment的状态,比如EditText键入的文本,即使Fragment被回收又重新创建,一样能恢复EditText之前键入的文本。
onStop():执行该方法时,Fragment完全不可见。
onDestroyView():销毁与Fragment有关的视图,但未与Activity解除绑定,依然可以通过onCreateView方法重新创建视图。通常在ViewPager+Fragment的方式下会调用此方法。
onDestroy():销毁Fragment。通常按Back键退出或者Fragment被回收时调用此方法。
onDetach():解除与Activity的绑定。在onDestroy方法之后调用。

Fragment生命周期执行流程(注意红色的不是生命周期方法):
Fragment创建:setUserVisibleHint()->onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume();
Fragment变为不可见状态(锁屏、回到桌面、被Activity完全覆盖):onPause()->onSaveInstanceState()->onStop();
Fragment变为部分可见状态(打开Dialog样式的Activity):onPause()->onSaveInstanceState();
Fragment由不可见变为活动状态:onStart()->OnResume();
Fragment由部分可见变为活动状态:onResume();
退出应用:onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()(注意退出不会调用onSaveInstanceState方法,因为是人为退出,没有必要再保存数据);
Fragment被回收又重新创建:被回收执行onPause()->onSaveInstanceState()->onStop()->onDestroyView()->onDestroy()->onDetach(),重新创建执行onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->setUserVisibleHint();
横竖屏切换:与Fragment被回收又重新创建一样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值