我的Android之旅(七)--Fragment及其生命周期


Fragment

Android是在Android 3.0 (API level 11)开始引入Fragment的。

可以把Fragment想成Activity中的模块,这个模块有自己的布局,有自己的生命周期,单独处理自己的输入,在Activity运行的时候可以加载或者移除Fragment模块。

可以把Fragment设计成可以在多个Activity中复用的模块。

当第一次绘制Fragment的UI时系统调用onCreateView()方法,必须返回一个View,如果Fragment不提供UI也可以返回null。

注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。

Fragment有两种加载方式:一种是在Activity的layout中使用标签<fragment>声明;另一种方法是在代码中把它加入到一个指定的ViewGroup中。

另外,Fragment它可以并不是Activity布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。

加载方式1:通过Activity的布局文件将Fragment加入Activity

在Activity的布局文件中,将Fragment作为一个子标签加入即可。


Fragment 和Activity之间的在通信
1.在Fragment 中声明一个接口
2.在Activity中实现Fragment声明的接口
3.在Fragment中声明一个接口对象
4.在Fragment的生命周期Onattch方法中判断当前Activity是否实现了此
Fragment中声明的接口。如果已经实现,就把当前Activity转化为接口对象。
5.调用Activity中实现的方法。=》(接口对象.方法名)
(谨记上述的步骤,有助于理解)
下面我们就通过代码具体的了解Fragment

首先建立一个包,专门存放Fragment的文件:

依据下图的步骤来新建需要的Fragment。
下面就是Fragment简单的引用
Fragment1Activity
package com.jerehedu.jerduech07;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;

import com.jerehedu.jerduech07.fragment.FirstFragment;
import com.jerehedu.jerduech07.fragment.LeftFragment;
import com.jerehedu.jerduech07.fragment.SecondFragment;

public class Fragment1Activity extends AppCompatActivity implements LeftFragment.OnFragmentInteractionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment1);
        getSupportActionBar().hide();
    }
    @Override
    public void changeFragment(int which) {
        if(which==1){
            Fragment fragment1=new FirstFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.fl,fragment1)
                    .commit();
        }else if (which==2){
            Fragment fragment2=new SecondFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.fl,fragment2).commit();
        }
    }
}

对应的布局文件:Fragment1_Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.jerehedu.jerduech07.Fragment1Activity">
<fragment
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:name="com.jerehedu.jerduech07.fragment.TopFragment"
    android:id="@+id/top_fragment"/>
    <!--对fragment静态的引用-->
    <fragment
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:id="@+id/left_fragment"
        android:name="com.jerehedu.jerduech07.fragment.LeftFragment"
        android:layout_below="@+id/top_fragment" />
    <!--<fragment-->
        <!--android:layout_width="300dp"-->
        <!--android:layout_height="match_parent"-->
        <!--android:id="@+id/main_fragment"-->
        <!--android:name="com.jerehedu.jerduech07.fragment.MainFragment"-->
        <!--android:layout_below="@+id/top_fragment"-->
        <!--android:layout_toEndOf="@+id/left_fragment" />-->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fl"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/top_fragment"
        android:layout_toEndOf="@+id/left_fragment">
    </FrameLayout>
</RelativeLayout>


接下来的三个Fragment文件是Fragment1activity内所引用到的所有文件:

(1)

FristFragment:
package com.jerehedu.jerduech07.fragment;


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

import com.jerehedu.jerduech07.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class FirstFragment extends Fragment {
    public FirstFragment() {
        // Required empty public constructor
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false);
        //将静态布局转化为V
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
       Bundle bundle= getArguments();
        if (bundle!=null){
         int ch=   bundle.getInt("channel");
            TextView tv= (TextView)getView().findViewById(R.id.tv);
            tv.setText(ch+"");
        }
    }
}

FristFragment文件对应的布局文件:

<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"
    tools:context="com.jerehedu.jerduech07.fragment.FirstFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="30sp"
        android:layout_gravity="center"
        android:text="我是fragment1"
        android:background="#b9f2c0"
        android:id="@+id/tv"/>


</FrameLayout>

(2)SecondFragment

package com.jerehedu.jerduech07.fragment;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.jerehedu.jerduech07.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class SecondFragment extends Fragment {


    public SecondFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false);
    }

}

其对应的布局文件如下:
<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"
    tools:context="com.jerehedu.jerduech07.fragment.SecondFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="我是第二个fragment"
        android:layout_gravity="center"
        android:textSize="20sp"
        android:gravity="center"
        android:id="@+id/f2"/>

</FrameLayout>

(3)
LeftFragment:
Fragment1Actuvity实现了该碎片的接口以及对应的方法
package com.jerehedu.jerduech07.fragment;


import android.content.Context;
import android.os.Bundle;
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 android.widget.Toast;

import com.jerehedu.jerduech07.R;
import com.jerehedu.jerduech07.fragmentcallback.OneFragment;

/**
 * A simple {@link Fragment} subclass.
 */
public class LeftFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

   private Fragment fragment1=new FirstFragment();
     private Fragment fragment2 = new SecondFragment();

    public LeftFragment() {
        // Required empty public constructor
    }
 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view=inflater.inflate(R.layout.fragment_left, container, false);
        Button bt1= (Button) view.findViewById(R.id.bt1);
        Button bt2= (Button) view.findViewById(R.id.bt2);
        Button bt3= (Button) view.findViewById(R.id.bt3);
        Button bt4= (Button) view.findViewById(R.id.bt4);
        Button bt5= (Button) view.findViewById(R.id.bt5);
        Button bt6= (Button) view.findViewById(R.id.bt6);
        bt1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               Toast.makeText(getContext(), "点击了按钮1", Toast.LENGTH_SHORT).show();
                //new 一个Fragment,不需要写this
                FragmentManager fm=getFragmentManager();
                FragmentTransaction fr=fm.beginTransaction();
                fr.replace(R.id.fl,fragment1);
                fr.commit();//提交
            }
        });
        bt2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "点击了第二个那妞", Toast.LENGTH_SHORT).show();
                FragmentManager fm2 = getFragmentManager();
                FragmentTransaction fr2 = fm2.beginTransaction();
                fr2.replace(R.id.fl, fragment2);
                fr2.commit();
            }
        });
        bt3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.changeFragment(1);

            }
        });
        bt4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.changeFragment(2);
            }
        });
        bt5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (fragment1!=null&&!fragment1.isHidden()){
                    getFragmentManager().beginTransaction().hide(fragment1).commit();
                }
            }
        });
        bt6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (fragment1 != null && fragment1.isHidden())
                    getFragmentManager().beginTransaction().show(fragment1).commit();
            }
        });
        return view;
    }

    @Override
    public void onAttach(Context context) {
        if (context instanceof OneFragment.OnFragmentInteractionListener){
            mListener= (OnFragmentInteractionListener) context;
        }else{
            throw new RuntimeException(context.toString()

                    +"must implement OnFragmentInteractionListener");
        }

    }

    public interface OnFragmentInteractionListener{
        void changeFragment(int which);
    }
}

其对应的布局文件
<RelativeLayout 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="#d4f905"
    tools:context="com.jerehedu.jerduech07.fragment.LeftFragment">

    <!-- TODO: Update blank fragment layout -->
    <!--<TextView-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="match_parent"-->
        <!--android:text="LeftFragment"-->
        <!--android:background="#ffff04"-->
        <!--android:textColor="#ffffff"-->
        <!--android:gravity="center"-->
        <!--android:textSize="30sp"/>-->
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="第一个Fragment"
        android:textSize="10sp"
        android:id="@+id/bt1"
        />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="第二个Fragment"
        android:textSize="10sp"
        android:id="@+id/bt2"
        android:layout_gravity="center_horizontal|top"
        android:layout_below="@+id/bt1"
        android:layout_alignParentStart="true" />
   <Button
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="第一个Back"
       android:textSize="10sp"
       android:id="@+id/bt3"
       android:layout_below="@+id/bt2"
       android:layout_alignParentStart="true" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="第二个Back"
        android:textSize="10sp"
        android:id="@+id/bt4"
        android:layout_below="@+id/bt3"
        android:layout_alignParentStart="true" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/bt5"
        android:text="隐藏Fragment1"
        android:layout_below="@+id/bt4"
        android:layout_alignParentStart="true" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/bt6"
        android:text="显示Fragment1"
        android:layout_below="@+id/bt5"
        android:layout_alignParentStart="true" />
</RelativeLayout>

运行结果如下:






Fragment2Activity文件:
package com.jerehedu.jerduech07;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;

import com.jerehedu.jerduech07.fragment.FirstFragment;
import com.jerehedu.jerduech07.fragment.SecondFragment;
import com.jerehedu.jerduech07.fragmentcallback.OneFragment;

public class Fragment2Activity extends AppCompatActivity implements OneFragment.OnFragmentInteractionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment2);
    }

    @Override
    public void changeFragment(int which) {
        if (which==1){
            Fragment fragment1=new FirstFragment();
           getSupportFragmentManager()
                   .beginTransaction()
                   .replace(R.id.fl2, fragment1)
                   .commit();

        }else if (which==2){
            Fragment fragment2=new SecondFragment();
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fl2, fragment2)
                    .commit();
        }

    }
}

其对应的布局文件为:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".Fragment2Activity">
   <fragment
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/one_Fragment"
       android:name="com.jerehedu.jerduech07.fragmentcallback.OneFragment"/>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/fl2"
        android:layout_below="@+id/one_Fragment">

    </FrameLayout>

</RelativeLayout>

所用到的其他Fragment文件见Fragment1Activity
运行结果如下:






Fragment的生命周期:

onAttach () Fragment被附加到Activity的时,调用此函数,在这个方法中可以获得宿主Activity。
onCreate () Fragment被创建的时,调用此函数。
onCreateView () Fragment的布局加载时,调用此函数。
onActivityCreated () 当宿主Activity启动完毕后,调用此函数。
onStart () 启动Fragment时,调用此函数。
onResume () Fragment恢复时,调用此函数。
onPause () Fragment暂停时,调用此函数。
onStop() Fragment停止时,调用此函数。
onDestroyView() 销毁Fragment中的View控件时,调用此函数。
onDestroy() 销毁Fragment时,调用此函数。
onDetach() Fragment从Activity脱离时,调用此函数




下面俩个实例演示了Fragment和Activity各自生命周期的关系,以及运行的规律:

Fragment:生命周期
package com.jerehedu.jerduech07.fragment;


import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.jerehedu.jerduech07.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class LifeFragment extends Fragment {
    private TextView tv;
    public LifeFragment() {
        // Required empty public constructor
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("====LifeFragment===","onAttach");
        //Fragment附加到Activity
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("====LifeFragment===", "onCraet");
        //Fragment被创建
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
  //       Inflate the layout for this fragment
        View view=inflater.inflate(R.layout.fragment_life,container,false);
        return view;

    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d("====LifeFragment===", "onActivityCreated");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d("====LifeFragment===", "onStart");
    }
    @Override
    public void onResume() {
        super.onResume();
        Log.d("====LifeFragment===", "onResume");
    }
    @Override
    public void onPause() {
        super.onPause();
        Log.d("====LifeFragment===", "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("====LifeFragment===", "onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("====LifeFragment===", "onDestroyView");
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("====LifeFragment===", "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("====LifeFragment===", "onDetach");
        //和Attach相反,从Activity脱离
    }



}

Activity:生命周期
package com.jerehedu.jerduech07;

import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.jerehedu.jerduech07.fragment.FirstFragment;
import com.jerehedu.jerduech07.fragment.LifeFragment;

public class FragmentLifeActivity extends AppCompatActivity {
    final Fragment fragment=new LifeFragment();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_life);
        getSupportActionBar().hide();
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.life_frame, fragment).commit();
        final Button bt1= (Button) findViewById(R.id.bt_remove);
        Button bt2= (Button) findViewById(R.id.bt_replace);
        Button bt3= (Button) findViewById(R.id.bt_hide);
        Button bt4= (Button) findViewById(R.id.bt_show);

        bt1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (fragment!=null) {
                    getSupportFragmentManager().beginTransaction()
                            .remove(fragment).commit();
                }
            }
        });
        bt2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (fragment!=null) {
                    Fragment fragment1=new FirstFragment();
                   //捆绑数据  Bundle
                    Bundle bundle=new Bundle();
                    bundle.putInt("channel",66);
                    fragment1.setArguments(bundle);
                    //赋值


                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.life_frame, fragment1).commit();
                }

            }
        });
bt3.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (fragment!=null&&!fragment.isHidden()){
            getSupportFragmentManager().beginTransaction().hide(fragment).commit();
        }
    }
});
        bt4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (fragment!=null&&fragment.isHidden()){
                    getSupportFragmentManager().beginTransaction().show(fragment).commit();
                }

            }
        });

        getSupportFragmentManager().beginTransaction()
                .replace(R.id.life_frame, fragment).commit();

        Log.d("====Activity===","onCreat");
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.d("====Activity===", "onStart");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("====Activity===", "onCreat");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("====Activity===", "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("====Activity===", "onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("====Activity===", "onStop");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("====Activity===", "onDestroy");
    }
}

1.点击运行后各个生命周期运行的情况:


2.点击回退键时各个生命周期运行状况



3.点击HOME键各个生命周期运行状况:


且该程序还可实现下面的界面:


点击按钮remove  --fragment




点击 replace  --fragment:



hide--fragment



show --fragment:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值