Android 性能优化--UI

2017-07-24  本文已影响27人  Mr_不靠谱_先森

布局标签

<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标签同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。

在使用了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方法要避免执行大量的操作

上一篇 下一篇

猜你喜欢

热点阅读