位置: 编程技术 - 正文

Android中的布局优化方法(Android中的布局有哪些)

编辑:rootadmin

推荐整理分享Android中的布局优化方法(Android中的布局有哪些),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:Android中的布局有哪些?( ),Android中的布局文件位于什么目录中,Android中的布局类型和特点?,Android中的布局分别有,Android中的布局文件,Android中的布局文件位于什么目录中,Android中的布局文件位于什么目录中,android中的布局文件通常放在,内容如对您有帮助,希望把文章链接给更多的朋友!

Android开发中的布局很重要吗?那是当然。一切的显示样式都是由这个布局决定的,你说能不重要吗。要实现一个好的布局,不只是实现了、显示出来就完了,不管层次,堆砌代码也可以实现功能,但是这显然违背了Android布局设计的原则。可能你会说,Android布局设计哪有什么原则,我可以明确告诉你,当然有,只要有利于提高最终效果的方法、意识,我们都可以把它提升为原则。在Android布局设计中,这个最终效果就是快的页面加载速度,好的流畅度,而这个方法就太多了,鉴于本人水平有限,下面就说几种自己实践过的、切实有效的方法吧。前奏太长,罗哩罗嗦,好吧,开始说起。

最近做演出项目,碰到了一个以前没见过的错误StackOverflowError,具体错误如下:

查过资料之后才发现,原因就出在布局的嵌套层次上,说明白点儿就是“嵌套层次过深,导致栈溢出”,这样就引出了一个问题,我们在Android开发中经常听到的是内存泄漏、堆溢出(听起来都头皮发麻的OOM),好像很少听说有栈溢出的,好了,找找Android中对栈大小的限制吧。抱歉,没找到,只在支离破碎的国外论坛中间看到有说1K的,有说4K的,反正没看到有官方的说明,纠结良久还是一筹莫展,看哪位大虾如果知道的话就指点一下本鸟吧。。。。。。既然遇到了问题,还是转回头来解决问题吧,无法提高栈的大小,那就只能提高栈的使用率了,最直接的方法就是缩减层级,而且缩减层级还有一个重要的好处就是提高页面加载速度,因为Android中的布局是嵌套加载的,多一层布局就要耗费很长的加载时间。这时候我才体会到了merge的妙用,不只是merge,下面我会结合hierarchyviewer工具来分别讲述一下merge,ViewStub,include在布局优化中的作用。

1、merge

顾名思义,就是合并、融合的意思。使用它可以有效的将某些符合条件的多余的层级优化掉。使用merge的场合主要有两处:

(1) 自定义View中使用,父元素尽量是FrameLayout,当然如果父元素是其他布局,而且不是太复杂的情况下也是可以使用的

(2) Activity中的整体布局,根元素需要是FrameLayout

下面这个例子将融合这两种情况,来展示如何缩减布局层次。

总体显示界面如图所示:

其中粉红色圈住的部分为我们的自定义View。

整个界面的布局layout_mergedemo.xml如下:

[html] view plaincopy<FrameLayout xmlns:android=" xmlns:tools=" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="sp" android:textColor="#FFFF" android:gravity="center_horizontal" android:text="我的家园"/> <com.example.myandroiddemo.MyItemView android:id="@&#;id/myitem_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" /> </FrameLayout> 自定义布局view_item.xml如下:[html] view plaincopy<LinearLayout xmlns:android=" xmlns:tools=" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <ImageView android:id="@&#;id/view_item_img" android:layout_width="dp" android:layout_height="dp" android:scaleType="fitXY"/> <TextView android:id="@&#;id/view_item_txt" android:layout_width="fill_parent" android:layout_height="dp" android:gravity="center_vertical" android:layout_marginLeft="dp" android:textSize="sp" android:textColor="#FFFF"/> </LinearLayout> 自定义View中使用下面来解析布局:[java] view plaincopypublic class MyItemView extends LinearLayout { ...... private void initView(Context context) { mContext = context; View view = LayoutInflater.from(mContext).inflate(R.layout.view_item, this, true); mMyItemImg = (ImageView)view.findViewById(R.id.view_item_img); mMyItemText = (TextView)view.findViewById(R.id.view_item_txt); } ...... }

整个功能开发完成之后,使用hierarchyviewer来看一下布局层次:

我们发现简单的一个功能竟然使用了六层布局,包括每个Window自动添加的PhoneWindow$DecorView和FrameLayout(id/content)。明显可以看到这个布局存在冗余,比如第二层和第三层的FrameLayout,比如第四层的MyItemView(LinearLayout子类)和第五层的LinearLayout,都可以缩减。

好了,该我们的merge标签大显身手了。将布局这样修改:

简化layout_mergedemo.xml:

[html] view plaincopy<merge xmlns:android=" xmlns:tools=" <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="sp" android:textColor="#FFFF" android:gravity="center_horizontal" android:text="我的家园"/> <com.example.myandroiddemo.MyItemView android:id="@&#;id/myitem_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" /> </merge> 简化view_item.xml:[html] view plaincopy<merge xmlns:android=" xmlns:tools=" > <ImageView android:id="@&#;id/view_item_img" android:layout_width="dp" android:layout_height="dp" android:scaleType="fitXY"/> <TextView android:id="@&#;id/view_item_txt" android:layout_width="fill_parent" android:layout_height="dp" android:gravity="center_vertical" android:layout_marginLeft="dp" android:textSize="sp" android:textColor="#FFFF"/> </merge> Android中的布局优化方法(Android中的布局有哪些)

因为这里merge代替的布局元素为LinearLayout,而不是FrameLayout,所以我们需要在自定义布局代码中将LinearLayout的属性添加上,比如垂直或者水平布局,比如背景色等,此处设置为水平布局:

[java] view plaincopyprivate void initView(Context context) { setOrientation(LinearLayout.HORIZONTAL); …… }

OK,就是这么简单,再来看看布局层次吧:

哈哈,只有四层了,加载速度也明显加快,特别是如果布局比较复杂,子View较多的情况下,合理使用merge能大大提高程序的速度和流畅性。

但是使用merge标签还是有一些限制的,具体有以下几点:

(1)merge只能用在布局XML文件的根元素

(2)使用merge来inflate一个布局时,必须指定一个ViewGroup作为其父元素,并且要设置inflate的attachToRoot参数为true。(参照inflate(int, ViewGroup, boolean))

(3)不能在ViewStub中使用merge标签。最直观的一个原因就是ViewStub的inflate方法中根本没有attachToRoot的设置

说到这儿,merge的使用也就讲完了。还想唠叨一下做的演出项目,因为本人水平有限,并且产品提的这个显示需求确实比较BT,所以整个项目的显示框架做了很多嵌套,具体点就是ActivityGroup中嵌套ViewFlipper,然后再嵌套TabHost,然后再嵌套自己的Activity,大体数了一下,最多竟然有几层,My God!知道Android布局设计的原则是什么吗?最好是层以下,尽量不要超过层,如果再多性能就会下降,也可能会出现问题,就是我们看到的StackOverFlow,这个项目被证实也确实在某些低端机上发生了这种错误,比如HTC的某某机型,OPPO的某某机型,(不要声讨我,没有恶意贬低的意思<_>),最终我使用merge缩呀缩呀,把大部分的布局都缩减到了层以下,一测试,通过!

还要说一下,因为Window窗体(比如Activity)加载时会自动添加PhoneWindow$DecorView和FrameLayout(id/content)两层布局,所以如果我们在Activity的自定义布局根元素中使用merge,而且想设置总体背景什么的,可以用(id/content)将FrameLayout取出来,再设置属性,可以这样实现:

[java] view plaincopy//setContentView(R.layout.layout_showset); FrameLayout frameLayout = (FrameLayout)this.getWindow().getDecorView().findViewById(android.R.id.content); frameLayout.setBackgroundResource(R.drawable.bg_repeated_main); LayoutInflater.from(this).inflate(R.layout.layout_showset, frameLayout, true); 将setContentView方法摒弃,改由我们手动添加布局。

好了,就这样吧!!!

2、ViewStub

这是什么玩应儿呢?其实就是一个轻量级的页面,我们通常使用它来做预加载处理,来改善页面加载速度和提高流畅性,ViewStub本身不会占用层级,它最终会被它指定的层级取代。 还是说说演出项目吧,还说?对了,实践才能发现问题嘛,在哪儿发现问题就在那儿改进。由于项目中用到了比较多的动画,而且嵌套布局比较复杂,所以在Android低端机上进行页面切换时候经常让人感觉卡卡的,不怎么流畅,因为页面切换动画和标题旋转动画是同时进行的,所以为了达到更好的体验就需要使用一种方法,在动画进行时尽量的减少其他操作,特别是页面加载重绘。赶紧想办法,起初我想先将要加载的页面所有的组件都初始为gone显示状态,整个页面只留一下加载滚动条,后来发现这是不行滴,因为在Android的机制里,即使是将某一个控件的visibility属性设置为不可见的gone,在整个页面加载过程中还是会加载此控件的。再后来就用到了ViewStub,在做页面切换动画时,只在页面中放一个loading加载图标和一个ViewStub标签,像下面这样:

layout_loading.xml布局文件:

[html] view plaincopy<merge xmlns:android=" <ViewStub android:id="@&#;id/viewstub" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <NetErrAndLoadView android:id="@&#;id/start_loading_lay" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </merge> 这个页面是相当轻量级的,所以导致动画加载速度非常快、而且流畅。等页面切换动画完成之后,我们再指定ViewStub的资源,来加载实际的页面,这个资源就是实际要加载的页面的布局文件。比如要加载MainActivity的布局文件layout_main.xml,onCreate实现如下:[java] view plaincopyprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_loading); mLoadHandler = new Handler(); mLoadingView = (NetErrAndLoadView)findViewById(R.id.start_loading_lay); mLoadingView.startLoading(); mViewStub = (ViewStub)findViewById(R.id.viewstub); mViewStub.setLayoutResource(R.layout.layout_main); mLoadHandler.postDelayed(new Runnable() { @Override public void run() { mViewStub.inflate(); mLoadingView.hide(); } },); } 上面的单位是ms,就是延迟加载的时间。上面使用的是动态添加ViewStub指向布局资源的方法(mViewStub.setLayoutResource(R.layout.layout_main)),当然根据需要可以直接在ViewStub的布局块儿中设置,需要设置ViewStub标签下的layout属性(android:layout="@layout/ layout_main")。 ViewStub也是有少许缺点的,下面所说: 1、 ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不能够再通过ViewStub来控制它了。所以它不适用 于需要按需显示隐藏的情况。 2、 ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。如果想操作一个具体的view,还是使用visibility属性吧。 3、 VIewStub中不能嵌套merge标签。(前面好像说过)不过这些确定都无伤大雅,我们还是能够用ViewStub来做很多事情。 有时候真的不得不佩服google的Android团队的远见性和架构性,这种细微的设计都能考虑的到,想用就有。3、include

制造这个标签纯碎是为了布局重用,在项目中通常会存在一些布局公用的部分,比如自定义标题,我们不需要把一份代码Ctrl C, Ctrl V的到处都是,严重违背程序简洁化、模块儿化的设计思想,毕竟作为现代化的码农,也需要与时俱进,不再抱着以前那种卖代码的思想来编写程序了(一行代码几个钱?)。这里就不写例子了,随便网上搜一下,include的使用一大堆,简单说一下如何调用吧,比如现在有一个公用布局head.xml,如果在其他的布局中引用,只需要这样添加include标签:

[html] view plaincopy<include android:layout_width="fill_parent" android:layout_height="wrap_content" layout="@layout/head" /> 这个标签下的布局在父布局刷新时候同样是会加载的,所以它即不能像merge那样缩减层级,也不能像ViewStub那样轻量级实现延迟加载,它就是用来布局重用的,各有各的疗效嘛,可以理解。 OK,到这儿我也啰嗦完了,现在脑子里只有一个想法,既然Android的设计者都绞尽脑汁帮我们想到了各种便利用途,我们再不使用就不单是脑子有问题的问题了,就是没把用户需求放在第一位,是得罪上帝的。哈哈,说大了,轻喷。。。。。。不过这几个标签确实很有用,建议在合适的地方都体验一下,还是那句话,谁用谁知道<_>。 说明:以上都是基础内容,只不过可能注意用的人不多,这些标签的使用我也是学习,然后用到了项目当中,本人只是结合自己的理解叙述一遍。如果有更好的改进方法,或者是认为上面的文字有误,欢迎交流。

HTTP之Range理解 1、什么是Range?当用户在听一首歌的时候,如果听到一半(网络下载了一半),网络断掉了,用户需要继续听的时候,文件服务器不支持断点的话,则

android压力测试命令monkey详解 一、Monkey是什么?Monkey就是SDK中附带的一个工具。二、Monkey测试的目的?:该工具用于进行压力测试。然后开发人员结合monkey打印的日志和系统打印的日

在Android studio 中配置高德地图api后显示地图遇到的问题 在Androidstudio中按照高德官网中配置地图api后,显示地图时报错如下图原因是高德官网上是拿在eclipse中配置为示例,而在Androidstudio中配置的时候需要去

标签: Android中的布局有哪些

本文链接地址:https://www.jiuchutong.com/biancheng/387565.html 转载请保留说明!

上一篇:CentOS 7下搭建安卓开发环境[Eclipse](centos7如何安装)

下一篇:使用Python的Flask框架来搭建第一个Web应用程序(python flask)

  • 捐赠税前扣除比例表
  • 个体工商户月销售额超10万怎么报税
  • 基础设施道路建设
  • 利润是非限定净现值吗
  • 实收资本一直挂着其他应收款怎么办
  • 材料出入库制度
  • 公对公退款要交税吗
  • 公允价值下降属于资产吗
  • 企业所得税税率有几个档次
  • 房地产开发企业土地增值税清算
  • 银行承兑汇票到期日后多久可以承兑
  • 生产过程中产品的质量保证体系
  • 代扣业务员佣金怎么做账
  • 社保企业二次扣款怎么扣
  • 渔业专业合作社简介
  • 营改增后在建工程转让应缴纳税费有哪些
  • 有限合伙企业清算
  • 分公司税务是独立核算还是非独立
  • 营改增后还有建筑业发票吗
  • 一般纳税人选择简易计税进项税可以抵扣吗
  • 出口企业增值税优惠政策
  • 关于油票的纳税人识别号
  • 建筑企业预交增值税问题尚未得到解决
  • 增值税价外费用不包括
  • 收购公司款项的支付是利好还是利差
  • u盘转移到另一个u盘
  • 一次性计提折旧的政策
  • sxgdsenu.exe - sxgdsenu是什么进程 有什么用
  • win11打开图片
  • 不用命令打开组策略
  • 研发费用加计扣除是什么意思啊
  • 不动产租赁费计入什么科目
  • 公司为员工缴纳社保的基数怎么确定
  • 公司作为股东有什么好处
  • linux操作系统文件系统
  • 手机怎么设置无信号
  • 云霞下的麦田
  • 承兑汇票到期超过10天怎么办
  • 个体经营所得税申报表a
  • 宝塔面板入口
  • 企业销售旧车增值税处理
  • 租赁增值税发票税率
  • 小规模纳税人当月应交增值税怎么算
  • linux mint 下mysql中文支持问题
  • 认缴制和实缴制的区别公司破产
  • 现金发放工资会计科目怎么写
  • 专项扣除影响实绩吗
  • 增值税报表附表三
  • 其他债权投资计提减值影响所有者权益吗
  • 固定资产原值增加折旧怎么算
  • 个体户 查账
  • 劳动合同要给税收吗
  • 小规模季度超过45万了怎么缴纳
  • 工厂加工费如何计算
  • 计提本月工资会计怎么做账
  • 结转库存商品需要附件吗
  • 专利权转让的条件
  • 天然气管道安装费多少钱一米
  • 报关金额多报了900美金怎么办
  • 印花税应税凭证是还是否
  • sql server real
  • win10创意者更新易升
  • 微软一般什么时候活动
  • windows优化软件
  • linux中man的用法
  • rsync如何同步隐藏文件和排除文件?rsync同步隐藏文件和排除文件的方法
  • win8提升模式
  • ubuntu20关机卡在logo
  • hookproxy.dll
  • Linux操作系统中怎么永久设置环境变量?
  • Linux查看内存的命令是
  • psrameters
  • 导入项目出现这个问题
  • css行与行之间的间距怎么调
  • python中的is和==的区别
  • android使用so
  • 小规模纳税人开1%普票怎么报税
  • 亦庄税务局电话号码
  • 大修费属于什么费用
  • 公司租房的房产税应计入哪个科目
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设