Fragment

Posted 故意的是吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Fragment相关的知识,希望对你有一定的参考价值。

 在android3.0中引入了Fragments的概念,主要目的是用在大屏幕设备上(如平板电脑),支持更多动态和灵活的UI设计。利用平板电脑的大屏幕,放入更多UI组件,组件之间会产生更多的交互。

Fragment在应用中应当是一个模块化和可重用的组件,因为Fragment定义了它自己的布局,以及通过使用它自己的生命周期回调方法定义了自己的行为,可以将Fragment包含到多个Activity中

知识概括:可以理解为Activity是一座房子,Fragment是其中一个房间样式

1、Fragment可以作为Activity界面的一部分组成出现

2、可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用

3、在Activity运行过程中,可以添加、移除、替换Fragment

4、Fragment可以响应自己的输入事件,并且有自己的生命周期。他们的生命周期会受宿主Activity的生命周期影响。


onCreateView()方法

Fragment第一次绘制它的用户界面的时候,系统会调用此方法,为了绘制Fragment的UI,此方法必须返回一个View。如果不显示UI,则返回null即可。


加载方式:

1、静态加载

    在Activity的layout文件中生命Fragment,需要注意<fragment>中的android:name属性指定了再layout中实例化的Fragment类。

            标示Fragment的方法:

                     android:id 属性一共一个唯一的ID

                     android:tag属性提供了唯一的字符串

例1:

新建fragment1.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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is fragment 1"
        android:textSize="30sp"/>

</LinearLayout>
新建fragment2.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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is fragment 2"
        android:textSize="30sp"/>
</LinearLayout>
修改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="com.bcp.fragmenttest.MainActivity">

    <fragment
        android:name="com.bcp.fragmenttest.Fragment1"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:id="@+id/fragment1"/>
    <fragment
        android:name="com.bcp.fragmenttest.Fragment2"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:id="@+id/fragment2"/>
</LinearLayout>
新建Fragment1.java

package com.bcp.fragmenttest;

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

/**
 * Created by super on 2016/4/26.
 */
public class Fragment1 extends Fragment 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        return inflater.inflate(R.layout.fragment1, container, false);
    

新建Fragment2.java

package com.bcp.fragmenttest;

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

/**
 * Created by super on 2016/4/26.
 */
public class Fragment2 extends Fragment 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        return inflater.inflate(R.layout.fragment2,container,false);
    
修改MainActivity.java
package com.bcp.fragmenttest;

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

public class MainActivity extends AppCompatActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    

运行效果:



2、动态加载

撰写代码将Fragment添加到一个Activity layout中,

add() 添加一个Fragment(指定要添加的Fragment和插入的View)

类似的还有remove()、替换()

处理Fragment事务:根据用户的情况,对Fragment进行添加、移除、替换,以及执行其他动作,提交给Activity的每一套变化被称为一个事务。

FragmentManager  fragmentManager = getFragmentManager ();

FragmentTransaction  beginTransaction = fragmetnManager.beginTransaction();

每一个事务都是同时执行的一套变化,可以在一个事务中设置你所有想执行的变化,包括add()、remove()、replace()。然后提交给Activity,必须调用commit()方法

如果允许用户通过按下BACK键返回到前一个Fragment状态,调用commit()之前可以加入addToBackStack()方法


动态加载Fragment主要分4步:

1、获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到;

2、开启一个事务,通过调用beginTransaction方法开启;

3、向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的实例;

4、提交事务,使用commit方法提交。

例2:

在例1基础上做修改,横屏显示fragment1、竖屏显示fragment2

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="com.bcp.fragmenttest.MainActivity"
    android:id="@+id/main_layout"
    android:orientation="horizontal">


</LinearLayout>
ManiActivity.java
package com.bcp.fragmenttest;

import android.app.Activity;
import android.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Display;

public class MainActivity extends Activity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取屏幕宽度和高度
        Display display=getWindowManager().getDefaultDisplay();
        //宽度大于高度
        if (display.getWidth()>display.getHeight())
            //加载fragment1
            Fragment1 fragment1=new Fragment1();
            getFragmentManager().beginTransaction().replace(R.id.main_layout,fragment1).commit();
        else
            //高度大于宽度,加载fragment2
            Fragment2 fragment2=new Fragment2();
            getFragmentManager().beginTransaction().replace(R.id.main_layout,fragment2).commit();
        
    

生命周期:

重要方法 --  

 onAttach() Fragment和Activity建立关联的时候调用

onCreateView() 为Fragment加载布局时调用

onActivityCreate() 当Activity中的onCreate执行完后调用

onDestroyView() Fragment中的布局被移除时调用

onDetach() Fragment和Activity解除关联的时候调用


启动程序:

onAttach()---onCreate()---onCreateView()---onActivityCreated()---onStart()---onResume()


点击home键时:

onPause()---onStop()


再次进入程序:

onStart()---onResume()


按back推出程序:

onPause()---onStop()---onDestroyView()---onDestroy()---onDetach()


Fragment之间进行通信:

例3:

在例1基础上修改

fragment2.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="#00f">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is fragment 2"
        android:textSize="30sp"/>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Get fragment1 text"/>
</LinearLayout>

fragment1.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="#00c020">
    <TextView
        android:id="@+id/fragment1_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is fragment 1"
        android:textSize="30sp"/>


</LinearLayout>

Fragment2.java

package com.bcp.fragmenttest;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by super on 2016/4/26.
 */
public class Fragment2 extends Fragment 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        return inflater.inflate(R.layout.fragment2,container,false);
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);
        //getActivity()方法获取自身关联的Activity
        Button button= (Button) getActivity().findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                TextView textView= (TextView) getActivity().findViewById(R.id.fragment1_text);
                Toast.makeText(getActivity(), textView.getText(), Toast.LENGTH_SHORT).show();
            
        );
    

效果:点击button弹出提示信息




以上是关于Fragment的主要内容,如果未能解决你的问题,请参考以下文章

Fragment的生命周期

为啥popbackstack会调用fragment的onCreateView?

fragment生命周期

Fragment实践————简易版新闻应用

片段:按下返回按钮并自定义它时调用哪个回调

在 Activity 中调用 Fragment 方法会导致空指针异常