博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Fragment
阅读量:5314 次
发布时间:2019-06-14

本文共 4812 字,大约阅读时间需要 16 分钟。

 阅读过程中有疑惑的地方:

  • inflate方法的第三个参数,为true和false时,到底有何区别;
  • FragmentTransaction的replace方法,到底是怎么个替换法?是把当前view中所有fragment都替换掉,还是只替换id相同的fragment;
  • FragmentTransaction的addToBackStack()方法,是返回上一次状态,但是为何平板上面实际操作的时候是直接退出了activity;
  • padding的单位,按我的理解,只能是像素吧;
  •  

  发现了一个自适应计算的方法:TypedValue.applyDimension,方法源码如下:

 

1 public static float applyDimension(int unit, float value, 2                                        DisplayMetrics metrics) 3     { 4         switch (unit) { 5         case COMPLEX_UNIT_PX: 6             return value; 7         case COMPLEX_UNIT_DIP: 8             return value * metrics.density; 9         case COMPLEX_UNIT_SP:10             return value * metrics.scaledDensity;11         case COMPLEX_UNIT_PT:12             return value * metrics.xdpi * (1.0f/72);13         case COMPLEX_UNIT_IN:14             return value * metrics.xdpi;15         case COMPLEX_UNIT_MM:16             return value * metrics.xdpi * (1.0f/25.4f);17         }18         return 0;19     }

 

  根据当前value以及单位、屏幕密度来动态计算,返回的值是计算过后的实际像素。

  实例:

 

1  int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,2                     4, getActivity().getResources().getDisplayMetrics());3  text.setPadding(padding, padding, padding, padding);

 

  dp实际上可以理解成一个相对的比例,比如若在mdpi、分辨率是480x800的屏幕上面,一个宽240dp的按钮,实际像素是240px,占了屏幕的1/2;那么在ldpi、分辨率是320x480的屏幕上面,它也要占屏幕的1/2,但是button的像素只有160px了。

  阅读完以后的总结:

  • 设计原则,为什么要用fragment
  • 创建方式,包括两种,一种是通过xml文件夹,另外一种是在代码中添加
  • 如何管理
  • 与activity如何交互

 

一、设计原则

  fragment是为了使大屏幕的界面更加灵活而产生,将UI抽象成可重用的组件,然后在界面上灵活使用。最常见的用法是在横竖屏切换、或者平板与手机共用同一个apk的时候,如下图:

Fragment - 笨小孩 - 我要当地主

 

 

 

应用场景1

  个人理解:平板横屏的时候,可以将左侧的列表和右侧的详细信息同时展现出来;竖屏的时候宽度不够,那么只是单独展示列表或者详细信息。常规的做法是需要针对这种方式分别写上3个activity.那么使用fragment后,将列表抽象成一个共用的fragment,详细信息也抽象成一个公用的fragment,横屏的布局文件中包含两个fragment,竖屏的只包含一个fragment,但是共用同一个activity A的代码。需要做的判断是在点左侧列表中一个选项的时候,是在右侧更新内容还是另起一个activity来展示。另起的activity B 只要将fragment B包含进去即可,并不需要新增很多再处理的代码,这样就达到了一个重用的效果。

 

二、创建

 

  fragment的生命周期是受其依附的activity影响,当activity暂停或者停止时,fragment也会同时达到相应的状态。当activity出于运行状态时,fragment才会进入自由的一个生命周期。

 

  其中,比较重要的生命周期方法包括:

  • onCreateView:在onCreate之后,用于返回fragment的根视图对象,一般使用InflateLayout.inflate方法,从xml资源文件转换成View对象。
  • onActivityCreated:在其依附的activity的onCreate方法成功返回后触发,用于做进一步操作,比如创建一个接口用于回调给activity,这时候可以检验activity是否实现了该接口。
  1. 创建方式

 

  包括两种,一种是直接在xml文件中做配置:  

 

1 
2
6
11
16

 

 

 

  其中的name属性实际就是具体指定fragment的实例,id和tag两个属性都可以用来标识fragment,但是一般用id;若是无界面的fragment,则用tag来标识。

  另外一种是在代码中动态的添加:  

1 FragmentManager fragmentManager = getFragmentManager()2 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();3 fragmentTransaction.add(R.id.replace);

   其中的R.id.fragment_container可以看作成是定义好的fragment容器,也即是xml中定义的fragment节点,但是没有指定过name或者class属性;是否也可以看作成一个任意的ViewGroup对应的资源Id?两者取其一还是都可以? 

 

  2. 管理fragment

  主要是通过FragmentManager对象来操作,主要负责:

  • 创建transaction,进行fragment的添加、删除、替换等事物操作;
  • 查找fragment,这个fragmentManager对象的引用是否依附于activity中的,通过getFragmentManager()方法可以直接获取该对象。通过findFragmentById获取findFragmentByTag来查找当前activity下存在的fragment;
  • 执行返回键的操作,出栈已存放的fragment事物;

  transaction提交之前的所有添加删除操作看成一个事物,当调用addToBackStack方法后,会将之前所有发生的改变看作一次改变,再返回回来的时候,是展示所有这改变之前的状态。

  3. 与activity进行交互

  fragment毕竟是独立出来的组件,那么fragment中发生的操作如何让activity也捕捉到呢?activity又如何向fragment传送值呢?

  让activity捕捉到,无非就是在fragment中触发某种操作后,比如点击按钮后,然后fragment通知activity,然后activity再做出相关的响应。那么fragment如何在恰当的时候通知activity呢?sdk中提供了一种做法,在fragment中定义了一个接口,里面定义了一个方法;然后在onAttach时,判断当前依附的activity有没有实现该接口,同时引用已经实现了该接口的activity对象,用来强制实现;在fragment的比如button事件中,直接调用该引用的注册方法,通知activity来做处理。如下:

public class Fragment_A extends Fragment{  private OnChangedListener m_Listener;   public interface OnChangedListener{     public void onChanged(int index);   }    @Override  public void onAttach(Activity activity){      super.onAttach(activity);      try{          m_Listener=(OnChangedListener)activity;      }catch(ClassCastException ex){      throw new ClassCastException(activity.toString() + " 必须实现OnChangedListener!");  }  }

 

  Activity实现了OnChangedListener就可以接收到对应的事件,这个是不是就是传说中的监听者模式。

  那么activity如何向fragment传递数据呢?

  Fragment类包括两个方法:setArguments和getArguments。setArguments方法必须在fragment attach到activity之前调用,参数是Bundle对象;然后在fragment中调用getArguments方法,获取该fragment实例化时传递进来的Bundle对象。

  4.保存状态

  fragment的生命很大程度上会受到其依附的activity的映像,因此为了保证数据完整性,也需要在适当的时候保存下当前状态:

1   @Override2         public void onSaveInstanceState(Bundle outState) {3             super.onSaveInstanceState(outState);4             outState.putInt("curChoice", mCurCheckPosition);5         }

 

   然后当该fragment再次被重新创建的时候,恢复之前保存的数据:

1  @Override2         public void onActivityCreated(Bundle savedInstanceState) {3             super.onActivityCreated(savedInstanceState);4 5              if (savedInstanceState != null) {6                 // Restore last state7             }8         }

 

 总结:

  •   fragment的使用能够让UI更灵活
  •   感觉如何管理fragment是个关键

其中,图片引用自 ,转载请说明出处~~

转载于:https://www.cnblogs.com/caiwan/archive/2013/01/24/2875306.html

你可能感兴趣的文章
Spring面试题
查看>>
C语言栈的实现
查看>>
代码为什么需要重构
查看>>
TC SRM 593 DIV1 250
查看>>
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
Python-S9-Day127-Scrapy爬虫框架2
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
右侧导航栏(动态添加数据到list)
查看>>
81、iOS本地推送与远程推送详解
查看>>
虚拟DOM
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
关于View控件中的Context选择
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
Spark的启动进程详解
查看>>
使用命令创建数据库和表
查看>>
机器视觉:SSD Single Shot MultiBox Detector
查看>>
201521123044 《Java程序设计》第1周学习总结
查看>>
MIT Scheme 的基本使用
查看>>
在16aspx.com上下了一个简单商品房销售系统源码,怎么修改它的默认登录名和密码...
查看>>