1.Androidç»ä»¶ä¹Fragmentï¼ä¸ï¼---åºç¡ç¥è¯ä¸è¿ç¨
2.ViewStub你肯定听过,但是这些细节了解吗?
3.android 什么时候必须用inflater
4.详解LayoutInflater.inflate()
5.setContentView()及LayoutInflater布局加载源码分析
6.Android中使用ViewStub提高布局性能
Androidç»ä»¶ä¹Fragmentï¼ä¸ï¼---åºç¡ç¥è¯ä¸è¿ç¨
Fragmentæ¯Android3.0åå¼å ¥çä¸ä¸ªæ°çAPIï¼ä»åºç°çåè¡·æ¯ä¸ºäºéåºå¤§å±å¹çå¹³æ¿çµèï¼ å½ç¶ç°å¨ä»ä»ç¶æ¯å¹³æ¿APP UI设计çå® å¿ï¼èä¸æ们æ®éææºå¼åä¹ä¼å å ¥è¿ä¸ªFragmentï¼ æ们å¯ä»¥æä»çæä¸ä¸ªå°åçActivityï¼å称Activityç段ï¼æ³æ³ï¼å¦æä¸ä¸ªå¾å¤§ççé¢ï¼æ们 å°±ä¸ä¸ªå¸å±ï¼åèµ·çé¢æ¥ä¼æå¤éº»ç¦ï¼èä¸å¦æç»ä»¶å¤çè¯æ¯ç®¡çèµ·æ¥ä¹å¾éº»ç¦ï¼è使ç¨Fragment æ们å¯ä»¥æå±å¹ååæå åï¼ç¶åè¿è¡åç»ï¼è¿è¡ä¸ä¸ªæ¨¡ååç管çï¼ä»èå¯ä»¥æ´å æ¹ä¾¿çå¨ è¿è¡è¿ç¨ä¸å¨æå°æ´æ°Activityçç¨æ·çé¢ï¼å¦å¤Fragment并ä¸è½åç¬ä½¿ç¨ï¼ä»éè¦åµå¥å¨Activity ä¸ä½¿ç¨ï¼å°½ç®¡ä»æ¥æèªå·±ççå½å¨æï¼ä½æ¯è¿æ¯ä¼åå°å®¿ä¸»Activityççå½å¨æçå½±åï¼æ¯å¦Activity 被destoryéæ¯äºï¼ä»ä¹ä¼è·çéæ¯ï¼å¼ç¨å®æ¹çä¸å¼ å¾çï¼å ¶å®å·²ç»è¯´æé®é¢äºï¼å°±æ¯ä¸ºäºæ´å¥½çéé 大å±ï¼å¨å¤§å±çæ¶åï¼ä¸éè¦å»å¨ä¸ä¸ªactivityå é¨éè¿å¤æçå¸å±åçé¢å»å®ç°ï¼åªéè¦å»å¨ä¸ä¸ªactivityå é¨ï¼éè¿å¤ä¸ªfragmentæ¥åçé¢å¸å±å®ç°å³å¯ï¼èä¸é对äºå¤ä¸ªfragmentæ¥è¯´ï¼ æ¯ä¸ªfragmentæåç¬ççå½å¨æï¼
Demoæ ·ä¾ï¼æ们å¨ä¸ä¸ªçé¢ä¸ï¼æä¸ä¸ä¸¤ä¸ªfragmentï¼å¦å¾æ示ï¼
Step 2: Fragmentå建ï¼è§å¾å è½½ï¼æ°æ®èµå¼
BlankFragment .java
Step 3: Activityå¨onCreate( )æ¹æ³ä¸è°ç¨setContentView()ä¹åè°ç¨FragmentTransaction è¿è¡äºå¡æ交
FragmentTestActivity.java
å¨xmlä¸å£°æ两个fragmentï¼æå®ä¸ºå ·ä½çfragment
Step 1:å®ä¹Fragmentçå¸å±ï¼å°±æ¯fragmentæ¾ç¤ºå 容ç
Step 2:èªå®ä¹ä¸ä¸ªFragmentç±»,éè¦ç»§æ¿Fragmentæè ä»çåç±»,éåonCreateView()æ¹æ³ å¨è¯¥æ¹æ³ä¸è°ç¨:inflater.inflate()æ¹æ³å è½½Fragmentçå¸å±æ件,æ¥çè¿åå è½½çview对象
BlankFragment.java
Step 3:å¨éè¦å è½½FragmentçActivity对åºçå¸å±æ件ä¸æ·»å fragmentçæ ç¾ï¼ è®°ä½ï¼nameå±æ§æ¯å ¨éå®ç±»åå¦ï¼å°±æ¯è¦å å«Fragmentçå åï¼å¦:
Step 4: Activityå¨onCreate( )æ¹æ³ä¸è°ç¨setContentView()å è½½å¸å±æ件å³å¯!
é对å¨ä¸ä¸ªActivityä¸çæ个Layoutä¸åæ¢Fragment,,æ é两ç§æ¹æ³ï¼
æ们èªå·±çä¸ä¸æ¹æ³æ³¨é
æºç æ¹æ³æ³¨ééé¢è¯´çå¾æç½ï¼è¿ä¸ªæ¹æ³ä¼ç§»é¤ææçfragmentï¼ç¶åæ·»å å½åçfragmentã
è¿æ¶å为两ç§æ åµï¼ä¸ç§æ¯fragmentå·²æ并ä¸å¨åå°å±ç¤ºï¼ä¸ç§æ¯æªææè å¨åå°ï¼é对äºåè ï¼æ¤æ¶replaceï¼çå½å¨æä¸ä¼åçååï¼é对åè ï¼çå½å¨æä¼éæ°èµ°
å为两ç§æ åµï¼ä¸ç§fragmentå·²åå¨ï¼ä¸ç§æªåå¨ï¼é对äºåè ï¼çå½å¨ææ ååï¼ä½æ¯ä¼åè°onHiddenChangedæ¹æ³ï¼é对äºåè ï¼çå½å¨æä¼å建ä¸æ¬¡ã
1.Fragmentæ¯Googleå®æ¹å¼å ¥çä¸ä¸ªä¸ºäºéé 大å±ãå¤é¡µé¢çä¸ä¸ªç»ä»¶ãæ¨å¯ä»¥ç解为å®å°±æ¯ä¸ä¸ªç±»èå·²ï¼åªä¸è¿éé¢å å«äºViewï¼å¹¶ä¸ä¸activityççå½å¨æè¿è¡äºå ³èã
2.å¨æå è½½ä¸éæå è½½ç¸å¯¹æ¥è¯´ï¼å»ºè®®ä½¿ç¨å¨æå è½½ï¼éæå è½½åºå®å¨äºxmlæ件ä¸ï¼æ°¸è¿ä¸åã
3.replaceçfragmentå¦æä¸å¨åå°ï¼ä¼æ§è¡ææçå½å¨æï¼åä¹ä¸ä¼æ§è¡ä»»ä½çå½å¨ææ¹æ³ï¼hide+showçå½å¨æ并ä¸ä¼åçååï¼ä½æ¯ä¼åè°onHiddenChangedæ¹æ³ï¼å¨å®é å¼åä¸ï¼å»ºè®®addä¹åï¼ä½¿ç¨hide+showæ¥æä½fragmentï¼ä¸æ¹é¢åå°èµæºçéå¤å è½½åå建ï¼å¦å¤ä¸æ¹é¢æåç¨æ·ä½éªæã
4.fragmentççå½å¨æ大ä½ä¸åactivityä¸è´ï¼ä½æ¯åæååæå¤äºä¸äºä¸è¥¿ï¼å 为fragmentå é¨æviewï¼é£ä¹è¿ä¸ªviewéè¦è¿è¡å建ãç¶åæ·»å å°activityå é¨ï¼æ以ç¸åºçå¨onCreateä¸onStartä¹é´å°±å¤äºå 个æ¹æ³-onCreateViewãonViewCreatedãç¸åçéçï¼fragmentçviewä¸activity解ç»ï¼ä¹ç¸åºçå¨onStopä¸onDestoryä¹é´å¤ä¸ªæ¹æ³-onDestroyViewãonAttachä¸onDetachå¯ä»¥ç解为è§å¾ä¸activity产çå ³èåæ¥è§¦å ³èï¼æ¯æå¼å§åæåçæ¥éª¤ã
Demoå°å
ViewStub你肯定听过,但是这些细节了解吗?
1什么是ViewStub
ViewStub是一个看不见的、不占空间的虚拟视图,用于懒加载布局。当它变为可见或执行inflate()方法时,openjdk源码编译所指定的布局才会加载替换ViewStub。ViewStub存在于视图层次结构中,直到调用setVisibility(int)或inflate()方法。加载完成后,ViewStub会被移除,其占用的空间被新的布局替代。
2ViewStub构造方法
构造方法用于初始化ViewStub,关键方法包括setVisibility和inflate()。需要注意的是,ViewStub只能被inflate一次,inflate后ViewStub对象将被置为空。ViewStub仅用于加载一个布局文件,而不是特定的View。
3inflate()方法解析
inflate()方法是加载布局的关键实现,其核心在于将指定的激励广告源码布局加载到视图层次结构中,替换ViewStub。使用该方法时,ViewStub将执行其功能,并在加载完成后被移除。
4WeakReference使用
WeakReference用于管理对象的创建,确保内存资源的有效管理。在使用ViewStub时,WeakReference可以帮助避免内存泄漏问题。
5ViewStub为何无大小与不绘制
ViewStub在源码中被设计为无显示内容的特殊View,其draw和dispatchDraw方法被重写为不执行任何操作。onMeasure方法同样不执行任何操作,直接设置尺寸为0,以确保其在加载布局时不会占用任何空间。
6ViewStub为何不绘制
ViewStub通过设置WILL_NOT_DRAW标志来优化性能。当设置为true时,onDraw()方法将不会被调用,避免不必要的绘制过程,从而提高效率。
7可以多次inflate()吗
ViewStub对象只能被inflate一次,之后将被置为空。tasker源码乱码因此,再次尝试inflate将导致错误。理解其内部实现机制有助于避免常见的使用错误。
8ViewStub不支持merge
ViewStub不支持包含merge标签的布局文件。尝试使用这样的布局将导致异常,因此在设计布局时需注意这一点。
9ViewStub使用场景
ViewStub常用于处理页面状态切换,如显示数据为空、加载失败或网络错误的UI。它支持全局和局部定制,能够优化加载速度并减少资源消耗,提高用户体验。
ViewStub总结分析
掌握ViewStub的原理和应用有助于在实际开发中提高代码效率和用户体验。理解其内部机制,如构造方法、inflate()方法、为何无大小与不绘制等,对于合理使用ViewStub至关重要。
android 什么时候必须用inflater
在实际开发中LayoutInflater这个类还是非常有用的,它的224的源码作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。 具体作用: 1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。
LayoutInflater 是一个抽象类,在文档中如下声明:
publicabstractclass LayoutInflater extends Object
获得 LayoutInflater 实例的三种方式
1.LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()
2.LayoutInflater localinflater =(LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
3. LayoutInflater inflater = LayoutInflater.from(context);
其实,这三种方式本质是相同的,从源码中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是调用 PhoneWindow 的getLayoutInflater()方法,看一下该源代码:
public PhoneWindow(Context context) { super(context); mLayoutInflater = LayoutInflater.from(context); }
可以看出它其实是调用 LayoutInflater.from(context)。
LayoutInflater.from(context):
publicstatic LayoutInflater from(Context context) { LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (LayoutInflater == null) { thrownew AssertionError("LayoutInflater not found."); } return LayoutInflater; }
可以看出它其实调用 context.getSystemService()。
结论:所以这三种方式最终本质是都是调用的Context.getSystemService()。
inflate 方法 通过 sdk 的 api 文档,可以知道该方法有以下几种过载形式,返回值均是 View 对象,如下:
public View inflate (int resource, ViewGroup root) public View inflate (XmlPullParser parser, ViewGroup root) public View inflate (XmlPullParser parser, ViewGroup root, booleanattachToRoot) public View inflate (int resource, ViewGroup root, boolean attachToRoot)
示意代码:
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test)); //EditText editText = (EditText)findViewById(R.id.content);// error EditText editText = (EditText)view.findViewById(R.id.content);
对于上面代码,指定了第二个参数 ViewGroup root,抽奖源码制作当然你也可以设置为 null 值。
注意:
·inflate方法与 findViewById 方法不同;
·inflater 是用来找 res/layout下的 xml 布局文件,并且实例化;
·findViewById() 是找具体 xml 布局文件中的具体 widget 控件(如:Button、TextView 等)。
详解LayoutInflater.inflate()
LayoutInflater.inflate()是Android开发中常见方法,广泛应用于Fragment添加布局文件或RecyclerView Adapter为item添加布局。此方法接收三个参数:resource、root 和 attachToRoot。resource参数是目标布局文件,root参数为布局的根参数,attachToRoot参数决定是否将resource依附于root。
官方文档解释,attachToRoot为true时,resource指定的布局文件会依附于root指定的ViewGroup,方法返回root参数,反之返回填充并返回resource指定的布局文件。具体实现参见源码。
总结而言,attachToRoot参数决定布局文件的依附性,false时root仅用于创建正确的LayoutParams的子类,true时布局文件依附root。
具体应用场景如下:
1. inflate(R.layout.xxx,null):生成布局文件,宽高属性参照父布局,无效的宽高修改不会影响显示效果。
2. inflate(R.layout.xxx,parent,false):加入父布局,布局文件的宽高属性有效,显示宽度和高度符合布局文件设定。
3. inflate(R.layout.xxx,parent,true):加入父布局且依附root,布局文件依附root。若root为ListView等,调用addView方法时出错,因此在Adapter内使用attachToRoot为true会报错。适用于为Fragment创建布局时,布局文件会添加到父activity中盛放fragment的布局中。
setContentView()及LayoutInflater布局加载源码分析
setContentView()和LayoutInflater布局加载源码深度解析
当我们在Android应用中调用setContentView()时,其实涉及到了一系列复杂的流程。这个过程主要分为三个步骤:系统布局加载、LayoutInflater初始化以及LayoutInflater布局加载。 首先,setContentView()方法通过Activity的PhoneWindow对象加载布局。在判断mContentParent是否为空后,会创建DecorView,然后将自定义的activity_main_layout加载到mContentParent,这个mContentParent对应id为R.id.content的Layout。接着,系统会加载一个包含R.id.content的系统布局到DecorView中。 LayoutInflater的初始化过程关键在于其作为系统服务注册在SystemServiceRegistry中。当我们通过LayoutInflater.from(this)获取实例时,实际上是通过SystemServiceRegistry获取并初始化LayoutInflater的。 LayoutInflater的布局加载流程则涉及xml预编译、View的反射创建以及递归解析子布局。在inflate方法中,会先检查根节点标签是否为"merge",然后决定是否递归加载子布局并决定是否添加到父布局中。View的创建则可能通过自定义的Factory进行拦截和定制。 总结来说,setContentView()和LayoutInflater的交互使得我们能够灵活地加载和定制Activity的布局。通过理解这些源码细节,开发者可以更好地控制和优化应用的界面显示。Android中使用ViewStub提高布局性能
在Android开发中,使用ViewStub可以提升布局性能,特别是在面对复杂视图时。ViewStub是一种特殊的视图,能够在需要时延迟加载布局资源,从而提高整体性能。
首先,我们了解一下ViewStub。它在Java编程中相当于一个用于替代其他代码的临时程序模块。具体到Android中,ViewStub用于延迟加载布局资源,避免在应用启动时加载不必要的视图。
ViewStub的使用场景通常在布局中存在多个重复或动态生成的视图元素时。例如,在一个应用的首页,如果包含了一系列可以动态显示或隐藏的广告条,使用ViewStub可以在用户点击或滑动时动态加载和显示这些广告,从而提高性能。
要使用ViewStub,只需在XML布局文件中使用``标签,并设置其`android:layout`属性指向要加载的布局资源。在代码中,可以通过调用`inflate()`方法或设置`visibility`为`VISIBLE`来触发布局的加载。
值得注意的是,ViewStub不直接支持在布局中使用``标签。然而,通过间接的方式,如使用``标签,可以实现对特定视图的延迟加载。在验证过程中,直接使用``标签会导致崩溃,而使用间接方式则正常运行,表明ViewStub对间接引用的支持良好。
深入理解ViewStub的实现方式,可以发现`inflate()`方法和`setVisibility()`方法的共同点在于它们都可以实现加载布局,但`setVisibility()`方法只在ViewStub首次延迟初始化且`visibility`属性非`GONE`时才调用`inflate()`方法。
通过研究ViewStub的源码,我们可以更全面地理解其工作原理。此外,关于如何优化视图和提高布局性能的探讨,能够对开发者大有裨益。
此外,作者计划在知乎上进行一场名为《我学安卓的那些套路》的直播分享会,旨在分享学习Android的经验和心得。直播内容涵盖了学习路径、常见问题解决策略、优化技巧等多个方面。对于对Android开发感兴趣或有疑问的朋友,欢迎参与直播,获取更多实用知识。