前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android学习笔记----Fragment

android学习笔记----Fragment

作者头像
砖业洋__
发布2023-05-06 19:20:54
6130
发布2023-05-06 19:20:54
举报
文章被收录于专栏:博客迁移同步博客迁移同步

关于Fragment官方文档:https://developer.android.google.cn/guide/components/fragments?utm_source=udacity&utm_medium=course&utm_campaign=android_basics

Fragment详解见链接

https://blog.csdn.net/harvic880925/article/details/44917955

以下是自己的笔记:

静态添加碎片

fragment1.xml

代码语言:javascript
复制
<?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">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="fragment1的内容"
        android:textColor="#00ff00"/>
</LinearLayout>

fragment2.xml

代码语言:javascript
复制
<?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">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="fragment2的内容"
        android:textColor="#ff0000"/>
</LinearLayout>

Fragment1.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {
    // 当系统第一次绘制UI的时候调用,通过这个方法让fragment显示自己的布局
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1, container, false);
        return view;
    }
}

笔记批注:

       Activity 的 onCreate() 方法与 Fragment 的 onCreateView() 方法稍微不同,在 Activity 的 onCreate() 方法中,我们可以调用 setContentView() 来为 该 Activity 设置布局。在 Fragment 中,我们需要根据 XML 布局资源 ID 获得 视图,并在 onCreateView() 方法中返回该视图。

       我们来看看这里onCreateView()参数的意思,这里R.layout.fragment1 是对应用资源中保存的名为 fragment1.xml 的布局资源的引用。传递到 onCreateView() 的 container 参数是Fragment布局,将插入到的父 ViewGroup(来自 Activity 的布局)。savedInstanceState 参数是在恢复Fragment时,提供上一个Fragment实例相关数据的 Bundle。(同样与 Activity 一样,假使 Activity 的进程被终止,而您需要在重建 Activity 时恢复Fragment状态,您也可以使用 Bundle 保留Fragment的状态。您可以在Fragment的 onSaveInstanceState() 回调期间保存状态,并可在 onCreate()、onCreateView() 或 onActivityCreated() 期间恢复状态。如需了解有关保存状态的详细信息,请参阅 Activity 文档)

inflate() 方法带有三个参数:

1.您想要扩展的布局的资源 ID; 2.将作为扩展布局父项的 ViewGroup。传递 container 对系统向扩展布局的根视图(由其所属的父视图指定)应用布局参数具有重要意义; 3.指示是否应该在扩展期间将扩展布局附加至 ViewGroup(第二个参数)的布尔值。(在本例中,其值为 false,因为系统已经将扩展布局插入 container — 传递 true 值会在最终布局中创建一个多余的视图组。)

Fragment2.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

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

activity_main.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="example.com.fragment_rumen.Fragment1"
        android:id="@+id/list"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />
    <fragment android:name="example.com.fragment_rumen.Fragment2"
        android:id="@+id/viewer"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />
</LinearLayout>

笔记批注:

       可以看到,使用<fragment>标签在布局中添加碎片,其中我们需要指定android:name属性来显式指明要添加的碎片类名,记得一定要把包名加上。<fragment> 中的 android:name 属性指定要在布局中实例化的 Fragment 类。当系统创建此 Activity 布局时(setContentView(R.layout.activity_main)),会实例化在布局中指定的每个fragment,并为每个fragment调用 onCreateView() 方法,以检索每个fragment的布局(这里是R.layout.fragmemt1和R.layout.fragment2)。系统会直接插入fragment返回的 View 来替代 <fragment> 元素。

MainActivity.java

代码语言:javascript
复制
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);
    }
}

至于MainActivity,由于我们使用的V4包,必须将MainActivity派生自FragmentActivity,否则根本无法启动程序!报错Trying to instantiate a class example.com.fragment_rumen.Fragment1 that is not a Fragment。因为系统的Activity只能用来盛装系统自带的Fragment,而无法盛装V4包中的Fragment,因为系统的Activity根本无法识别V4包中的Fragment,因为这根本就不是一块的代码!如果不使用V4包,使用系统自带的Fragment则不必将MainActivity派生自FragmentActivity。

那为什么这里extends AppCompatActivity可以,但是extends Activity会报错呢?

public class AppCompatActivity extends android.support.v4.app.FragmentActivity implements android.support.v7.app.AppCompatCallback, android.support.v4.app.TaskStackBuilder.SupportParentable, android.support.v7.app.ActionBarDrawerToggle.DelegateProvider

继承了FragmentActivity,所以不报错。

这种简单的碎片用法实际不会采用,用于理解,接下来看看高级一点的使用。

动态添加碎片

动态添加碎片主要分为5步。

1.创建待添加碎片的的实例。

2.获取FragmentManager,在活动中可以直接通过调用getSupportFragmentManager()方法得到。

3.开启一个事务,通过调用beginTransaction()方法开启。

4.向容器中添加或替换碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。

5.提交事务,调用commit()方法来完成。

目录结构

MainActivity.java

代码语言:javascript
复制
import android.graphics.Point;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Point point = new Point();
        getWindowManager().getDefaultDisplay().getRealSize(point);
        int width = point.x;
        int height = point.y;
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (height > width) { // 竖屏
            // android.R.id.content 代表当前手机的窗体
            fragmentTransaction.replace(android.R.id.content, new Fragment1());
        } else { // 横屏
            fragmentTransaction.replace(android.R.id.content, new Fragment2());
        }
        fragmentTransaction.commit();
    }
}

笔记批注:

       关于Fragment有两个不同的包下的Fragment选择,一个是系统内置的android.app.Fragment,一个是support-v4库中的android.support.v4.app.Fragment。这里强烈建议使用support-v4库中的Fragment,因为它可以让碎片在所有android系统版本中保持功能的一致性。比如Fragment是api11(android 3.0)才开始支持的,在之前系统版本的手机中无法运行。又比如在Fragment中嵌套Fragment,这个功能是在api 17(android 4.2)才开始支持的,如果使用的是内置的Fragment,那么4.2之前的系统设备运行就会崩溃,说是不支持的方法。而使用support-v4库中的Fragment就不会出现这个问题,会自动向下兼容,只要保证support-v4库是最新的就行的。

       另外,我们并不需要在build.gradle文件中添加support-v4库的依赖,因为build.gradle文件中已经添加了appcompat-v7库的依赖,而这个库会把support-v4库也一起引入进来。

Fragment1.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 */
public class Fragment1 extends Fragment {
    public Fragment1() {
        // Required empty public constructor
    }

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

Fragment2.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 */
public class Fragment2 extends Fragment {
    public Fragment2() {
        // Required empty public constructor
    }

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

activity_main.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

fragment1.xml

代码语言:javascript
复制
<?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">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="fragment1竖屏的内容"
        android:textColor="#00ff00"/>
</LinearLayout>

fragment2.xml

代码语言:javascript
复制
<?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">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="fragment2横屏的内容"
        android:textColor="#ff0000"/>
</LinearLayout>

运行结果:

模拟微信主界面

运行效果图:

目录结构

MainActivity.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

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

    public void click(View view) {
        // 获取管理者
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        switch (view.getId()) {
            case R.id.btn_wx:
                fragmentTransaction.replace(R.id.ll_layout, new WxFragment());
                break;
            case R.id.btn_contact:
                fragmentTransaction.replace(R.id.ll_layout, new ContactFragment());
                break;
            case R.id.btn_discover:
                fragmentTransaction.replace(R.id.ll_layout, new DiscoverFragment());
                break;
            case R.id.btn_me:
                fragmentTransaction.replace(R.id.ll_layout, new MeFragment());
                break;
        }
        fragmentTransaction.commit();
    }
}

WxFragment.java

代码语言:javascript
复制
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;

/**
 * A simple {@link Fragment} subclass.
 */
public class WxFragment extends Fragment {
    private static final String TAG = "WxFragment";

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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_wx, container, false);
        // 测试按钮如何点击
        view.findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "================onClick: ");
            }
        });
        return view;
    }
}

ContactFragment.java

代码语言:javascript
复制
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;

/**
 * A simple {@link Fragment} subclass.
 */
public class ContactFragment extends Fragment {
    private static final String TAG = "WxFragment";

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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_contact, container, false);
        return view;
    }
}

DiscoverFragment.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 */
public class DiscoverFragment extends Fragment {
    private static final String TAG = "WxFragment";

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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_discover, container, false);
        return view;
    }
}

MeFragment.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 */
public class MeFragment extends Fragment {
    private static final String TAG = "WxFragment";

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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_me, container, false);
        return view;
    }
}

activity_main.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/ll_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    </LinearLayout>

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

        <Button
            android:id="@+id/btn_wx"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="click"
            android:text="微信" />

        <Button
            android:id="@+id/btn_contact"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="click"
            android:text="通讯录" />

        <Button
            android:id="@+id/btn_discover"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="click"
            android:text="发现" />

        <Button
            android:id="@+id/btn_me"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="click"
            android:text="我" />
    </LinearLayout>
</RelativeLayout>

fragment_wx.xml

代码语言:javascript
复制
<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是微信模块的内容" />

    <Button
        android:id="@+id/btn_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="测试" />
</LinearLayout>

fragment_contact.xml

代码语言:javascript
复制
<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="我是通讯录模块的内容" />
</LinearLayout>

fragment_discover.xml

代码语言:javascript
复制
<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="我是发现模块的内容" />
</LinearLayout>

fragment_me.xml

代码语言:javascript
复制
<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="22sp"
        android:textColor="#ff1234"
        android:text="我是me模块的内容" />
</LinearLayout>

Fragment之间的通信

示例效果图:

目录结构图:

MainActivity.java

代码语言:javascript
复制
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
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);
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();

        fragmentTransaction.replace(R.id.ll1, new Fragment1());
        fragmentTransaction.replace(R.id.ll2, new Fragment2());

        fragmentTransaction.commit();
    }
}

Fragment1.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {
    // 当系统第一次绘制UI的时候调用,通过这个方法让fragment显示自己的布局
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1, container, false);
        view.findViewById(R.id.btn_update).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 通过fragment的公共桥梁---->activity
                Fragment2 fragment2 = (Fragment2) getActivity().getSupportFragmentManager().findFragmentById(R.id.ll2);
                fragment2.setText("hello world!");
                // 不能通过new对象操作,会空指针异常,找不到textview控件,因为new出来不会执行CreateView
            }
        });
        return view;
    }
}

Fragment2.java

代码语言:javascript
复制
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Fragment2 extends Fragment {

    private TextView tv_content;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, container, false);
        tv_content = (TextView) view.findViewById(R.id.tv_content);
        return view;
    }

    public void setText(String text) {
        tv_content.setText(text);
    }
}

activity_main.xml

代码语言:javascript
复制
<?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="horizontal">

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

    </LinearLayout>

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

    </LinearLayout>
</LinearLayout>

fragment1.xml

代码语言:javascript
复制
<?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">
    <Button
        android:id="@+id/btn_update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮"/>
</LinearLayout>

fragment2.xml

代码语言:javascript
复制
<?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">
    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="fragment2的内容"
        android:textColor="#ff0000"/>
</LinearLayout>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Fragment详解见链接
  • 静态添加碎片
  • 动态添加碎片
  • 模拟微信主界面
  • Fragment之间的通信
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档