Android开发-Fragment(碎片)

目录

知识点

1.Fragment概述

1.1 定义

1.2 Fragment设计思想

2.Fragment与Activity区别

3.Fragment生命周期 

3.1 Activity与Fragment生命周期的比较

3.2 Fragment的四种状态

3.3 实例创建

4.Fragment的创建

4.1 创建方式方法

4.2 Fragment的静态加载

4.3 动态加载

4.3.1 实例

4.3.2 动态切换fragment的方法:

4.3.3 Fragment中常用的方法:

5.在Fragment中模拟返回栈

6.Fragment的通信传值

6.1 概述

6.1.1 获取对方的实例

6.1.2 与对方进行传值

6.2 Activity -> Fragment

6.3 Fragment -> Activity

6.4 Fragment -> Fragment


知识点

Fragment的基本概念与应用。

Fragment与Activity的对比,生命周期的比较。
Fragment怎么使用,包括静态和动态加载。
Fragment的增,删,替换等操作。

 

1.Fragment概述

1.1 定义

         Fragment(碎片)是一种可以嵌入在活动当中的UI片段,能够让程序更加合理和充分的利用大屏幕的空间,因而在平板上应用得很广泛。和Activity很像,同样可以包含布局,同样拥有自己的生命周期。

1.2 Fragment设计思想

         在手机上的界面,看平板上来看就可能完全不一样,可能导致控件被拉长等等。Fragment为了解决终端适配的问题,比如平板和手机。

2.Fragment与Activity区别

         区别如下所示:

1.Fragment是Android3.0+以后的
2.一个Activity可以运行多个Fragment
3.Fragment不能脱离Activity而存在
4.Activity是屏幕的主体,而Fragment是Activity的一个组成元素
5.Fragment模块化,可重用
6.Fragment可以互相嵌套,但是最好不用。

 

3.Fragment生命周期 

3.1 Activity与Fragment生命周期的比较

                           Activity生命周期                                                           Fragment生命周期 

 

                    

1.onAttach()方法:顾名思义,是Fragment和Activity建立关联的时候调用。
2.onCreate()方法:当Fragment创建时调用。
3.onCreateView()方法:为Fragment加载布局时调用。
4.onViewCreated()方法:当Fragment加载布局完成后时调用
5.onActivityCreated()方法:当Activity中的onCreate方法执行完后调用。
6.onStart()方法:当Fragment启动时调用。
7.onResume()方法:当Fragment正在运行时调用。
8.onPause()方法:当Fragment不在交互时调用。
9.onStop()方法:当Fragment不可再见时调用。
10.onDestoryView()方法:Fragment中的布局被移除(即销毁)时调用(即与Fragment关联的视图被移除)
11.onDestory()方法:Fragment被移除(即销毁)时调用
12.onDetach()方法:Fragment与Activity解除关联时调用。

          注意:Fragment中不存在onRestart()方法,该方法只存在与Activity中。

3.2 Fragment的四种状态

运行状态当Fragment是可见的,且所关联的Activity正处于运行状态时,该Fragment也处于运行状态。
暂停状态

当Activity处于暂停状态(由于另外一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见

Fragment就会进入到暂停状态。

停止状态

当一个Activity处于停止状态,与之关联的Fragment就会进入到停止状态。处于停止状态的Fragment对于

用户来说是完全不可见的,有可能会被系统回收。

销毁状态当Activity被销毁时,与之关联的Fragment就会进入销毁状态,

3.3 实例创建

         需要定义类继承Fragment抽象类:

//Fragment类,继承自android.support.v4.app.Fragment;
public class Fragment_1 extends Fragment{
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //加载布局
        View view = inflater.inflate(R.layout.fragment,container,false);
        return view;
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    @Override
    public void onStart() {
        super.onStart();
    }
    @Override
    public void onResume() {
        super.onResume();
    }
    @Override
    public void onPause() {
        super.onPause();
    }
    @Override
    public void onStop() {
        super.onStop();
    }
    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    @Override
    public void onDetach() {
        super.onDetach();
    }
}

       注意:Fragment中不存在onRestart()方法,该方法只存在与Activity中。

4.Fragment的创建

4.1 创建方式方法

        Fragment可以通过两种方式创建:

静态方法创建定义布局,定义类继承Fragment,在Activity布局中加入<fragment>
动态方法创建 

4.2 Fragment的静态加载

         以xxx.xml文件形式加载,把Fragment当成普通的控件,直接写在Activity的布局文件中,步骤:

1、继承Fragment,重写onCreateView决定Fragemnt的布局

2、在Activity的布局文件中中加入此Fragment,就当和普通的View控件一样,<fragment ...../>(name属性传入类名

  left_fragment.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="#fce57f">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Button"
        android:background="#fa6b47"/>
</LinearLayout>

right_fragment.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"
    android:background="#751f56">
    <TextView
        android:textSize="20sp"
        android:textColor="#FFFFFF"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is right fragment"/>
</LinearLayout>

LeftFragment.java:

//Fragment类,继承自android.support.v4.app.Fragment;
public class LeftFragment extends Fragment{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left_fragment,container,false);
        return view;
    }
}

RightFragment.java:

public class RightFragment extends Fragment{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.right_fragment,container,false);
        return view;
    }
}

将Fragment添加到Activity的布局文件activity_main.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">
    <!-- id一定别忘记 -->
    <fragment
        android:id="@+id/left_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:name="com.administrator.fragmentstudy.LeftFragment"
        android:layout_weight="1"/>
    <fragment
        android:id="@+id/right_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:name="com.administrator.fragmentstudy.RightFragment"
        android:layout_weight="1"/>
</LinearLayout>

运行结果:

    

注意:添加进去的fragment一定要有id,否则要报错: Error inflating class fragment。

 

4.3 动态加载

4.3.1 实例

     步骤:

1.创建待添加的Fragment实例。
2.在Activity布局中加入FrameLayout布局(所有控件默认摆放在布局的左上角)
3.在Activity中,使用getSupportFragmentManager()获取FragmentManager对象
4.开启一个事务,通过调用beginTransaction()方法开启
5.向容器(通过FrameLayout的id属性)添加Fragment实例,添加使用add(),替换使用replace()
6.提交事务,调用commit()方法

创建another_right_fragment.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:background="#fce4b8">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="This is another right fragment"
        android:textSize="20sp"
        android:textColor="#e10367"/>
</LinearLayout>

创建AnotherRightFragment.java:

public class AnotherRightFragment extends Fragment{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.another_right_fragment,container,false);
        return view;
    }
}

在Activity的布局文件,activity_layout.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">
    <fragment
        android:id="@+id/left_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:name="com.administrator.fragmentstudy.LeftFragment"
        android:layout_weight="1"/>
    <FrameLayout
        android:id="@+id/another_right_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
</LinearLayout>

在MainActivity.java中:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建Fragment实例
        AnotherRightFragment anotherRightFragment = new AnotherRightFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        //开启Fragment事务
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        //向容器添加Fragment实例
        transaction.add(R.id.another_right_fragment,anotherRightFragment);
        //提交事务
        transaction.commit();
    }
}

 运行效果:

4.3.2 动态切换fragment的方法:

add(Container container,Fragment fragment)添加Fragment到指定的容器里面。
remove(Container container,Fragment fragment)删除指定的Fragment
replace(Container container,Fragment fragment)用新的Fragment替换掉指定的Fragment

4.3.3 Fragment中常用的方法:

android.app.Fragment主要用于定义Fragment
android.app.FragmentManager主要用于在Activity中操作Fragment
android.app.FragmentTransaction保证一些列Fragment操作的原子性

 

5.在Fragment中模拟返回栈

       通过FragmentTransaction的addToBackStack()方法:

addToBackStack(String s)接收一个名字用于描述返回栈的状态,一般传入null即可。

 

6.Fragment的通信传值

6.1 概述

          由于Activity与Fragment各自存在一个独立的类中,它们之间因此没有明显的方式来直接进行通信。

6.1.1 获取对方的实例

Fragment获取它所在的Activity调用Fragment的getActivity()方法即可返回它所在的Activity。
Activity获取它包含的Fragment

调用Activity关联的FragmentManager的findFragmentById(int id) 或

findFragmentByTag(String tag)方法即可获取指定的Fragment。

         实例代码如下:

RightFragment rightFragment = (RightFragment)getSupportFragmentManager().findFragmentById(R.id.right_fragment);

6.1.2 与对方进行传值

            Activity向Fragment传递数据:

在Activity中创建Bundle数据包,并调用Fragment的setArgument(Bundle bundle)方法即可将Bundle数据包传递给Fragment。

          Fragment向Activity传递数据或Activity需要在Fragment运行中进行实时通信:

在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,这样Fragment即可调用该回调方法将数据传递给Activity。

6.2 Activity -> Fragment

   方法:

       Activity通过Bundle对象将其传递的值放在里面,然后通过setArgument()方法来传递,然后Fragment通过getArguments()方法按照键的唯一性来获取值。
setArguments(Bundle bundle)
getArguments().XXX方法

      在Fragment的继承类中:

public class Fragment_1 extends Fragment {
    public static final String bundle_content = "BUNDLE_CONTENT";
    private String content;
    private TextView textView;

    public static Fragment_1 newInstance(String content){
        Bundle bundle = new Bundle();
        bundle.putString(bundle_content,content);
        Fragment_1 fragment = new Fragment_1();
        //设置Bundle
        fragment.setArguments(bundle);
        return fragment;
    }
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_1,container,false);
        //可以对Fragment布局控件进行操作
        textView = view.findViewById(R.id.fragment_1_tv);
        return view;
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if(getArguments() != null) {
            //获取内容
            content = getArguments().getString(bundle_content);
            //设置内容
            textView.setText(content);
        }
    }
}

     注意:这里的Fragment创建顺序。 textView.setText(content)是放在onActivityCreated()方法里面。

     在Activity的MainActivity中:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);      
        Fragment_1 fragment = new Fragment_1();
        getSupportFragmentManager().beginTransaction()
                .add(R.id.title,Fragment_1.newInstance("这是Activity向Fragment传递的内容"))
                //提交
                .commit();
        getSupportFragmentManager().beginTransaction()
                .add(R.id.content,Fragment_1.newInstance("这是Activity向Fragment传递的内容"))
                //提交
                .commit();
    }
}

6.3 Fragment -> Activity

在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,这样Fragment即可调用该回调方法将数据传递给Activity。
Callback
        Fragment类方法编写接口,实现回调:
public class Fragment_1 extends Fragment {
    private TextView textView;
  
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_1,container,false);
        //可以对Fragment布局控件进行操作
        textView = view.findViewById(R.id.fragment_1_tv);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String str = textView.getText().toString();
                //这里一定要非空判断,否则出现空指针异常
                if(onContentClickListener != null){
                    onContentClickListener.onClick(str);
                }
            }
        });
        return view;
    }

    //定义接口
    public interface OnContentClickListener{
        void onClick(String content);
    }
    //定义变量
    private OnContentClickListener onContentClickListener;
    //设置接口的方法(括号里面的参数不能与onContentClickListener一样,否则出错)
    public void setOnContentClickListener(OnContentClickListener listener){
        onContentClickListener = listener;
    }
}

         Activity类implements Fragment_1.OnContentClickListener,继承接口,实现其方法:

public class MainActivity extends AppCompatActivity implements Fragment_1.OnContentClickListener{
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.btn);
        Fragment_1 fragment = new Fragment_1();
        getSupportFragmentManager().beginTransaction()
                .add(R.id.title,fragment)
                //提交
                .commit();
        fragment.setOnContentClickListener(this);
    }

    @Override
    public void onClick(String content) {
        button.setText(content);
    }
}

 

6.4 Fragment -> Fragment

       首先在一个Fragment中可以得到与它相关联的Activity,然后再通过这个Activity去获取另外一个Fragment的实例,这样就实现了Fragment之间的通信。

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckyliuqs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值