Android性能优化内存优化最详细最通俗讲解--安卓优化之路--布局优化控件优化(二)

在开发中布局是必不可少的,如果某个页面的页面相对复杂,就会引起过度绘制,加载是出现卡顿等。

本篇就一部剧为切入点,主要说一下布局中的优化和某些控件的优化。

RelativeLayout  LinearLayout对比

之前看了一篇阿里的面试题。RelativeLayout  LinearLayout哪个效率高?为什么?就以这个问题开始本篇文章;

1.RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure
2.RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin。
3. 在不响应层级深度的情况下,使用 Linearlayout 而不是 RelativeLayout
然而再Studio中默认是RelativeLayout,又是为什么??
默认新建 RelativeLayout 是希望开发者能采用尽量少的 View 层级,很多效果是 需要多层 LinearLayout 的嵌套,这必然不如一层的 RelativeLayout 性能更好 尽量减少布局嵌套,减少层级结构。

include  merge  ViewStub的使用和对比

在布局优化中,Android中提到的抽象布局

<include  />:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:orientation="vertical"   
  3.     android:layout_width=”match_parent”  
  4.     android:layout_height=”match_parent”  
  5.     android:background="@color/bg"  
  6.    
  7.   
  8.     <include layout="@layout/toobar"/>  
  9.   
  10.     <TextView android:layout_width=”match_parent”  
  11.               android:layout_height="wrap_content"  
  12.               android:text="@string/hello"  
  13.               android:padding="10dp" />  
  14.   
  15.     ...  
  16.   
  17. </LinearLayout> 
在<include>标签当中,我们是可以覆写所有layout属性的,即include中指定的layout属性将会覆盖掉titlebar中指定的layout属性

<merge />

可以删减多余的层级

一个垂直布局的include,这是如果include布局使用的LinearLayout就没意义了,使用的话反而减慢你的UI表现。这时可以使用

  1. <merge xmlns:android="http://schemas.android.com/apk/res/android">  
  2.   
  3.     <Button  
  4.         android:layout_width="fill_parent"   
  5.         android:layout_height="wrap_content"  
  6.         android:text="@string/add"/>  
  7.   
  8.     <Button  
  9.         android:layout_width="fill_parent"   
  10.         android:layout_height="wrap_content"  
  11.         android:text="@string/delete"/>  
  12.   
  13. </merge> 

<ViewStub />

<ViewStub />标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。各种不常用的布局想进度条、显示错误消息等可以使用<ViewStub />标签,以减少内存使用量,加快渲染速度。<ViewStub />是一个不可见的,大小为0View。

  1. <ViewStub  
  2.     android:id="@+id/stub_import"  
  3.     android:inflatedId="@+id/panel_import"  
  4.     android:layout="@layout/progress_overlay"  
  5.     android:layout_width="fill_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:layout_gravity="bottom" />

public class MainActivity extends AppCompatActivity {
    private ViewStub viewStub;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewStub = (ViewStub) findViewById(R.id.vs);
        //textView  = (TextView) findViewById(R.id.hello_tv);空指针
    }
    public  void inflate(View view){
        viewStub.inflate();
        //textView  = (TextView) viewStub.findViewById(R.id.hello_tv);空指针
        textView  = (TextView) findViewById(R.id.hello_tv);
    }
    public void setData(View view){
        textView.setText("DATA!!");

    }
}

ViewStub只有在初始化之后才会存在,所以第一个注释中的空指针是因为ViewStub还未初始化。那第二个注释中的空指针是怎么回事呢?前面我们也说了,ViewStub在加载完成之后会移除自身,并把自身的内容转给父布局,所以此时viewStub中的内容已经不存在了,textView已经是父布局的东西了,所以不能使用viewStub来findViewById。另外,前面我们说了ViewStub只能加载一次,若调用两次inflate()的话会导致异常。








猜你喜欢

转载自blog.csdn.net/u010354511/article/details/80491118
今日推荐