美文网首页
Android 性能优化--UI

Android 性能优化--UI

作者: Mr_不靠谱_先森 | 来源:发表于2017-07-24 17:31 被阅读27次

布局标签

  • include
    <include>
    的用途就是将布局中的公共部分提取出来以供其他Layout使用,从而实现布局的优化。这种布局的编写方式大大便利了开发,个人感觉这种思想和React Native中的面向组件编程思想有着异曲同工之妙,都是将特定功能抽取成为一个独立的组件,只要控制其中传入的参数就可以满局不同的需求。例如:我们在编辑Android界面的时候常常需要添加标题栏,如果在不使用<include>
    的情况下,只能在每一个需要显示标题栏的xml文件中编写重复的代码,费时费力。但是只要我们将这个需要多次被使用的标题栏布局抽取成一个独立的xml文件,然后在需要的地方使用<include>
    标签引入即可。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/simple_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="80dp" />

    <include
        android:id="@+id/my_foot_ly"
        layout="@layout/foot" />

</RelativeLayout>

其中include引入的foot.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="match_parent" 
    android:id="@+id/my_foot_parent_id">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_above="@+id/title_tv"/>

    <TextView
        android:id="@+id/title_tv"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_alignParentBottom="true"
        android:text="@string/app_name" />
</RelativeLayout>

注意
在使用<include>标签最常见的问题就是 findViewById查找不到<include>进来地控件的跟布局,而这个问题出现的前提就是在include的时候设置了id。当设置id后,原有的foot.xml跟布局Id已经被替换为在 <include>中指定的id了,所以在 findViewById查找原有id的时候就会报空指针异常。

<include>标签简单的说就是相当与将layout指定的布局整体引入到main.xml中。所以我们就和操作直接在main.xml中的布局是一样的只不过有一个上面提到的更布局id被覆盖的问题。

  • ViewStub

ViewStub标签同include一样可以用来引入一个外部布局。不同的是,ViewStub引入的布局默认是不会显示也不会占用位置的,从而在解析的layout的时候可以节省cpu、内存等硬件资源。

ViewStub常常用来引入那些默认不显示,只在特定情况下才出现的布局,例如:进度条,网络连接失败显示的提示布局等

<?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="match_parent" >

……
    <ViewStub
        android:id="@+id/network_error_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/network_error" />

</RelativeLayout>

其中network_error.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="match_parent" >

    <Button
        android:id="@+id/network_setting"
        android:layout_width="@dimen/dp_160"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/network_setting" />

    <Button
        android:id="@+id/network_refresh"
        android:layout_width="@dimen/dp_160"
        android:layout_height="wrap_content"
        android:layout_below="@+id/network_setting"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/dp_10"
        android:text="@string/network_refresh" />

</RelativeLayout>

在代码中通过(ViewStub)findViewById(id)找到ViewStub,通过stub.inflate()展开ViewStub,然后得到子View,如下:

private View networkErrorView;

private void showNetError() {
  if (networkErrorView != null) {
    networkErrorView.setVisibility(View.VISIBLE);
  }else{
    ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
    if(stub !=null){
      networkErrorView = stub.inflate();

      //  效果和上面是一样的
      //  stub.setVisibility(View.VISIBLE);   // ViewStub被展开后的布局所替换
      //  networkErrorView =  findViewById(R.id.network_error_layout); // 获取展开后的布局
    }
 }
}

private void showNormal() {
  if (networkErrorView != null) {
    networkErrorView.setVisibility(View.GONE);
  }
}

在上面showNetError()中展开了ViewStub,同时我们对networkErrorView进行了保存,这样下次不用继续inflate。

  • merge

在使用了include后可能会导致布局嵌套太多,导致视图节点太多,减慢了解析速度。

merge标签可用于两种典型情况:

  1. 布局顶接点是FrameLayout并且不需要设置background或者padding等属性,可使用merge代替,因为Activity内容视图的parent view就是一个FrameLayout,所以可以用merge消除只能一个。
  2. 某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时,顶结点会自动被忽略,而其自己点全部合并到主布局中。
    以include引入的foot.xml为公用的页面底部 为例
    可以发现多了一层没必要的RelativeLayout,将foot.xml中RelativeLayout改为merge,如下:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_above="@+id/text"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_alignParentBottom="true"
        android:text="@string/app_name" />

</merge>

绘制优化

绘制优化是指View的onDraw方法要避免执行大量的操作

相关文章

  • Android UI性能优化

    Ui性能优化 参考博客:Android UI性能优化实战 识别绘制中的性能问题Android UI性能优化详解 1...

  • Android UI优化

    Android性能优化 - UI篇Android性能优化 - CPU/GPU篇 一、UI层级优化 借助工具:Hie...

  • 性能优化

    Android UI性能优化实战 识别绘制中的性能问题性能优化(二) UI 绘制优化 通过Hierarchy Vi...

  • Android性能优化 - CPU/GPU篇

    Android性能优化 - UI篇Android性能优化 - CPU/GPU篇 前言 本篇主要讲解APP性能优化路...

  • Android性能优化

    Android性能优化 Android 性能优化的方法 性能问题一般分为3类 UI卡顿 内存问题 耗电问题 布局优...

  • Android 面试基础坑,你掉进去过几次?

    一、性能优化 1.如何对 Android 应用进行性能分析 android 性能主要之响应速度 和UI刷新速度。 ...

  • Android群英传读书笔记(第十章)

    上一章 本章主要介绍的是android的性能优化。 1.布局优化 Android UI渲染机制在Android中,...

  • Android 性能优化

    app性能优化 android优化分为: 内存优化 UI优化 电量优化 apk瘦身优化 启动优化 下面通过各种百度...

  • Android 性能优化总结

    将从以下几个方面总结Android的应用性能优化 性能 框架API UI 性能 I/O性能 屏幕滚动性能 内存 A...

  • Android优化文章精选

    Android性能优化典范 Android性能优化典范 - 第1季Android性能优化之渲染篇Android性能...

网友评论

      本文标题:Android 性能优化--UI

      本文链接:https://www.haomeiwen.com/subject/qfbbkxtx.html