Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-04-17:LinearLayout, FrameLayout, RelativeLayout 哪个效率高, 为什么? #30

Open
Moosphan opened this issue Apr 17, 2019 · 23 comments

Comments

@Moosphan
Copy link
Owner

No description provided.

@zhuoCreator
Copy link

LinearLayout

@xleix
Copy link

xleix commented Apr 17, 2019

FrameLayout > RelativeLayout > LinearLayout

@canyie
Copy link

canyie commented Apr 17, 2019

看使用场景,
如果非常简单的情况(比如就一个子View),那当然是FrameLayout最好,LinearLayout其次,RelativeLayout最低
如果比较复杂,使用LinearLayout比RelativeLayout需要更多的布局嵌套,那还不如用RelativeLayout

@wjwang0914
Copy link

那这个效率更高,还使用场景,如果同级层次结构就能实现的LinearLayout的性能肯定要高于RelativeLayout性能,但是如果使用LinearLayout要多级层次结构才能实现,那肯定使用RelativeLayout的性能更高,所以说要看性能具体看使用场景

@Ssuiyingsen
Copy link

尽量减少嵌套

@Carey0732
Copy link

在布局不复杂的情况下 FrameLayout>LinearLayout>RelativeLayout 布局复杂的情况就是RelativeLayout>LinearLayout,framelayout只适合单个子布局,尽量不要在复杂嵌套多的布局使用

@kongxiaoan
Copy link

对于比较三者的效率那肯定是要在相同布局条件下比较绘制的流畅度及绘制过程,在这里流畅度不好表达,并且受其他外部因素干扰比较多,比如CPU、GPU等等,我说下在绘制过程中的比较,1、Fragment是从上到下的一个堆叠的方式布局的,那当然是绘制速度最快,只需要将本身绘制出来即可,但是由于它的绘制方式导致在复杂场景中直接是不能使用的,所以工作效率来说Fragment仅使用于单一场景,2、LinearLayout 在两个方向上绘制的布局,在工作中使用页比较多,绘制的时候只需要按照指定的方向绘制,绘制效率比Fragment要慢,但使用场景比较多,3、RelativeLayout 它的没个子控件都是需要相对的其他控件来计算,按照View树的绘制流程、在不同的分支上要进行计算相对应的位置,绘制效率最低,但是一般工作中的布局使用较多,所以说这三者之间效率分开来讲个有优势、不足,那一起来讲也是有优势、不足,所以不能绝对的区分三者的效率,好马用好铵 那需求来说

@18361237136
Copy link

这个需要分情况来说。
FrameLayout是一个堆叠布局,LinearLayout是两个方向上的排列布局,RelativeLayout是根据其他控件来确定位置。
画布局最重要的是减少层级嵌套。
简单的布局,FrameLayout>LinearLayout>RelativeLayout
复杂的布局:与上面相反

@whiteShirtCoder
Copy link

其实从绘制角度上来说,framelayout针对的是单一布局,它是从左上角开始绘制的一个堆叠布局,从其内部实现来看,它的绘制过程是较简单的,LinearLayout是一个方向性布局,在实际绘制过程中,通过方向上的计算来绘制布局的,而RelativeLayout是根据控件的位置来确定位置绘制的,简单布局的话FrameLayout>LinearLayout>RelativeLayout,但是较复杂布局的话,RelativeLayout>LinearLayout>FrameLayout

@wangfengye
Copy link

相同嵌套层级下: FrameLayout>LinearLayout>RelativeLayout ,现在问这个问题不加上ConstraintLayout
?

@Petterpx
Copy link

Petterpx commented Apr 19, 2019

这个吧,如果单纯看性能 Frgament>LinearLayout>RelativeLayout
很多东西,上面的大佬们已经说过了,我就补充一点,及对一点优化的建议。
View在绘制的时候,RelativeLayout会对子View做两次measure。这是由于RelativeLayout是基于相对位置的,而且子View会在横向和纵向两个方向上分布,因此,需要在横向和纵向分别进行一次measure过程。而LinearLayout只进行纵向或横向的测量,所以measure的时间会比RelativeLayout少很多。但是如果设置了 weight,在测量的过程中,LinearLayout会将设置过weight的和没设置的分别测量一次,这样就导致measure两次。所以我们一般再使用时如果布局很复杂,那么建议使用RelativeLayout减少层级。也推荐使用include引入布局。
LinearLayout的好处就是可以进行适配屏幕,也是因为它可以用比例来卡,所以我们在使用时,具体使用场景由我们的布局来定吧。
4/20 修改回答

@chenqi5256969
Copy link

chenqi5256969 commented Apr 20, 2019

如果不考虑布局的排版要求,那肯定是FrameLayout大于LinearLayout,LinearLayout和RelativeLayout相差无几。

  1. FrameLayout中的子元素都堆在屏幕的左上角,子元素不能指定位置,绘制起来当然效率高。
    2.在阅读RelativeLayout和LinearLayout的源码中,我发现有这么一段注释:
    //So, instead of running the code twice, we just set the width to a "default display width"
    我们没有运行代码两次,而是将宽度设置为“默认显示宽度”
    楼上说的都是RelativeLayout会绘制两次,这到底是怎么回事???
    @Petterpx @Moosphan @kongxiaoan

@Petterpx
Copy link

如果不考虑布局的排版要求,那肯定是的FrameLayout大于LinearLayout中,LinearLayout中和RelativeLayout的相差无几。

  1. FrameLayout中的子元素都堆在屏幕的左上角,子元素不能指定位置,绘制起来当然效率高
    .2。在阅读RelativeLayout和LinearLayout的源码中,我发现有这么一段注释:
    //所以,而不是跑步代码两次,我们只是
    将宽度设置为“默认显示宽度” 我们没有运行代码两次,而是将宽度设置为“默认显示宽度”
    楼上说的都是RelativeLayout会绘制两次,这到底是怎么回事???
    @Petterpx @Moosphan @kongxiaoan

首先很抱歉,我上面的回答有误,实际上应该是 测量(Measure)两次,回到原因上面,是因为:
RelativeLayout会对子View做两次measure。这是由于RelativeLayout是基于相对位置的,而且子View会在横向和纵向两个方向上分布,因此,需要在横向和纵向分别进行一次measure过程。而LinearLayout只进行纵向或横向的测量,所以measure的时间会比RelativeLayout少很多。但是如果设置了 weight,在测量的过程中,LinearLayout会将设置过weight的和没设置的分别测量一次,这样就导致measure两次。

@MicroKibaco
Copy link

LinearLayout 和 RelativeLayout 以及FrameLayout 可以完全放弃掉了,建议选择 ConstrainLayout 和 MotionLayout

@suagger
Copy link

suagger commented Nov 15, 2019

在布局简单的情况下使用FrameLayout > LinearLayout > RelativeLayout,因为RelativeLayout会让子View调用两次OnMeasure方法,而LinearLayout只需要调用一次,LinearLayout 在有weight时,也会调用子View2次onMeasure。在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。使用多层LinearLayout嵌套时,尽量使用RelativeLayout,在时间上此时RelativeLayout耗时更小,RelativeLayout中尽量使用padding代替margin,也可以使用include等方法进行布局的优化

@chunlinchulv
Copy link

FrameLayout>LinearLayout>RelativeLayout(简单布局)
RelativeLayout>LinearLayout>FrameLayout(复杂布局)

@maoruibin
Copy link

LinearLayout, FrameLayout, RelativeLayout 哪个效率高

效率可以分为两方面讲:

  • 使用效率
  • 绘制性能效率

在开发中,更快的更健壮的完成任务是每个开发人员都追求的,所以在写布局时,如何更有效率呢?不一样的场景选用不一样的布局。

  • 简单的布局优先使用 LinearLayout
  • 对于有层叠方式的布局使用 FrameLayout
  • 布局元素比较多,有互相依赖,则使用 RelativeLayout

设计布局关键点

  • 减少布局层次,如果能有效减少布局层次,使用效率较低的 RelativeLayout 也无妨。
  • 避免过渡绘制,注意背景颜色使用。

就绘制效率而言

  • LinearLayout 跟 FrameLayout 的绘制性能都优于 RelativeLayout,后者因为要计算与子布局的定位关系,所以会进行两次 measure。
  • LinearLayout 在使用了 weight 时,绘制跟 RelativeLayout 效率一样,也会执行两次 measure。

具体绘制效率对比参见文章 Android中RelativeLayout和LinearLayout性能分析 - 简书

@zhouguizhi
Copy link

这些没有从源码分析中找到答案,都是没啥说服依据

@mlinqirong
Copy link

简单同层次布局FrameLayout>LinearLayout>RelativLayout 复杂嵌套层次的话RelativLayout >LinearLayout>FrameLayout
view在绘制的时候RelativLayout 布局横向和纵向各测量一次 LinearLayout只往指定的方向测量一次 如果LinearLayout设置了weight
LinearLayout会向设置weight和没设置的各测量一次 所以在复杂的布局RelativLayout效率高于LinearLayout

@MicroKibaco
Copy link

MicroKibaco commented Dec 16, 2021 via email

@hellowwwwp
Copy link

hellowwwwp commented May 23, 2022

这个吧,如果单纯看性能 Frgament>LinearLayout>RelativeLayout 很多东西,上面的大佬们已经说过了,我就补充一点,及对一点优化的建议。 View在绘制的时候,RelativeLayout会对子View做两次measure。这是由于RelativeLayout是基于相对位置的,而且子View会在横向和纵向两个方向上分布,因此,需要在横向和纵向分别进行一次measure过程。而LinearLayout只进行纵向或横向的测量,所以measure的时间会比RelativeLayout少很多。但是如果设置了 weight,在测量的过程中,LinearLayout会将设置过weight的和没设置的分别测量一次,这样就导致measure两次。所以我们一般再使用时如果布局很复杂,那么建议使用RelativeLayout减少层级。也推荐使用include引入布局。 LinearLayout的好处就是可以进行适配屏幕,也是因为它可以用比例来卡,所以我们在使用时,具体使用场景由我们的布局来定吧。 4/20 修改回答

这个才是正确解, LinearLayout 使用 weight 时和 RelativeLayout 一样都要测量两次, 所以就是 Fragment > LinearLayout >= RelativeLayout

@MicroKibaco

This comment was marked as off-topic.

1 similar comment
@MicroKibaco

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests