Android Fragment之间的通信

本文介绍了Android中的Fragment,包括它的作用、生命周期,并详细讲解了静态和动态Fragment的使用方法。重点探讨了Fragment之间的通信,提供了从Fragment到Activity以及反之的交互示例,帮助开发者掌握Fragment在UI设计和应用开发中的灵活运用。
摘要由CSDN通过智能技术生成

1.Fragment 的概述

(1)Fragment是什么

 我们都知道,Fragment的翻译可以译为:碎片、片段。在Android开发中引入这一概念的目的是为

了解决不同安卓设备屏幕分辩率不同的问题,引入Fragment碎片技术,可以实现动态和灵活的UI

计,软件工程师们不需要再对同一款软件进行多次的适应性开发,以便于适应不同屏幕分辨率的安卓设备。

我们可以将Fragment看作是Acitivity的一部分,甚至可以说,整个Activity就是由不同的Fragment组成。更

具有吸引力的是,Fragment有着自己的生命周期和各种处理事件的函数,也就是说,我们不必再将所有的事

件处理都写在Activity中,只需要有一个Fragment专门去处理即可。

(2)Fragment的生命周期

 Fragment必须是依存于Activity的,Fragment的生命周期很大程度上受制于Activity。这里放上一张官

网提供的Activity与Fragment生命周期关系说明图。


生命周期的对比说明

从图中我们可以看到,在Activity创建时,Fragment也同时被创建,但是Fragment的创建是分为好几步的

onAttach();  //当Activity与Fragment关联时调用

onCreate(); //创建Fragment时调用

onCreateView();  //创建该Fragment的视图

onActivityCreate();  //当Activity的onCreate()方法返回时调用

onDestoryView();  //与onCreateView相对应,当改Fragment被移除时调用

onDestory(); //销毁Fragment时调用

onDetach();  //与onAttach()相对应,当Fragment与Activity的关联被取消时调用

2.静态Fragment 和 动态Fragment

静态Fragment是Fragment最简单的使用方法。我们将主布局文件中加入fragment布局就可,这里我们是将

fragment直接当作一个控件来使用的。

动态Fragment,我们不需要再将fragment的布局文件事先放入主布局中,而是,当我们需要用到的时候,

通过代码,动态的进行加入。

这里有以下几个注意事项:

1.注意每一个fragment的布局都要有一个与之对应的继承于Fragment的类(我们在这里对fragment与activity进行绑定和关联)。

2.关于继承.app.Fragment和.support.v4.app.Fragment的问题:

如果要使用前者,那么MainActivity继承Activity即可,然后动态添加时,是getFragmetManager();

如果使用后者,那么MainActivity要继承FragActivty,然后动态添加时,是getSupportFragmentManager();

3.Fragment 之间的简单通信

在了解了Fragment的基本知识之后,我们最关心的还是Fragment之间是如何进行通信的。如何从一个

fragment向宿主activity发送请求,又如何从activity向fragment发送请求是我们这一节讲述的重点。

首先,我们创建一个Android项目,命名为Fragment。

在Activity.xml文件下,进行如下布局的编写:

<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"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/et1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="我是activity啊" />

    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#76EE00"
        android:text="发送信息到左" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#7171C6"
        android:text="发送信息到右" />

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

        <LinearLayout
            android:id="@+id/left_Fragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#FF3E96"
            android:orientation="vertical" >
        </LinearLayout>

        <LinearLayout
            android:id="@+id/right_Fragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#98F5FF"
            android:orientation="vertical" >
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

左fragment,left.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" >

    <EditText
        android:id="@+id/left_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="我是左啊" />
    <Button
        android:id="@+id/left_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送信息到activity" />
    <Button
        android:id="@+id/left_btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送信息到右" />
</LinearLayout>

右fragment,right.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" >

    <EditText
        android:id="@+id/right_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="我是右啊" />

    <Button
        android:id="@+id/right_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送信息到activity" />

    <Button
        android:id="@+id/right_btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送信息到左" />
</LinearLayout>

效果图如下所示:
这里写图片描述
以上我们只是完成了UI布局的编写,以及Fragment碎片的位置,例子中我一共定义了两个碎片,接下来要做的就是让碎片与宿主Activity相关联(这里任意Activity均可)。我们之前提到过,每一个fragment的布局都要有一个与之对应的继承于Fragment的类,以此来进行Fragment的布局绑定和关联必要的Activity,所以,我们必须先定义Fragment的继承类,具体代码如下所示。
左fragment的继承类:

/**LeftFragment.java**/

package com.skylake.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;


public class LeftFragment extends Fragment {

    EditText Left_et;
    Button Left_btn;
    Button Left_btn2;
    TransData td;
    TransDataToRight tdtr;
    //Fragment与Activity关联后调用
    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
        td = (TransData) activity;
        tdtr = (TransDataToRight) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        // inflate()的作用就是将一个用xml定义的布局文件查找出来,
        // 注意与findViewById()的区别,inflate是加载一个布局文件,
        // 而findViewById则是从布局文件中查找一个控件。
        // 关于LayoutInflater类
        // inflate(int resource, ViewGroup root, boolean attachToRoot)方法三个参数的含义
        // resource:加载的XMl布局资源ID
        // root:生成的分层视图的父对象(如果attachToRoot为true),或者是一个简单的提供了一系列布局参数生成的Veiw对象(如果attachToRoot为false)
        // attachToRoot:是否要填充的分层视图要添加到父对象中,如果为false。ROOT内容仅仅是初始化,如果要使用,仍需要手动添加。
        return inflater.inflate(R.layout.left, null);
    }

    /**
     * public void onViewCreated(View view, Bundle savedInstanceState)
     * onCreateView(LayoutInflater, ViewGroup, Bundle)
     * 方法返回之后、之前被保存的View对象的状态被恢复之前,系统会立即调用该方法。
     * 这样就给子类在了解自己所在的View层次树被完全被创建的情况,提供初始化自己的机会。
     * 在这个时点,Fragment对象的View层次树还没有跟它的父对象绑定。
     * 
     * 参数 view 通过onCreateView(LayoutInflater, ViewGroup, Bundle)方法返回的View对象。
     * savedInstanceState 如果该参数是非空的(non-null),那么该Fragment对象要使用这个参数中的状态来进行重建。
     */

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);
        Left_et = (EditText) view.findViewById(R.id.left_et);
        Left_btn = (Button) view.findViewById(R.id.left_btn);
        Left_btn2 = (Button) view.findViewById(R.id.left_btn2);
        Left_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                td.setData(Left_et.getText().toString());
            }
        });
        Left_btn2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tdtr.setDataToRight(Left_et.getText().toString());
            }
        });
    }

    public void setData(String data) {
        Left_et.setText(data);
    }
    public interface TransData{
        public void setData(String str);
    }
    public interface TransDataToRight{
        public void setDataToRight(String str);
    }

}

右fragment的继承类:

/**RightFragment.java**/

package com.skylake.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class RightFragment extends Fragment {

    EditText Right_et;
    Button right_btn;
    Button right_btn2;
    TransDataX tdx;
    TransDataToLeft tdtl;

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
        tdx = (TransDataX) activity;
        tdtl = (TransDataToLeft) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.right, null);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);

        Right_et = (EditText) view.findViewById(R.id.right_et);
        right_btn = (Button) view.findViewById(R.id.right_btn);
        right_btn2 = (Button) view.findViewById(R.id.right_btn2);
        right_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tdx.setData(Right_et.getText().toString());

            }
        });
        right_btn2 = (Button) view.findViewById(R.id.right_btn2);
        right_btn2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tdtl.setDataToLeft(Right_et.getText().toString());
            }
        });

    }

    public void setData(String str) {
        Right_et.setText(str);
    }

    public interface TransDataX {
        public void setData(String str);
    }

    public interface TransDataToLeft {
        public void setDataToLeft(String str);
    }
}

定义好之后,我们便可以在Activity中进行碎片绑定了,具体代码如下所示。

package com.skylake.fragment;

import com.skylake.fragment.LeftFragment.TransData;
import com.skylake.fragment.LeftFragment.TransDataToRight;
import com.skylake.fragment.RightFragment.TransDataToLeft;
import com.skylake.fragment.RightFragment.TransDataX;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements TransData,TransDataToRight,TransDataToLeft,TransDataX{

    LeftFragment lFragment;   //定义左侧碎片的对象
    RightFragment rFragment;  //定义右侧碎片的对象
    EditText et1;             //初始化一些输入和输出控件
    Button btn1;
    Button btn2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建Fragment对象,等待与Activity进行关联
        lFragment = new LeftFragment();
        rFragment = new RightFragment();

        //关联操作,即将Fragment嵌入此Activity中
        FragmentManager fManger = getFragmentManager();
        FragmentTransaction ft = fManger.beginTransaction();
        ft.replace(R.id.left_Fragment, lFragment);
        ft.replace(R.id.right_Fragment, rFragment);
        ft.commit(); //注意,我们动态绑定时,需要提交操作

        et1 = (EditText) findViewById(R.id.et1);
        btn1 = (Button) findViewById(R.id.btn1);
        btn2 = (Button) findViewById(R.id.btn2);
        btn1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                //当Fragment与Activity关联后,Fragment便成为此Activity中的一部分
                //所以,我可以通过Fragment对象,来调用其内部的方法
                lFragment.setData(et1.getText().toString());

            }
        });
        btn2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                rFragment.setData(et1.getText().toString());

            }
        });

    }
    /**
     * 接口中的函数可以重复定义。多个接口实现了同一种功能,那么我们只需要定义一个公用的接口方法即可
     * 实现Fragment与Activity通信时,定义的接口
     */
    @Override
    public void setData(String str) {
        // TODO Auto-generated method stub
        et1.setText(str);
    }

    @Override
    public void setDataToRight(String str) {
        // TODO Auto-generated method stub
        rFragment.setData(str);
    }

    @Override
    public void setDataToLeft(String str) {
        // TODO Auto-generated method stub
        lFragment.setData(str);
    }

}

附上一张效果图吧~~
效果图
这里就大功告成啦~ 之后我会提供源码,供大家免费下载参考。

点击下载喔~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值