Android开发教程之Fragment定义、创建与使用方法详解【包含Activity通讯,事务执行等】

yizhihongxing

Android开发教程之Fragment定义、创建与使用方法详解

Fragment是Android平台中一种重要的组件类型,用于在活动中展示多个页面。本文将详细介绍Fragment的定义、创建、使用以及如何实现Fragment和Activity之间的通讯,同时还会讨论如何在Fragment中执行事务。

Fragment的定义和创建

定义Fragment

Fragment是一种用户界面组件,可以被插入到一个Activity中,属于该Activity的一部分。它能够独立的执行交互操作、添加或移除。因此,常把Fragment比喻为“Activity的模块”或者“Activity内的子Activity”。

定义一个Fragment,需要继承android.app.Fragment或者android.support.v4.app.Fragment类。

public class ExampleFragment extends Fragment {

}

在Fragment中完成界面布局,是很重要的步骤,通过重写onCreateView方法实现。

public class ExampleFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        //加载fragment布局
        View view = inflater.inflate(R.layout.fragment_example, container, false);
        return view;
    }
}

创建Fragment

Fragment的创建,必须依存在一个Activity当中。具体步骤分为以下几步:

1.定义Fragment布局

在创建一个Fragment前,我们先定义Fragment的布局,例如我们定义一个简单的TextView,布局文件名为“fragment_example.xml”:

<TextView
    android:id="@+id/tv_example"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="This is an example fragment"/>

2.创建Fragment

通过FragmentManager.beginTransaction()方法获取一个FragmentTransaction对象,可用于添加、移除或替换Fragment。用户可以使用add()方法将一个Fragment添加到Activity当中。

ExampleFragment exampleFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, exampleFragment);
transaction.commit();

在上述代码中,我们通过实例化ExampleFragment对象,再通过FragmentTransaction.add()方法加入Activity当中。

3.将Fragment添加到Activity当中

在上一步中,我们把Fragment的显示容器放置在Activity中。因此,用户可以通过XML来定义Fragment的显示容器,例如下面的例子:

<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</FrameLayout>

when we add Fragment,我们需要指定容器id与Fragment映射

transaction.add(R.id.fragment_container, exampleFragment);

使用Fragment

在创建了Fragment并将其添加到Activity中之后,我们可以直接通过FragmentManager.findFragmentById()或者FragmentManager.findFragmentByTag()方法获取该Fragment,并使用该对象来执行相应的操作。

ExampleFragment fragment = (ExampleFragment)getSupportFragmentManager().findFragmentById(R.id.form_bottom_sheet);

使用findFragmentById方法用来找到之前我们定义的fragment_container视图中的Fragment。

如同Activity一样,Fragment也有生命周期的概念,重写对应的生命周期方法可以实现Fragment对应状态的监听或者处理:

生命周期 描述
onAttach() 当Fragment被添加到Activity时调用
onCreate() 当Fragment被创建时调用
onCreateView() 创建Fragment的布局时调用,该方法必须返回一个View,该view即显示在activity中的Fragment布局
onActivityCreated 当 Fragment 所在的Activity 完成了其 onCreate() 生命周期后,调用该方法,可以获取所有的 view 资源
onResume() 当Fragment对用户可见时调用,Fragment进入前台,从后台返回
onPause() 当Fragment不再对用户可见时调用,Fragment前台退至后台
onStop() 当Fragment被退到栈顶面之后调用
onDestroyView() 当Fragment被销毁或与Activity的关联被切断时触发
onDestroy() 当Fragment被销毁时调用
onDetach() 当Fragment与Activity脱离关联时调用

Fragment和Activity交互

在Fragment中获取Activity的引用

当Fragment作为Activity的子组件运行时,可以通过getActivity()方法获得Activity对象的引用。在Fragment中获取Activity对象的引用示例如下:

public class ExampleFragment extends Fragment {
    private MainActivity mainActivity;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof MainActivity) {
            mainActivity = (MainActivity) context;
        } else {
            throw new IllegalArgumentException("Activity must instanceof MainActivity");
        }
    }

    @Nullable
     @Override
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.fragment_example, container, false);
         final TextView textView = (TextView)view.findViewById(R.id.tv_example);
         textView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 mainActivity.changeText("change text from Fragment");
             }
         });
         return view;
     }
}

在上述代码中,在Fragment中声明了一个MainActivity对象,之后在onAttach()方法中通过getContext()方法获得了一个Activity对象。接着在Fragment的onCreateView()方法中初始化Fragment的布局。当用户点击TextView时,就可以调用Activity中的方法,从而实现了Fragment和Activity的交互。

在Activity中获取Fragment的引用

在Activity中获取到Fragment的引用,可以通过Fragment管理器来完成,具体而言,就是通过FragmentManager.findFragmentById()或者FragmentManager.findFragmentByTag()方法获取Fragment。

ExampleFragment exampleFragment = (ExampleFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_container);

在上述代码中,我们通过实例化ExampleFragment对象来获取R.id.fragment_container中的Fragment对象。

Fragment本身并不允许直接修改相邻的Activity,所以Fragment中的事件不能直接影响Activity中的操作。而Fragment和Activity之间的通信则需要使用接口方法。

例如,在Activity中定义一个接口,并在Fragment中实现该接口就可以实现两者之间的交互。

public class MainActivity extends AppCompatActivity implements ExampleFragment.OnButtonClickListener {

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

        ExampleFragment exampleFragment = new ExampleFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.fragment_container, exampleFragment);
        transaction.commit();
    }

    @Override
    public void onButtonClick(String text) {
        TextView textView = findViewById(R.id.tv_example);
        textView.setText(text);
    }
}

在上述MainActivity代码中,我们实现了由ExampleFragment.OnButtonClickListener接口定义的onButtonClick()方法,并且在ExampleFragment中定义了该接口,从而完成了Activity和Fragment的交互。

public class ExampleFragment extends Fragment {
    public interface OnButtonClickListener {
        void onButtonClick(String text);
    }

    private OnButtonClickListener clickListener;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnButtonClickListener) {
            clickListener = (OnButtonClickListener) context;
        } else {
            throw new IllegalArgumentException("Activity must instance of MainActivity");
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_example, container, false);
        Button button = (Button) view.findViewById(R.id.btn_example);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                clickListener.onButtonClick("Dialog Fragment!");
            }
        });
        return view;
    }
}

在上述ExampleFragment代码中,我们定义了一个OnClicklistener接口来完成点击事件,在onAttach方法中获取clickListener接口的实现,并当clickListener被执行时,调用onButtonClick方法从而完成了Activity和Fragment之间的交互。

Fragment的事务操作

通过事务操作可以对Fragment的可见性以及执行remove、add、detach和replace等操作来进行动态添加或替换等操作。通常,在一个FragmentTransaction中可以执行多项操作。

例如:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, exampleFragment);
transaction.addToBackStack(null);
transaction.commit();

在上述代码中,我们通过调用FragmentTransaction.addToBackStack()方法将前一次事务操作前的状态加入到后退栈中,这样当用户按下返回键时,就可以回到之前的状态。

常用事务操作的示例如下:

//新建一个Fragment
ExampleFragment exampleFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
//设置事务动画
transaction.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_right_out);
//添加一个Fragment
transaction.add(R.id.fragment_container, exampleFragment);
//替换fragment
transaction.replace(R.id.fragment_container, exampleFragment, "tag");
//将前一个事务状态加入到后退栈中
transaction.addToBackStack(null);
//Set是否保留要实例化的Fragment的状态
transaction.setReorderingAllowed(true);
//提交事务
transaction.commit();

在上述代码中,我们依次执行了设置事务动画、添加Fragment、替换Fragment、将前一个事务的状态加入后退栈、设置是否保留要实例化的Fragment的状态等多项操作。

其他相关方法

从Fragment中调用另一个Fragment的方法

Fragment和Fragment之间传递参数并不是象Activity和Activity那样方便,在Fragment中调用另一个Fragment的方法有一定的限制。例如,可以使用FragmentManager.findFragmentById()方法获得一个Fragment的实例,然后调用它的方法。

public class ExampleFragment extends Fragment {
    private ExampleFragment2 exampleFragment2;
    private TextView tvText;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        FragmentManager fm = getActivity().getSupportFragmentManager();
        exampleFragment2 = (ExampleFragment2) fm.findFragmentById(R.id.fragment_example2);
        tvText = (TextView)getView().findViewById(R.id.tv_example);
    }

    public void changeText(String string) {
        tvText.setText(string);
    }

    public void changeTextFromFragment2(String string) {
        tvText.setText(string);
    }
}

在上述ExampleFragment中,我们实现了两个方法changeText()和changeTextFromFragment2(),并在onActivityCreated()方法中获得了ExampleFragment2的实例。

判断当前Fragment是否被添加到Activity中

可以通过isAdded()方法来判断当前的Fragment是否被添加到Activity中,使用方法如下:

public class ExampleFragment extends Fragment {
    @Override
    public void onResume() {
        super.onResume();
        if (isAdded()) {
            //执行逻辑
        }
    }
}

示例说明

示例一:Fragment完成简单计算器功能

本示例中,我们创建一个简单的Fragment,并在其中实现简单的加减乘除等计算器功能。

首先,在MainActivity中添加一个Fragment容器,并将ShowResultFragment添加进来,这样可以在Activity界面上看到AddFragment中的界面。

<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/fragment_calculate"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.android.fragmentaddexample.ShowResultFragment"/>

</FrameLayout>

下面是AddFragment的布局文件add_fragment.xml,该文件包含一个编辑框和四个按钮,分别是addBtn(加法)、subBtn(减法)、mulBtn(乘法)和divBtn(除法),我们可以在add_fragment.xml中添加如下代码:

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

    <EditText
        android:id="@+id/first_edit_Text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <Button
        android:id="@+id/addBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="+"/>

    <Button
        android:id="@+id/subBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="-"/>

    <Button
        android:id="@+id/mulBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="*"/>

    <Button
        android:id="@+id/divBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="/"/>

</LinearLayout>

接下来我们就可以在ShowResultFragment.java中实现计算器的逻辑。我们使用EditText控件来获取用户输入的两个数值,并通过四个按钮的点击事件来实现相应的计算逻辑。

public class ShowResultFragment extends Fragment {

    private EditText mFirstInputEdittext;
    private EditText mSecondInputEdittext;
    private Button mAddBtn;
    private Button mSubBtn;
    private Button mMulBtn;
    private Button mDivBtn;

    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int firstNum = 0;
            int secondNum = 0;
            if(!TextUtils.isEmpty(mFirstInputEdittext.getText())){
                firstNum = Integer.parseInt(mFirstInputEdittext.getText().toString());
            }

            if(!TextUtils.isEmpty(mSecondInputEdittext.getText())){
                secondNum = Integer.parseInt(mSecondInputEdittext.getText().toString());
            }

            int res = 0;

            switch (view.getId()){
                case R.id.addBtn:
                    res = firstNum+secondNum;
                    break;
                case R.id.subBtn:
                    res = firstNum - secondNum;
                    break;
                case R.id.mulBtn:
                    res = firstNum*secondNum;
                    break;
                case R.id.divBtn:
                    res = firstNum/secondNum;
                    break;
                default:
                    break;
            }
            Toast.makeText(getActivity(),String.valueOf(res),Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.add_fragment, container, false);
        mFirstInputEdittext = (EditText) view.findViewById(R.id.first_edit_Text);
        mSecondInputEdittext = (EditText) view.findViewById(R.id.second_edit_Text);
        mAddBtn = (Button) view.findViewById(R.id.addBtn);
        mSubBtn = (Button) view.findViewById(R.id.subBtn);
        mMulBtn = (Button) view.findViewById(R.id.mulBtn);
        mDivBtn = (Button) view.findViewById(R.id.divBtn);

        mAddBtn.setOnClickListener(mOnClickListener);
        mSubBtn.setOnClickListener(mOnClickListener);
        mMulBtn.setOnClickListener(mOnClickListener);
        mDivBtn.setOnClickListener(mOnClickListener);
        return view;
    }
}

接下来我们就可以在MainActivity中启动Fragment并执行计算器的逻辑:

    private void addFragment() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, new ShowResultFragment());
        transaction.commit();
    }

最后运行代码,可以在Activity中看到一个简单的计算器界面,可以计算加减乘除等运算。

示例二:Fragment之间的通讯

在本示例中,我们演示了Fragment之间的通讯。我们分别定义了两个Fragment,一个是AddFragment,另一个是ShowResultFragment,在AddFragment中实现了EditText控件的输入功能,并把结果显示在TextView中; ShowResultFragment中实现了一个Button可以清空TextView中的内容,两个Fragment之间通过Button来通讯。

我们首先在MainActivity中添加这两个Fragment:

private void addFragment() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container_add, new AddFragment(),"add");
        transaction.replace(R.id.fragment_container_show, new ShowResultFragment(),"show");
        transaction.commit();
    }

在AddFragment中的布局文件add_fragment.xml中添加一个TextView,并在ShowResultFragment中的布局文件show_fragment.xml中添加一个Button,用于清空AddFragment中的TextView,布局文件内容

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android开发教程之Fragment定义、创建与使用方法详解【包含Activity通讯,事务执行等】 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 程序员 代码是从头编还是使用框架好呢?

    当程序员开始编写代码时,他们经常会面临一个选择:是从头开始编写代码,还是使用框架来加速开发和减少代码的编写时间。虽然这个选择可能因项目而异,但以下是一些攻略来帮助你做出正确的决定: 什么是框架? 在了解如何选择到底是使用框架还是手写代码之前,需要了解什么是框架。框架通常是一组预定的规则、标准和工具的集合,可用于快速开发应用程序。框架也允许多个程序员在同一应用…

    other 2023年6月26日
    00
  • 解决bind错误bind:addressalreadyinuse

    以下是详细讲解“解决bind错误bind:address already in use的完整攻略”的标准Markdown格式文本: 解决bind错误bind:address already in use 在使用bind命令绑定端口时有时会出现“bind: address already in use”的错误。这个错误通常是由于端口已经被其他进程占用而导致的。…

    other 2023年5月10日
    00
  • nacos配置中心远程调用读取不到配置文件的解决

    在使用Nacos配置中心时,有时会遇到远程调用读取不到配置文件的问题。这种情况通常由以下原因引起: 配置文件未正确加载到Nacos服务端 配置文件加载到Nacos服务端,但客户端读取配置时未传入正确的配置ID 配置文件正确加载到Nacos服务端,客户端也传入了正确的配置ID,但配置文件格式不正确或者部分配置项未正确配置 针对以上问题,我们可以分别采取以下措施…

    other 2023年6月25日
    00
  • Go语言中的方法、接口和嵌入类型详解

    Go语言中的方法、接口和嵌入类型详解 方法 Go语言中,方法是一种作用于特定类型变量的函数。它类似于C++或者Java中的方法。在一个类型中定义方法给了这个类型的对象被调用这个方法的可能。在Golang中,方法的语法格式如下: func (receiver type) methodName(parameters) (results) { // 方法体 } 其…

    other 2023年6月26日
    00
  • 为什么snmp通常在udp而不是tcp/ip上运行?

    以下是关于“为什么SNMP通常在UDP而不是TCP/IP上运行”的完整攻略,包含两个示例。 为什么SNMP通常在UDP而不是TCP/IP上运行? SNMP(Simple Network Management Protocol)是一种用于管理和监控网络设备的协议。通常,SNMP在UDP(User Datagram Protocol)而不是TCP/IP(Tran…

    other 2023年5月9日
    00
  • iOS8.1 beta测试版固件下载 苹果iOS8.1 beta版固件下载地址大全

    iOS 8.1 Beta测试版固件下载攻略 苹果公司发布了iOS 8.1 Beta测试版固件,这是一个提前体验即将发布的iOS 8.1版本的机会。本攻略将为您提供详细的步骤,以下载和安装iOS 8.1 Beta测试版固件。 步骤一:注册为苹果开发者 在下载iOS 8.1 Beta测试版固件之前,您需要注册为苹果开发者。请按照以下步骤进行操作: 访问苹果开发者…

    other 2023年8月4日
    00
  • 安装博图v17时安装不上一直提示要重启的解决方法

    安装博图v17时出现无法正常安装的情况,常见的出现多为安装程序提示重启计算机才能安装的问题。以下是解决该问题的攻略。 步骤一:关闭占用程序 先检查计算机中是否有其他程序在占用该软件相关的文件或进程。可在任务管理器中搜索相关进程并结束它。此外,如果计算机中安装了多个安全软件,有可能其中一个软件已经锁定了该软件的安装程序,需要把防火墙、杀毒软件暂停或设置其信任该…

    other 2023年6月27日
    00
  • Jquery实现图片预加载与延时加载的方法

    以下是详细讲解 “JQuery实现图片预加载与延迟加载的方法”的完整攻略: 什么是图片预加载? 图片预加载是在网页加载时提前把所需的图片加载进缓存,从而提高用户访问网页时的速度体验。而不是等到需要显示出来的时候再去加载,造成用户等待时间过长。 JQuery实现图片预加载的方法 实现图片预加载的方法一般有两种方式: 1. 利用JQuery的ajax请求 可以用…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部