布局优化的核心在于
1.减少布局嵌套
2.减少控件的使用
3.不能为了优化而优化,需要考虑到复用性和扩展性
4.开发与设计之间的协作性和规范性
1.图文优化
1.1
优化代码:利用drawableLeft配合drawablePadding
<TextView android:drawableLeft="@drawable/icon_1"
android:drawableRight="@drawable/icon_4"
android:drawablePadding="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textSize="16sp"
android:text="我的卡券"
android:background="@color/white"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="50dp" />
注意事项:任何一种优化,都只适用于某一部分特定的场景。
如果后续业务有扩展,整体的结构还是需要进行调整。
例如”我的卡券”后面,需要展示用户有多少张劵。
这个时候,一个控件就感觉不够用了。
1.2
优化代码:
利用lineSpacingExtra属性(行间距,绝对值),默认是0
或者lineSpacingMultiplier属性(行间距倍数,相对值),默认为1.0f
考虑到适配的话,建议用lineSpacingMultiplier
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@mipmap/ic_launcher"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:lineSpacingExtra="8dp"
android:paddingLeft="25dp"
android:text="揽件方式:上门取件\n快公司:顺丰快递\n预约时间:9月6日立即取件\n快递费用:等待称重确定价格"
android:textSize="14dp" />
注意事项:同样,维护才是难点。如果在”揽件”和”快递公司”二者之间加入一个,需要点击的事件,或者是联系方式变成红色,并且可以点击,那么这种就还是需要进一步去调整。
1.3 TextView部分文字变色,并且部分范围可以点击。
//设置文字
SpannableStringBuilder text = new SpannableStringBuilder();
String login = "登录即代表同意";
String protocol = "《用户服务协议及隐私权条款》";
style.append(login + protocol);
//设置部分文字点击事件
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
//doSomething
}
};
//设置点击区域的位置
text.setSpan(clickableSpan, login.length(), login.length() +
protocol.length(),Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
//设置部分文字颜色
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#0000CD"));
style.setSpan(foregroundColorSpan, a.length(), a.length() + b.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
mTvLogin.setMovementMethod(LinkMovementMethod.getInstance());
mTvLogin.setText(text);
1.4 使用Spannable
1 | String text = String.format("¥%1$s 门市价:¥%2$s", 18.6, 22); |
1.5 总结
综合上面四个demo,得到以下的总结:
任何一种优化,都有自己的使用场景
根据自身项目实际需求,弄出一个精简版的superTextview。
但是随后参照了淘宝和哔哩哔哩等热门APP,发现很多都没有这样去做。
例如哔哩哔哩的弹幕,因为高频率刷弹幕,所以优化处理,节省性能。
1
2
3
4
5而作为一些基础view,则还是普通的写法。
当然也包括了淘宝的页面。
其实这一类的优化,都要考虑其适用场景。
如果是属于同一个层级的话,优化意义并不大。
如果涉及到布局嵌套了,那么就可以做一下对应优化处理。
账户余额这里就可以用精简化的supertextview,从而达到减少布局嵌套。
2.减少嵌套
原则:尽量保持布局层级的扁平化。
手机的”设置”==>开发者选项==>显示布局边界,可以看到对应的控件
不影响层级的情况下,尽量使用LinearLayout而不是RelativeLayout。因为RelativeLayout比LinearLayout更耗时,它会让子View调用2次onMeasure,LinearLayout在有weight时,才会让子View调用2次onMeasure。Measure的耗时越长那么效率就低。
如果非要是嵌套,那么尽量避免RelativeLayout嵌套RelativeLayout。估计也没人会这样做
3.Space控件
3.1 介绍
1 | 多个组件之间的缝隙,如果用View,则消耗性能。 |
3.2 应用场景之一
3.3 注意事项
1 | 1. Space的draw是个空实现,所以设置样式是无效的。 |
4.利用LinearLayout自带的divider和showDividers
1 | android:divider="@drawable/divider" |
具体的divider,可以参照shape
android:showDividers有三种属性,
beginning //LinearLayout头部添加
middle //LinearLayout中间添加(即各child之间添加)
end //LinearLayout底部添加
divider的应用场景当然不仅仅只是线条,只要是包括drawable中的属性都可以。同样也考验一个团队的协同性和规范性。
5. include、merge 、ViewStub
include 略 只需要知道 可以调节大小,通常在title中用的比较多。
merge实际上就是结合include进行使用。可以减少布局嵌套,但是实际应用中,却用的非常少。
例如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/title"></include>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="标题" />
</LinearLayout>
而include中的根布局也是LinearLayout,此时,就可以用merge代替。
6.Recycleview的线条
1.Recycleview的分割线,不需要单独去写view,直接调用
mRvContent.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
当然也可以直接继承DividerItemDecoration 自己自定义
因为这里是相同的item样子的线条。如果有不同item线条,将要如何处理。
2.布局优化都做完了,再结合项目中的自定义view的解耦。
还有uml图和时序图的学习。
可以通过那个检测工具来检测布局层级分布情况,然后再对其进行优化处理。
首页的推荐目前没有什么毛病,用Vlayout。除了分析源码加上各种调用,然后就是自己手写。加上市面各种adapter,还有自己封装recyclerview。包括分割线,是否需要下拉上拉的滑动默认栏。
最关键是要结合屏幕适配来做。
不可能是给固定坐标。
所剩问题
1.relativelayout和framelayout的区别
2.toolbar的讲解。