Android 面试题之 Fragment 使用+实例(上)

简介: 一、为什么要有Fragment?二、Fragment为什么被称为第五大组件特点:三、Activity创建Fragment的方式静态创建样例:动态创建样例:四、FragmentPageAdapter和FragmentPageStateAdapter的区别

一、为什么要有Fragment?

image.png


Android运行在各种各样的设备中,有小屏幕的手机,还有大屏幕的平板,电视等。同样的界面在手机上显示可能很好看,在大屏幕的平板上就未必了,手机的界面放在平板上可能会有过分被拉长、控件间距过大等情况。针对屏幕尺寸的差距,Fragment 的出现能做到一个App可以同时适应手机和平板。这就是为什么要有Fragment的原因。


android.app.Fragment在API 级别 11 中 添加,已在API 级别 28 中弃用


二、Fragment为什么被称为第五大组件


Fragment比Activity更节省内存,其切换模式也更加舒适,使用频率不低于四大组件,且有自己的 生命周期,而且必须依附于Activity,不能独立存在。


特点:


  • Fragment依赖于Activity,不能独立存在


  • 一个Activity可以有多个Fragment


  • 一个Fragment可以被多个Activity重用


  • Fragment有自己的生命周期,并能接收输入事件


  • 可以在Activity运行时动态地添加或删除Fragment


三、Activity创建Fragment的方式


静态创建


  1. 定义Fragment的xml布局文件
  2. 自定义Fragment类,继承Fragment类或其子类,同时实现onCreateView()方法,在方法中通过inflater.inflate加载布局文件,接着返回其View
  3. 在需要加载Fragment的Activity对应布局文件中的name属性设为全限定类名,即包名.fragment
  4. 最后在Activity调用setContentView()加载布局文件即可


样例:


image.png


1.定义Fragment的xml布局文件(新建fragment_home.xml和fragment_mine.xml)


fragment_home.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="@color/color_ff0000"
    android:gravity="center"
    >
    <TextView
        android:id="@+id/tv_on"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="首页"
        android:onClick="onClick"
        android:textColor="@color/white"
        android:textSize="@dimen/text_size_20"/>
</LinearLayout>


fragment_mine.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="@color/color_188FFF"
    android:gravity="center"
    >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我的"
        android:textColor="@color/white"
        android:textSize="@dimen/text_size_20"/>
</LinearLayout>


2.自定义Fragment类,继承Fragment类或其子类,同时实现onCreateView()方法,在方法中通过inflater.inflate加载布局文件,接着返回其View


public class HomeFragment extends Fragment {
    private TextView tv_on;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container,false);
        MLog.e(this.getClass().getName()+"onCreateView");
        tv_on = view.findViewById(R.id.tv_on);
        tv_on.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MLog.e(this.getClass().getName()+"准备关闭");
            }
        });
        return view;
    }
}


3.在需要加载Fragment的Activity对应布局文件中的name属性设为全限定类名,即包名.fragment.HomeFragment


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/color_666666"
    android:orientation="horizontal">
    <fragment
        android:id="@+id/fragmen_home"
        android:name="com.scc.demo.fragment.HomeFragment"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <fragment
        android:id="@+id/fragmen_mine"
        android:name="com.scc.demo.fragment.MineFragment"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
</LinearLayout>


4.最后在Activity调用setContentView()加载布局文件即可


public class FragmentActivity extends ActivityBase {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MLog.e(this.getClass().getName()+"onCreate");
        setContentView(R.layout.activity_fragment);
    }
}


动态创建


  1. 获得FragmentManager对象,通过getSupportFragmentManager()


  1. 获得FragmentTransaction对象,通过fm.beginTransaction()


  1. 调用add()方法或者repalce()方法加载Fragment;


  1. 最后调用commit()方法提交事务


样例:


image.png


1.activity的布局文件

1.<?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">
    <FrameLayout
        android:id="@+id/fl_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/rg_bottom_tab"/>
    <RadioGroup
        android:id="@+id/rg_bottom_tab"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="#dcdcdc"
        android:orientation="horizontal">
        <RadioButton
            android:id="@+id/rb_home"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:gravity="center"
            android:text="首页"
            android:textSize="@dimen/text_size_18" />
        <RadioButton
            android:id="@+id/rb_list"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:gravity="center"
            android:text="列表"
            android:textSize="@dimen/text_size_18" />
        <RadioButton
            android:id="@+id/rb_news"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:gravity="center"
            android:text="消息"
            android:textSize="@dimen/text_size_18" />
        <RadioButton
            android:id="@+id/rb_mine"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:button="@null"
            android:gravity="center"
            android:text="我的"
            android:textSize="@dimen/text_size_18" />
    </RadioGroup>
</RelativeLayout>


2.自定义Fragment


public class HomeFragment extends Fragment {
    private TextView tv_on;
    public static HomeFragment newInstance(String param){
        HomeFragment fragment = new HomeFragment();
        Bundle args = new Bundle();
        args.putString("param", param);
        fragment.setArguments(args);
        return fragment;
    }
    public HomeFragment(){}
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container,false);
        MLog.e(this.getClass().getName()+"onCreateView");
        Bundle bundle = getArguments();
        String param = bundle.getString("param");
        tv_on = view.findViewById(R.id.tv_on);
        tv_on.setText("首页"+param);
        tv_on.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MLog.e(this.getClass().getName()+"准备关闭");
            }
        });
        return view;
    }
}


3.获得FragmentManager对象,通过getFragmentManager()


public class FragmentActivity extends ActivityBase {
    private RadioGroup rg_bottom_tab;
    private SparseArray<Fragment> mFragmentList;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);
        MLog.e(this.getClass().getName()+"onCreate");
        initView();
    }
    public void initView(){
        rg_bottom_tab = findViewById(R.id.rg_bottom_tab);
        mFragmentList = new SparseArray<>();
        mFragmentList.append(R.id.rb_home, HomeFragment.newInstance("我最帅"));
        mFragmentList.append(R.id.rb_list, ListFragment.newInstance("我最美"));
        mFragmentList.append(R.id.rb_news, NewsFragment.newInstance("我最新"));
        mFragmentList.append(R.id.rb_mine, MineFragment.newInstance("这里是我的"));
        rg_bottom_tab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // 具体的fragment切换逻辑可以根据应用调整,例如使用show()/hide()
                FragmentManager fragmentManager = getFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.fl_frame, mFragmentList.
                        get(checkedId));
                transaction.commit();
            }
        });
        // 默认显示第一个
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.fl_frame, mFragmentList.get(R.id.rb_home)).commit();
    }
}1.



四、FragmentPageAdapter和FragmentPageStateAdapter的区别


FragmentPageAdapter在每次切换页面的的时候,是将Fragment进行分离,适合页面较少的Fragment使用以保存一些内存,对系统内存不会多大影响。


FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存。


相关文章
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
94 6
|
2月前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
28 3
|
2月前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
25 3
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
27 2
|
2月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
58 1
|
2月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
Android面试高频知识点(1) 图解 Android 事件分发机制
43 1
|
2月前
|
存储 缓存 网络协议
5个Android性能优化相关的深度面试题
本文涵盖五个Android面试题及其解答,包括优化应用启动速度、内存泄漏的检测与解决、UI渲染性能优化、减少内存抖动和内存溢出、优化网络请求性能。每个问题都提供了详细的解答和示例代码。
29 2