Android开发中的一些小技巧
Android
一些小技巧可以优化布局,减少布局的嵌套,减少过度绘制,优化各项性能.
常常见到一个图标和文字并列的场景,比如水平排列的,左边一个图标右边有个文字,一般的实现用LinearLayout来水平排列ImageView和TextView。
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:oritation="horizontal">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_tag"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"/>
TextView有drawableLeft、drawableTop、drawableRight、drawableBottom属性可以设置上下左右的Drawable对象来替代上述的实现。
在布局设置,设置了才显示哪个方向的Drawable
android:drawableLeft="@drawable/ic_tag"
代码中设置setCompoundDrawables,用null或0的参数表示不显示对应的位置(特别需要注意:设置的Drawable是必须是已调用过setBounds方法的,不然看不出效果),或者调用setCompoundDrawablesWithIntrinsicBounds内部会去处理drawable的bounds.
setCompoundDrawables(Drawableleft,Drawabletop,Drawableright,Drawablebottom)
Drawable与文字之间的距离可以通过drawablePadding来设置
android:drawablePadding="10dp"
setCompoundDrawablePadding(intpad)
优点:减少一层布局嵌套;
缺点:特殊的需求这个不好实现,可以考虑使用LayerDrawable实现一些特殊的需求 layer-list
正确使用ListView的分割线
ListView提供的分割线方法不能直接控制分割线的样式,但是可以控制分割线Drawable的样式,详细查看这篇文章http://blog.youkuaiyun.com/megatronkings/article/details/52156312。
不推荐在布局里面直接插入一个View做为分割线,然后还要在代码中控制显示隐藏。可以使用InsetDrawable来修饰分割线的留白等来达到设计效果。
实现线性布局里面的分割线,一般做法是添加View作为分割线,实际上可以使用LinearLayout的
setDividerDrawable(Drawable divider)和setShowDividers(int showDividers)方法来设置分割线,或者在xml布局中指定android:layout_divider.设置对应的参数即可显示分割线.SHOW_DIVIDER_NONE, // 默认的,不显示分割线
SHOW_DIVIDER_BEGINNING, // LinearLayout的开头显示分割线
SHOW_DIVIDER_MIDDLE, // LinearLayout中每个子View之间显示分割线
SHOW_DIVIDER_END // LinearLayout的尾部显示分割线
优点:减少分割线View的数量,直接绘制分割线效率更高.
缺点:不规则的分割线不好实现,可考虑搭配InsetDrawable实现
还有一些特殊的分割线,搭配各种Drawable可以自定义出来.
example:白色背景,顶部一条红色的分割线
有个需求是在一个ImageView上面覆盖一层半透明遮罩效果,一般做法是父布局用FrameLayout或者RelativeLayout,放上ImageView,然后再在上面覆盖一个背景半透明效果的View来实现。
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/xxxx"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#7fff0000"/>
其实可以直接设置ImageView的前景(foreground),类似设置背景一样,这样就减少了一层的嵌套了,该属性只在API>=23或者使用FrameLayout时有效果,或者直接设置FrameLayout的前景色。
android:layout_width="match_parent"
android:foreground="#7fff0000"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/xxxx"/>
布局中设置,可以使用Drawable或者Color
android:foreground="@drawable/xx"
或者在代码中设置
setForeground(Drawableforeground)使用颜色滤镜,这种需求可以通过设置颜色矩阵来控制更好,ImageView#setColorFilter().
对于图片的色阶控制效果相当于设置的蒙层效果.
也可以结合tint着色器属性来设置其前景/背景,需要考虑版本兼容问题
扩展:可以将图标作为FrameLayout的foreground来使用,可以减少一个View,需要注意对齐位置和拉伸问题
android:layout_width="match_parent"
android:layout_height="200dp"
android:foreground="@mipmap/ic_player"
android:foregroundGravity="center">
android:id="@+id/iv_thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:background="@mipmap/default_image"/>
在全局中设置Window样式的背景色(图),而不是在每个根布局中单独设置背景.
给启动的目标Activity设置Window样式背景色(图),加速App加载视觉效果,而不是一片空白(或者黑漆漆的)后才看到页面效果.
可以设置getWindow().setBackgroundDrawable(xx);
或者设置透明背景,启动时看上去没启动感觉getWindow().setBackgroundDrawableResource(android.R.color.transparent);
使用Compat类
ViewCompat,DrawableCompat