IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Fragment -> 正文阅读

[移动开发]Android Fragment

1.Fragment

fragment译为“碎片”,是Android 3.0(API 11)提出的,最开始是为了适配大屏的平板。

Fragment看起来和Activity一样,是一个用户界面。可以结合多个Fragments到一个activity中来构建一个有多方面功能的UI,还可以重用同一个Fragment在多个activities中。Fragment可以当成是activity的一个组件,每个Fragment有单独的生命周期,可以在activity运行时进行添加和移除Fragment。因此,相比较于activity,Fragment更加轻量级,更加灵活。

一个Fragment总是被植入在一个activity中 ,并且其生命周期受其父activity直接影响,比如activity处于暂停,则其中的Fragment都暂停;activity销毁,则所有Fragment都销毁。但是,当一个activity运行时,你可以独立的操作每一个Fragment,比如添加和删除他们。进行类似的操作时,可以将Fragment添加入被activity管理的后退栈中,这样用户可以通过点击返回按钮来返回之前打开的Fragment。

Fragment可以作为activity的一部分添加到布局文件中,通过声明元素作为ViewGroup的一部分。也可以将Fragment作为一个没有自己UI的不可见的activity的工人。

总结一下:

①Fragment是依赖于Activity的,不能独立存在。

②一个Activity里可以有多个Fragment。

③一个Fragment可以被多个Activity重用。

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

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

?

2.Fragment生命周期

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2f6Iqz6Iqz,size_20,color_FFFFFF,t_70,g_se,x_16

?常见的周期流程

①Activity加载Fragment的时候,依次调用:onAttach() -> onCreate() -> onCreateView() -> onActivityCreated() -> onStart() ->onResume()

②当做出一个悬浮的对话框风格的Activity,或者其他,就是让Fragment所在的Activity可见,但不获得焦点:onPause()

③当对话框关闭,Activity又获得了焦点:?onResume()

④当替换Fragment,并调用addToBackStack()将它添加到Back栈中:onPause() -> onStop() -> onDestoryView() 。注意,此时的Fragment还没有被销毁哦。

⑤当按下键盘的回退键,Fragment会再次显示出来:onCreateView() -> onActivityCreated() -> onStart() -> onResume()

⑥如果替换后,在事务commit之前没有调用addToBackStack()方法将Fragment添加到back栈中,或者退出了Activity的话,那么Fragment将会被完全结束,Fragment会进入销毁状态: onPause() -> onStop() -> onDestoryView() -> onDestory() -> onDetach()

?

3.Fragment创建

①静态加载--以<fragment>标签的形式添加到Activity的布局当中。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2f6Iqz6Iqz,size_20,color_FFFFFF,t_70,g_se,x_16

?1)定义Fragment的布局,就是fragment显示内容

2)自定义一个Fragment类,需要继承Fragment或者它的子类,重写onCreateView()方法,在该方法中调用inflater.inflate()方法加载Fragment的布局文件,接着返回加载的view对象。

public class Fragmentone extends Fragment {

? ? private View view;

? ? @Override

? ? public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

? ? ? ? if(view == null) {

? ? ? ? ? ? View view = inflater.inflate( R.layout.fragment1, container,false);

? ? ? ? }

? ? ? ? return view;

? ? }

}

3)在需要加载Fragment的Activity对应的布局文件中添加fragment的标签,注意name属性是全限定类名,就是要包含Fragment的包名。

4)Activity在onCreate( )方法中调用setContentView()加载布局文件。

②动态加载--通过java代码将fragment添加到已存在的宿主Activity中

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2f6Iqz6Iqz,size_20,color_FFFFFF,t_70,g_se,x_16

动态添加fragment常用的类:

FragmentManager:用来管理Activity中的fragment,app包中使用getFragmentManager() v4包中getSupportFragmentManager。可以通过findFragmentById获取指定的Fragment,可以调用popBackStack()方法弹出后台Fragment,还可以调用addToBackStack()方法加入栈,或监听后台栈的变化:addOnBackStackChangeListener。

FragmentTransaction:事务,用来添加、移除、替换fragment,记得在操作完后用commoi()提交事务。FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务

transaction.add():往Activity中添加一个Fragment

transaction.remove() :从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。

transaction.replace():使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体。

transaction.hide():隐藏当前的Fragment,仅仅是设为不可见,并不会销毁

transaction.show():显示之前隐藏的Fragment

transaction.commit():提交一个事务

detach():会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。

注意:在用fragment的时候,可能会经常遇到Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。

这些基本是操作Fragment的所有方式了,在一个事务开启到提交可以进行多个添加、移除、替换等操作。

注意:使用Fragment,一定要清楚这些方法,哪个会销毁视图,哪个会销毁实例,哪个仅仅只是隐藏,这样才能更好的使用它们。

attach():重建view视图,附加到UI上并显示。

1)比如:在FragmentA中的EditText填了一些数据,当切换到FragmentB时,如果希望回到A还能看到数据,则使用的就是hide和show;也就是说,希望保留用户操作的面板,可以使用hide和show,当然了不要使劲在那new实例,进行下非null判断。

2)再比如:不希望保留用户操作,可以使用remove(),然后add();或者使用replace()这个和remove、add是相同的效果。

3)remove和detach有一点细微的区别:在不考虑回退栈的情况下,remove会销毁整个Fragment实例,而detach则只是销毁其视图结构,实例并不会被销毁。那么二者怎么取舍使用呢?如果当前Activity一直存在,在不希望保留用户操作的时候,可以优先使用detach。

?

4.Fragment与Activity的交互

1)组件获取

Fragment获得Activity中的组件: getActivity().findViewById(R.id.list);

Activity获得Fragment中的组件(根据id和tag都可以):getFragmentManager.findFragmentByid(R.id.fragment1);

2)数据传递

①Activity传递数据给Fragment

采用Bundle方式:在activity中创建Bundle数据包,把要传的值存入bundle,调用Fragment实例的setArguments(bundle)从而将Bundle数据包传给Fragment,,然后Fragment中调用getArguments获得Bundle对象,然后进行解析就可以了。

举个例子:动态添加fragment的时候,在添加每个fragment之前,使用Bundle传输数据给每个fragment。

mManager = getSupportFragmentManager();

mTransaction = mManager.beginTransaction();

homeFragment = new HomeFragment();

//创建Bundle对象,并存储数据

Bundle bundle=new Bundle();

bundle.putString("home","Home");

homeFragment.setArguments(bundle);

fragment中接收数据:

Bundle bundle = this.getArguments();

String home = bundle.getString("home");

②Fragment传递数据给Activity

采用接口回调方式:在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,Fragment就可以通过回调接口传数据了。

首先定义一个接口回调接口:(Fragment中)

public interface ICallBack{??

? ? public void getResult(String result);??

}??

接着在Fragment中设置接口回调的方法:

public void getData(ICallBack callBack){??

? ? String msg = editText.getText().toString();??

? ? callBack.getResult(msg);??

}??

最后在Activity中回调:

leftFragment.getData(new ICallBack() {??

?@Override??

? ?public void getResult(String result) {?

? ? ? ? Toast.makeText(this, result, 1).show();??

??? }

});?

③Fragment与Fragment之间的数据互传

不同的fragment之间的通信要依靠ativity来完成。可以看成Fragment->Activity->Fragment,因为两个或多个fragment是依附于同一个activity,所以完全可以通过把值传递到共同依附的Activity,然后通过Bundle传给另一个fragment。

方式一:先调用findFragmentById()方法根据id获得fragment的对象,然后调用fragment中的方法进行赋值。

manager.findFragmentById(); //根据ID来找到对应的Fragment实例,主要用在静态添加fragment的布局中,因为静态添加的fragment才会有ID

manager.findFragmentByTag();//根据TAG找到对应的Fragment实例,主要用于在动态添加的fragment中,根据TAG来找到fragment实例

manager.getFragments();//获取所有被ADD进Activity中的Fragment

然后,直接在一个Fragment中调用另外一个Fragment的公开方法,前提是要先拿到另外一个Fragment的实例。

一般情况下,都是动态添加Fragment的,所以通过在add每个Fragment的时候,给每个Fragment设置个tag。

manager = this.getSupportFragmentManager();

transaction = manager.beginTransaction();

LeftFragment leftFragment = new LeftFragment();

RightFragment rightFragment = new RightFragment();

transaction.add(R.id.left, leftFragment, "left");

transaction.add(R.id.right, rightFragment, "right");

transaction.commit();

在Activity创建的时候,添加上所有的fragment,并为每个fragment设置tag,这样才会在每个fragment中通过findFragmentByTag()时,不会出现空指针。

在LeftFragment中:

RightFragment rightFragment = (RightFragment) getActivity().getSupportFragmentManager().findFragmentByTag("right");

if (rightFragment == null) return;

rightFragment .setTextView("right now");

这样就实现了在LeftFragment里给RightFragment传值的效果。

这种方式是两个fragment直接通信的。(不推荐使用)

方式二:通过接口回调的方法实现两个fragment之间的通信

比如点击MessageFragment的Button按钮,给CommunityFragment中的TextView传递数据。就需要在MessageFragment中定义接口,并定义回调的方法,该方法的参数中传一个String的字符串。接着让附属Activity实现这个接口,并重写回调方法,也就得到到传过来的数据,然后通过findFragmentByTag()的方法获取要传给的CommunityFragment的实例。

在CommunityFragment中定义一个方法用来接收这个数据,然后用对象直接调用这个方法将参数传递给这个方法,就可以了。

方式三:其他方式

EventBus:使用方便,但其使用的是反射原理,会有稍微的延迟,并且他人维护不方便;

static静态变量:使用方便,但是,每个static变量都会占用一块内存区,Android系统分配给每个App的内存是有限的(63M),过多很容易造成App内存溢出;

广播Broadcast Receiver:Android的广播是有限制的,除了系统的广播外,其他的广播尽量少用。另外,广播会有延迟;

接口:接口是常用的Fragment之间的通讯方式,通过一个主Activity作为通讯桥梁(谷歌官方声明:两个Fragment之间永远不要直接通讯),实现两个Fragment之间的通讯。

接口的方式是推荐的,但是,传统的接口方式会造成一些问题,如果主Activity实现了多个Fragment的通讯回调接口,那就需要implements很多接口,类中还要实现一大堆接口的方法,显得有点繁琐。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 08:51:08  更:2022-04-30 08:52:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 0:06:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码