精华内容
下载资源
问答
  • 布局优化

    2015-07-23 17:05:41
    布局优化

    1、Include

    将 其他的xml文件包含的当前xml文件中来

    common_nav.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000"
        android:paddingBottom="10dp"
        android:paddingTop="10dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="#FFF"
            android:layout_alignParentLeft="true"
            android:text="返回"
            android:paddingLeft="10dp"
            android:layout_centerVertical="true"
            />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:textColor="#FFF"
            android:layout_centerInParent="true"
            android:text="include优化"
            android:layout_centerVertical="true"
            />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="#FFF"
            android:layout_alignParentRight="true"
            android:text="前进"
            android:paddingRight="10dp"
            android:layout_centerVertical="true"
            />
    </RelativeLayout>
    

    activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent"  tools:context=".MainActivity">
    
        <include layout="@layout/common_nav"/>
    </RelativeLayout>
    

    这里写图片描述

    2、merge

    目的是通过删减多余或者额外的层级,从而优化整个Android Layout的结构。核心功能就是减少冗余的层次从而达到优化UI的目的!—转载

    3、ViewStub

    延时加载view

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent"  tools:context=".MainActivity">
    
    
        <ViewStub
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout="@layout/common_nav"
            android:id="@+id/viewStub"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加载"
            android:id="@+id/btn"
            />
    </RelativeLayout>
    
    package com.example.administrator.layoutoptimize;
    
    import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewStub;
    import android.widget.Button;
    
    
    public class MainActivity extends ActionBarActivity {
        private boolean inflated = false;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button btn = (Button)findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ViewStub viewStub = (ViewStub)findViewById(R.id.viewStub);
                    if(!inflated){
                        inflated = true;
                        viewStub.inflate();
                    }
                }
            });
        }
    }
    
    展开全文
  • Android布局优化

    2018-01-04 16:40:24
    布局优化

    渲染基本知识

    Android系统每隔16ms就重新绘制一次Activity,也就是说,我们的应用必须在16ms内完成屏幕刷新的全部逻辑操作,即每一帧只能停留16ms。
    渲染操作通常依赖于两个核心组件:CPU与GPU:
    * 在CPU方面,最常见的性能问题是不必要的布局和失效
    * 在GPU方面,最常见的问题是我们所说的过度绘制(overdraw)

    过度绘制

    Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面, 如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。

    开启过度绘制检测:设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示GPU过度绘制

    过渡绘制

    • 蓝色: 意味着overdraw 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。
    • 绿色: 意味着overdraw 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
    • 淡红: 意味着overdraw 3倍。像素绘制了四次,小范围可以接受。
    • 深红: 意味着overdraw 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。

    如何避免过度绘制

    去掉window的默认背景

    我们的Activity使用的Theme可能会默认的加上背景色,不需要的情况下可以去掉。

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">    
        <item name="windowBackground">null</item>
    </style>

    或者在Activity中进行设置

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().setBackgroundDrawable(null);
    }

    避免背景色的重复设置

    有时候在根布局中设置了背景颜色之后,单独的View,比如TextView就可以不用再设置背景颜色了。
    这个主要是结合UI设置,在写布局文件的时候稍加注意就可以避免的

    clipRect的使用

    我们可以通过canvas.clipRect()来 帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。

    减少嵌套层次及控件个数

    通过Hierarchy Viewer这个方便可视化的工具,可以得到:树形结构总览、布局view、每一个View(包含子View)绘制所花费的时间及View总个数。
    备注: Hierarchy Viewer不能连接真机的问题可以通过ViewServer这个库解决;

    Android的布局文件的加载是LayoutInflater利用pull解析方式来解析,然后根据节点名通过反射的方式创建出View对象实例;

    Merge

    减少视图层级。 至于为什么要减少视图层级上面已经说过了。
    < merge/>标签可用于两种典型情况:
    * 布局顶结点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity内容试图的parent view就是个FrameLayout,所以可以用merge消除只剩一个。
    * 某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自动被忽略,而将其子节点全部合并到主布局中。

    ViewStub

    ViewStub称之为“延迟化加载”,不仅可以提高性能,也可以节省内存(初始化对象不被创建)。
    App里常见的视图如蒙层、小红点,以及网络错误、没有数据等公共视图,使用频率并不高,如果每一次都参与绘制其实是浪费资源的,都可以借助ViewStub标签进行延迟初始化,仅当使用时才去初始化。

    <ViewStub
        android:id="@+id/view_stub"
        android:layout="@layout/item_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    ViewStub viewStub = (ViewStub)view.findViewById(R.id.view_stub);
    viewStub.inflate();

    include

    这玩意儿其实对于布局优化没有多大的作用,但是也是布局中的一个技巧。
    主要功能是对布局进行复用

    SpaceView

    Space标签于4.0添加的,继承自View主要用于占位,google官方解释为

    Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.
    
    Space是一个轻量级的View,一般用于分隔组件,布局或者在组件布局之间产生间隔

    Android中RelativeLayout和LinearLayout性能分析

    直接说结论:

    1. RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure。 所以LinearLayout在没有weight时,效果要更高一点
    2. RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin。
    3. 在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。

    View优化

    从内优化

    1. 减少View层级
    2. 去除不必要的背景
    3. 尽可能减少使用margin,padding,可以在父View中控制。
    4. 去除不必要的scollbar(onDraw)
    5. 减少使用渐变(onDraw)

    从外优化

    1. 布局嵌套过于复杂
    2. View的过度绘制
    3. View的频繁重新渲染
    4. UI线程中进行耗时操作
    5. 冗余资源以及错误逻辑导致加载和执行缓慢
    6. 频繁触发gc,导致渲染受阻

    布局小技巧

    viewFillper

    android:clipChildren

    android:clipToPadding

    相关链接

    Android 性能优化(二)之布局优化面面观
    Android性能优化第(十)篇—布局优化

    展开全文
  • Android 布局优化

    2018-08-30 18:17:37
    Android 布局优化,(含 include、Viewstub、merge的用法)
  • 详解Android布局优化

    2020-08-27 18:52:09
    本篇文章给大家详细分析了Android布局优化的相关知识点以及注意事项,对此有需要的朋友可以参考学习下。
  • 布局优化选择合适的布局使用include标签来共享布局使用ViewStub标签来实现布局的延迟加载merge标签的使用布局中背景颜色的设置要慎重尽量使用CompoundDrawable使用Lint检测 这一次我们来说说有关布局优化的问题。...

    这一次我们来说说有关布局优化的问题。布局是非常重要的,写的不好会很影响性能的。布局优化的思路其实很简单,基本上就是减少布局文件的嵌套与减少不必要的绘制。这个问题很容易理解,布局中的层级减少了,就意味着Android系统的绘制时的工作量减少了,那么性能自然就会上来。下面我们就聊一聊布局如何优化。

    选择合适的布局

    在能满足布局要求的情况下尽量使用消耗性能较低的ViewGroup,比如:如果一个布局既可以使用LinearLayout来布局也可以使用RelativeLayout来布局,这时我们该选择什么呢?首先我们知道越复杂的功能实现起来也越复杂,在源码中也可以看到,RelativeLayout比LinearLayout发杂的多(内部需要考虑水平方向和竖直方向上的依赖,造成两次遍历)。由此我们就能想到,在这种情况下,我们就选择LinearLayout。FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup。但很多时候我们单纯的通过一个LinearLayout或者FrameLayout是无法实现一个布局效果的,需要通过嵌套的方式来完成。这种情况下,不建议使用嵌套,这样很耗费程序的性能,建议使用RelativeLayout或者约束布局来完成。

    使用include标签来共享布局

    我们在开发时经常遇到好多页面都有相同的布局,这时我们每一个页面都要写一个吗?回答时no,要是都写得话就造成了代码的重复。我们可以将共用的布局抽离出来,独立写成一个XML文件,然后在需要它的页面中使用include标签把它引进来,这样不仅减少了代码量,而且修改起来也非常方便,不需要去每个页面中一个一个的去修改了,只需要修个这一个文件就可以了。使用:

    <include layout="@layout/title"/>
    

    < include>标签只支持android:layout_开头的属性,比如android:layout_width,android:layout_height,其他属性暂不支持,但是有一个特例:id属性,如果< include>制定了这个id属性,同时被包含的布局文件的跟布局页包含了id数据,这时会以< include>中的id属性为准。另外需要注意的是:当< include>标签中制定了android:layout_*这样的属性,那么必须要有android:layout_width属性和android:layout_height属性,否则android:layout_*属性是无法生效的。

    使用ViewStub标签来实现布局的延迟加载

    ViewStub是一种不可视并且大小为0的视图,因此他本身不参与任何的布局和绘制过程,他可以延迟到运行时才填充布局资源。他一般用在:当满足某些条件时某些UI才会展示,在进入一个页面时一般不会展示的情况下,比如网络错误页面,当发生网络错误时我们才展示,正常的情况下我们是不展示的。这时如果我们不使用ViewStub标签,而是直接将网络错误的布局隐藏,这种做法肯定是不好的,它虽然不显示出来,但是它会被inflate并占用资源。如果我们使用ViewStub标签就可以在它需要展示的时候再去填充布局。用法如下

    <ViewStub
            android:id="@+id/net_error_stub"
            android:inflatedId="@+id/net_error"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout="@layout/net_error" />
    

    其中android:inflatedId的值就是我们在Java代码中调用ViewStub的inflate()或者setVisibility()方法时返回的ID,这个ID就是被填充的View的ID。

    merge标签的使用

    < merge>标签和< include> 标签一起使用可以减少布局的层级嵌套。由于Activity的ContentView的最外层的布局是FrameLayout,因此,当一个独立的布局文件的最外层是FrameLayout,且这个布局不需要设置android:background或者android:padding等属性时,可以使用< merge>标签来代替< FrameLayout>标签,从而减少一层多余的Framelayout布局。使用一般限定在(使用相同的布局文件)

    布局中背景颜色的设置要慎重

    如果我们在嵌套的布局中每一层嵌套中都设置背景色,这会造成过度绘制,本来底层布局已经设置过颜色了,你在上层布局中又设置了一边同样的颜色,这时造成的直接结果就是GPU需要渲染这个颜色两边,从而造成了不必要的资源的浪费,降低了应用的性能。

    尽量使用CompoundDrawable

    如果存在相邻的ImageView和TextView实现的效果,看看能不能将其合并成一个TextView,ImageView中的图片设置成TextView的如下属性之一:drawableTop,drawbaleLeft,drawableRight或者drawableBottom。两者之间的间隔使用drawablePadding来代替。

    使用Lint检测

    Android Lint不仅可以对代码进行检测,对布局同样能够检测,可以用它来检测布局中哪些地方可以优化

    • AndroidLintUseCompoundDrawables:就是CompoundDrawable
    • MergeRootFrame:就是merge标签减少布局层次
    • TooManyViews:单个布局中存在太多的View,默认情况下,单个布局View的数量最多只能是80个,可以考虑复用布局,减少嵌套等。
    • NestedWeights:android:layout_weight属性会使得View控件被测量两次,当一个LinearLayout拥有非0dp值的android:layout_weight属性,这时如果将他嵌套在另一个拥有非0dp值的android:layout_weight属性的LinearLayout,那么这时测量的次数将呈指数级别增加。
    • Uselessleaf:一个布局如果既没有子View也没有设置背景,那么它将是不可见的,通常可以移除它。

    最后:应用的性能体现在应用代码中的一点一滴

    展开全文
  • Android性能优化之布局优化 前言includemergeViewStub其他的优化方式 ) 前言  Android中布局优化能让我们的界面绘制时间减少,用户感知到的卡顿时间也短,体验感自然而然也就上去了,Android中的布局优化可以从多个...

    Android性能优化之布局优化


    )

    前言

     Android中布局优化能让我们的界面绘制时间减少,用户感知到的卡顿时间也短,体验感自然而然也就上去了,Android中的布局优化可以从多个方面来入手,include,merge,ViewStub等等一些方面。

    include

     我们平常在画布局的时候经常碰到一些重复的共性布局,比如说标题栏,导航栏之类的,或者一些按钮之类的,我们在使用的时候重复的写非常麻烦,增加了我们工作量,使用include标签我们就可以避免去写那些无聊的共性代码,其实这个include单独来讲和我们这一篇文章没什么关系,但是他结合merge使用就可以减少一层ViewGroup的包裹,这一个我们在merge中去讲,下面贴出include的用法。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <include
            android:layout_width="match_parent"
            android:layout_height="50dp"
            layout="@layout/base_title_bar"/>
    
    </LinearLayout>
    

    merge

     merge的存在意义就是为了结合include来减少include引用过来的文件的外层ViewGroup,说白了就是用merge替代ViewGroup,虽然我们使用merge结合include可以达到减少绘制一层ViewGroup的效果,merge的布局是取决于父布局的,父布局是什么,他就是什么,或者我们可以这么理解,下面的代码我们就相当于将base_title_bar.xml中的两个textview直接写入到LinearLayout中,但是这里有个问题,我们的代码有时候include的xml与父布局所要的样式是不一样的,就比如我们当前引入的titlebar是要横向的,但是父布局是纵向的,这时候我们又得去给include外层再加上一层ViewGroup,所以我们在使用merge与include结合的时候要考虑清楚我们共性布局以后可能会使用的场景。

    base_title_bar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="out"
            android:textSize="18sp" />
    
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Title"
            android:textSize="18sp" />
    
    </merge>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <include
            android:layout_width="match_parent"
            android:layout_height="50dp"
            layout="@layout/base_title_bar"/>
    
    </LinearLayout>
    

    ViewStub

     ViewStub我们称之为懒加载,需要用到的时候就加载它,但是这里会有一个坑需要注意一下,就是ViewStub在显示之后就无法再隐藏了,因为ViewStub在显示的时候会将自己remove掉,替换成设置的view,这里我们只要记住ViewStub的作用就是一次性的按需加载就行了。我们使用到它的时候再按需加载,达到view在有需要的时候再渲染,以优化性能,下面是使用方法;

    坑点:ViewStub中的inflate()只能调用一次,调用多次会报错

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
    
        <ViewStub
            android:id="@+id/viewstub"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout="@layout/base_title_bar" />
    
    
    </LinearLayout>
    
    viewStub = (ViewStub) findViewById(R.id.viewstub);
    
    //第一种,直接显示,不获取到view
    if (viewStub != null) {
        viewStub.setVisibility(View.VISIBLE);
    }
    
    //第二种,显示,并且获取到view
    if (viewStub != null) {
        View view = viewStub.inflate();//获取到的是我们要显示出来的view
    }
    

    其他的优化方式

     一些其他的优化方式就是一些细节了,需要我们平时画界面的时候自己多注意注意,并且养成习惯

    1.子控件如果和父控件是同样的背景色时,子控件不需要再设定背景色了,用父控件的(能蹭一点是一点)。

    2.尽量减少不必要的嵌套,我们上面的include+merge的方式只是其中一种方式,我们平时画界面的时候还是得多注意一下能减少嵌套就减少嵌套(省着点用有限的资源)

    3.能用LinearLayout与FrameLayout的时候就不用RelativeLayout,毕竟RelativeLayout控件比LinearLayout与FrameLayout等复杂.

    4.合理的借助工具来分析界面是否过度绘制,并且进行合理的避免

    展开全文
  • Android 布局优化方案

    千次阅读 2020-12-28 15:45:31
    在 Android 开发中,UI 布局可以说是每个 App 使用频率很高的,随着 UI 越来越多,布局的重复性、复杂度也会随之增长,这样使得 UI布局的优化,显得至关重要,UI 布局...本篇文章就来总结一下 UI 布局优化的相关技巧。
  • android布局优化

    2016-08-12 15:35:50
    android布局优化
  • android 优化之布局优化

    千次阅读 2016-08-08 22:38:46
    布局优化中,Androi的官方提到了这三种布局、、,并介绍了这三种布局各有的优势,下面也是简单说一下他们的优势,以及怎么使用,简单复习下。 1、布局重用 标签能够重用布局文件,简单的使用如下: android:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,028
精华内容 4,811
关键字:

布局优化