背景
很久没写过UI了,最近项目比较忙,遇到几个问题记录一下。
- 设置文本行间距
- PopupWindow无法显示
- 绘制有色阴影
调整文字间距
问题
UE希望调整文本行间距,原来只记得有lineSpacing
的属性,而且只能调整行间距的倍数。
方案
后来查资料,发现可以通过lineSpacingExtra
来为行间距添加具体的Dimen值,并且可以为负数,如果为负数的话,会让行间距更加紧凑。
而lineSpacingMultiplier
属性则是为行间距设置倍数的。
PopupWindow无法显示
问题
在使用Popupwindow的showAsDropDown时候,发现PopupWindow无法弹出,而且UI出现卡死的情况
方案
原因是PopupWindow没有设置宽高,导致这种情况。所以在使用前必须setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
和setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
设置宽高,否则无法显示。
有色阴影
问题
在最近的改版中,发现有很多按钮的渐变,并且按钮出现了有色的阴影,而如果使用Android自带的translationZ
以及elevation
来调整Z轴的高度和倾斜度可以实现简单的黑色阴影。可是不能设置彩色
方案
可以通过Paint的setShadowLayer设置阴影层,并且在onDraw
绘制背景前绘制即可。
需要注意的点:
- ViewGroup必须将
setWillNotDraw(false)
,否则父View不会重绘 -
setShadowLayer
只能应用于CPU绘制,必须关闭硬件加速,否则无法绘制 - 阴影的颜色必须带透明度,如果没有透明度的话,则不会绘制阴影
下面是简单的Demo:
public class ShadowLayout extends FrameLayout {
private Paint paint;
private RectF rectF;
private int mShadowPadding;
private int mShadowRadius;
private int mShadowDx;
private int mShadowDy;
private int mShadowColor;
private int mRoundRadius;
public ShadowLayout(@NonNull Context context) {
super(context);
initPaint();
}
public ShadowLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public ShadowLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
// ViewGroup必须设置,否则不会重绘
setWillNotDraw(false);
// 必须使用CPU绘制,关闭硬件加速,否则不会绘制
setLayerType(LAYER_TYPE_SOFTWARE, null);
mShadowPadding = getContext().getResources().getDimensionPixelSize(R.dimen.20dp);
setPadding(mShadowPadding, mShadowPadding, mShadowPadding, mShadowPadding);
// 圆角的弧度
mRoundRadius = getContext().getResources().getDimensionPixelSize(R.dimen.25dp);
mShadowRadius = getContext().getResources().getDimensionPixelSize(R.dimen.10dp);
// 阴影的倾斜度
mShadowDx = getContext().getResources().getDimensionPixelSize(R.dimen.2dp);
mShadowDy = getContext().getResources().getDimensionPixelSize(R.dimen.5dp);
// 阴影的颜色必须带透明度,否则不会绘制
mShadowColor = Color.parse("#9FFF0000");
paint = new Paint();
paint.setColor(Color.TRANSPARENT);
paint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
rectF = new RectF();
}
public void setShadowColor(int color) {
mShadowColor = color;
setShadowLayer();
}
private void setShadowLayer() {
paint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
rectF.left = getPaddingLeft();
rectF.right = getWidth() - getPaddingRight();
rectF.bottom = getHeight() - getPaddingBottom();
rectF.top = getPaddingTop();
// 绘制带阴影的圆角矩形
canvas.drawRoundRect(rectF, mRoundRadius, mRoundRadius, paint);
}
}