重用
include
< include>标签可以在一个布局中引入另外一个布局,这个的好处显而易见。类似于我们经常用到的工具类,随用随调。便于统一修改使用。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:orientation="vertical"> <include layout="@layout/toolbar" /> ...省略 </LinearLayout>
而我toolbar的布局是单独的一个,可以在任务需要的地方进行include
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:navigationIcon="@drawable/back"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="@drawable/back"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<!--<RelativeLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:gravity="center">-->
<TextView
android:id="@+id/toolbar_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:ellipsize="end"
android:maxEms="9"
android:singleLine="true"
android:text="@string/gallery_app_name"
android:textColor="@android:color/white"
android:textSize="18sp" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right">
<TextView
android:id="@+id/title_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:padding="10dp"
android:textColor="@android:color/white"
android:textSize="15sp" />
<ImageView
android:id="@+id/image_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:padding="10dp" />
</FrameLayout>
</android.support.v7.widget.Toolbar>
2.合并
2.1 减少嵌套
首先我们心中要有一个大原则:尽量保持布局层级的扁平化。在这个大原则下我们要知道:
在不影响层级深度的情况下,使用LinearLayout而不是RelativeLayout。因为RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,才会让子View调用2次onMeasure。Measure的耗时越长那么绘制效率就低。如果非要是嵌套,那么尽量避免RelativeLayout嵌套RelativeLayout。这简直就是恶性循环,丧心病狂
2.2 使用merge
< merge/>主要用来去除不必要的FrameLayout。它的使用最理想的情况就是你的根布局是FrameLayout,同时没有使用background等属性。这时可以直接替换。因为我们布局外层就是FrameLayout,直接“合并”。
PS: 上面已经说了同时## 没有使用background等属性。 ##
2.3 用TextView同时显示图片和文字
这种效果很常见,一般实现方法是这样。(貌似没人这样写吧,哈哈)
<?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">
<LinearLayout
android:orientation="horizontal"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:src="@drawable/icon_1"
android:layout_height="match_parent" />
<TextView
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textSize="16sp"
android:text="我的卡券"
android:gravity="center_vertical"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<ImageView
android:layout_marginRight="10dp"
android:src="@drawable/icon_4"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
这里可以直接使用textview的drawable的right|left|top|bottom等
<?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">
<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" />
</LinearLayout>
你没有看错,少了两个ImageView和去除嵌套LinearLayout。效果不用说一样一样的
这里也可以动态设置图片的。setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)可以让我们动态去设置图片。
2.4 使用textview的行间距
想要实现的
我平时如果遇到这种之前是直接用下面的布局实现的
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="100dp"
android:background="@color/white"
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:padding="25dp"
android:src="@drawable/kd_1"
android:layout_width="100dp"
android:layout_height="100dp"/>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="100dp">
<TextView
tools:text="揽件方式:上门取件"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="25dp"/>
<TextView
tools:text="快递公司:顺丰快递"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="25dp"/>
<TextView
tools:text="预约时间:9月6日 立即取件"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="25dp"/>
<TextView
tools:text="快递费用:等待称重确定价格"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="25dp"/>
</LinearLayout>
</LinearLayout
优化后代码:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="100dp"
android:background="@color/white"
android:layout_width="match_parent">
<ImageView
android:padding="25dp"
android:src="@drawable/kd_1"
android:layout_width="100dp"
android:layout_height="match_parent"/>
<TextView
android:textSize="14dp"
android:lineSpacingExtra="8dp"
android:gravity="center_vertical"
android:text="揽件方式:上门取件\n快递公司:顺丰快递\n预约时间:9月6日 立即取件\n快递费用:等待称重确定价格"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
老规矩,效果一样一样的。可以看到我们仅仅利用Android:lineSpacingExtra=”8dp”这一行
代码就省去了3个TextView,如果行数更多呢?是不是方便多了。其中:lineSpacingExtra属性代表的是行间距,他默认是0,是一个绝对高度值。同时还有>lineSpacingMultiplier属性,它代表行间距倍数,默认为1.0f,是一个相对高度值。我们来使>用一下:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="100dp"
android:background="@color/white"
android:layout_width="match_parent">
<ImageView
android:padding="25dp"
android:src="@drawable/kd_1"
android:layout_width="100dp"
android:layout_height="100dp"/>
<TextView
android:textSize="14dp"
android:lineSpacingMultiplier="1.3"
android:gravity="center_vertical"
android:text="揽件方式:上门取件\n快递公司:顺丰快递\n预约时间:9月6日 立即取件\n快递费用:等待称重确定价格"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
当然了这两条属性可以同时使用,查看源码可以知道,他们的高度计算规则为mTextPaint.getFontMetricsInt(null) * 行间距倍数 + 行间距
使用Spannable或Html.fromHtml
如果实现上图红框中的效果,笨办法就是写三个TextView,“¥”,“价格”,“门市价”分别实现,其实用一个TextVIew就可以实现,类似如下代码:
String text = String.format("¥%1$s 门市价:¥%2$s", 18.6, 22);
int z = text.lastIndexOf("门");
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.setSpan(new AbsoluteSizeSpan(DisplayUtil.dip2px(mContext,14)), 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //字号
style.setSpan(new ForegroundColorSpan(Color.parseColor("#afafaf")), z, text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //颜色
style.setSpan(new AbsoluteSizeSpan(DisplayUtil.dip2px(mContext,14)), z, text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //字号
tv.setText(style);
用LinearLayout自带的分割线
还记得上文用TextView同时显示图片和文字中的例子吗?我们可以看到每个条目之间都是有一根分隔线的,那么怎么实现呢?别人我不知道,反正我原来是用一个View设置高度实现的。相信一定有人和我一样。
那么老办法我就不演示了,直接上代码:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:divider="@drawable/divider"
android:showDividers="middle">
<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" />
<TextView
android:drawableLeft="@drawable/icon_2"
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" />
<TextView
android:drawableLeft="@drawable/icon_3"
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" />
</LinearLayout>
这里核心实现:
android:divider="@drawable/divider"
android:showDividers="middle"
其中divider.xml是分隔线样式
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:width="1dp"
android:height="1dp"/>
<solid android:color="#e1e1e1"/>
</shape>
showDividers 是分隔线的显示位置,beginning、middle、end分别代表显示在开始位置,中间,末尾。
还有dividerPadding属性这里没有用到,意思很明确给divider添加padding。感兴趣可以试试。
Space控件
还是接着上面的例子,如果要给条目中间添加间距,怎么实现呢?当然也很简单,比如添加一个高10dp的View,或者使用android:layout_marginTop=”10dp”等方法。但是增加View违背了我们的初衷,并且影响性能。使用过多的margin其实会影响代码的可读性。
这时你就可以使用Space,他是一个轻量级的。我们可以看下源码:
public final class Space extends View {
/**
* {@inheritDoc}
*/
public Space(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
if (getVisibility() == VISIBLE) {
setVisibility(INVISIBLE);
}
}
/**
* {@inheritDoc}
*/
public Space(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
/**
* {@inheritDoc}
*/
public Space(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* {@inheritDoc}
*/
public Space(Context context) {
//noinspection NullableProblems
this(context, null);
}
/**
* Draw nothing.
*
* @param canvas an unused parameter.
*/
@Override
public void draw(Canvas canvas) {
}
/**
* Compare to: {@link View#getDefaultSize(int, int)}
* If mode is AT_MOST, return the child size instead of the parent size
* (unless it is too big).
*/
private static int getDefaultSize2(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
result = Math.min(size, specSize);
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(
getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec));
}
}
可以看到在draw方法没有绘制任何东西,那么性能也就几乎没有影响。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:divider="@drawable/divider"
android:showDividers="middle|beginning|end">
<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" />
<TextView
android:drawableLeft="@drawable/icon_2"
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" />
<Space
android:layout_width="match_parent"
android:layout_height="15dp"/>
<TextView
android:drawableLeft="@drawable/icon_3"
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" />
</LinearLayout>
防止过度绘制
http://blog.csdn.net/lmj623565791/article/details/45556391