android:height="100dp"/>android:startColor="@android:color/holo_blue..._android字体内容要加边框字体颜色要渐变">
当前位置:   article > 正文

android 字体颜色 渐变色,Android渐变色处理

android字体内容要加边框字体颜色要渐变

Android渐变色处理

大纲

1.xml 实现背景渐变 和 边框渐变

2.Drawable 实现背景渐变 和 边框渐变

3.自定义View实现渐变处理

xml实现渐变

背景渐变

使用shape 在xml布局中定义

android:shape="rectangle">

android:height="100dp"

/>

android:startColor="@android:color/holo_blue_light"

android:endColor="@android:color/holo_red_light"

/>

gradient标签下可以添加一些渐变控制,包含的属性如下表:

属性

描述

取值

type

类型

linear(默认值, 线性渐变) radial(辐射渐变,圆形) sweep(放射型)

startColor

开始颜色

endColor

结束颜色

centerColor

渐变中心区域的颜色

centerX, centerY

指定渐变中心

0 - 1 默认都是0.5表示区域的中心位置

angle

渐变角度,在type为linear时生效

45的倍数

gradientRadius

渐变半径,在type为radial生效,控制圆形渐变区域半径

useLevel

是否启用level, 启用后渐变区域将和设置的level相关,关于此字段我们稍后详解

类型

linear:

917b8561cfc6798cedc396efc75fdbb0.png

radial:

9f4753acaafb2ff3c3ae2ad121229b1e.png

sweep:

4ddb710933bc8c812d8f7302056318ea.png

useLevel

直译过来 level可以翻译成水平,抹平之类的,很难理解什么意思,我们直接看GradientDrawable的源码对useLevel字段的使用,我们以type 为linear为例:

private boolean ensureValidRect() {

...

if (gradientColors != null) {

final RectF r = mRect;

final float x0, x1, y0, y1;

if (st.mGradient == LINEAR_GRADIENT) {

final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f;

switch (st.mOrientation) {

case TOP_BOTTOM:

x0 = r.left; y0 = r.top;

x1 = x0; y1 = level * r.bottom;

break;

case TR_BL:

x0 = r.right; y0 = r.top;

x1 = level * r.left; y1 = level * r.bottom;

break;

case RIGHT_LEFT:

x0 = r.right; y0 = r.top;

x1 = level * r.left; y1 = y0;

break;

case BR_TL:

x0 = r.right; y0 = r.bottom;

x1 = level * r.left; y1 = level * r.top;

break;

case BOTTOM_TOP:

x0 = r.left; y0 = r.bottom;

x1 = x0; y1 = level * r.top;

break;

case BL_TR:

x0 = r.left; y0 = r.bottom;

x1 = level * r.right; y1 = level * r.top;

break;

case LEFT_RIGHT:

x0 = r.left; y0 = r.top;

x1 = level * r.right; y1 = y0;

break;

default:/* TL_BR */

x0 = r.left; y0 = r.top;

x1 = level * r.right; y1 = level * r.bottom;

break;

}

mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1,

gradientColors, st.mPositions, Shader.TileMode.CLAMP));

}

}

可以发现当用户设置useLevel 为true的时候(默认false), 渐变矩形的区域将缩小到getLevel() / 10000算出来的比例,而默认level为0,即如果单独只设置useLevel为true将看不到渐变效果,需要配合setLevel来决定渐变区域。我们来分别看下设置useLevel为true后,level 为 5000 和 8000的时候的样式:

useLevel 为 false:

5e0654a8e12c2f29c4a9cb573895f97f.png

level为5000 && useLevel为true:

30b58079273876005cfc4653c376d896.png

level为8000 && useLevel为true:

e9353a8579c030d226ad9ca104254d59.png

边框渐变

直接使用shape并不能实现边框的渐变,我们可以使用折中方案,将2个图层合成一个图,然后两个图之间的空隙可以当做渐变边框。这种方案有个弊端,即背景区域是不透明的纯色、我们可以在xml中使用layer-list标签来做出效果。注意一下应该是系统版本低版本上的图层size并不能生效,我们这里使用top bottom left right 来留出边框的位置。

>

android:height="100dp"

/>

android:startColor="@android:color/holo_blue_light"

android:endColor="@android:color/holo_red_light"

/>

实际效果:

6c06f0751f9e2364efe05800481ef220.png

此方法有一个问题就是并不能支持中间区域带透明度的问题,如果需要这个效果我们可以通过自定义Drawable 或者自定义View来实现。

使用Drawable实现渐变

API 16以及16以上系统提供了GradientDrawable来实现渐变和边框的Drawable,

参数定义同xml中的参数命名,需要特别指出的是对于angle的控制,GradientDrawable使用setOrientation来控制, 我们来看下系统angle转换成Orientation的源码:

int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);

angle %= 360;

if (angle % 45 != 0) {

throw new XmlPullParserException(a.getPositionDescription()

+ " tag requires 'angle' attribute to "

+ "be a multiple of 45");

}

st.mAngle = angle;

switch (angle) {

case 0:

st.mOrientation = Orientation.LEFT_RIGHT;

break;

case 45:

st.mOrientation = Orientation.BL_TR;

break;

case 90:

st.mOrientation = Orientation.BOTTOM_TOP;

break;

case 135:

st.mOrientation = Orientation.BR_TL;

break;

case 180:

st.mOrientation = Orientation.RIGHT_LEFT;

break;

case 225:

st.mOrientation = Orientation.TR_BL;

break;

case 270:

st.mOrientation = Orientation.TOP_BOTTOM;

break;

case 315:

st.mOrientation = Orientation.TL_BR;

break;

}

很清楚的能看到我们为什么说只支持是45的倍数。

GradientDrawable并不支持边框渐变, 我们依然可以使用2个图层的思路来解决边框渐变的控制,LayerDrawable 2个图层实现边框渐变 。

LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{bgDrawable, drawable});

layerDrawable.setLayerInset(1, borderWidth, borderWidth, borderWidth, borderWidth);

我们需要通过setLayerInset方法来控制图层图层直接的偏移来留出边框的位置。

自定义View实现渐变

配置画笔渐变,这里我们说Linear类型的渐变

private void updateGradientPaint(Paint paint, RectF r, GradientStat stat) {

float x0, x1, y0, y1;

int angle = stat.angle % 360;

if (angle % 45 != 0) {

throw new RuntimeException("");

}

if (angle == 0) {

x0 = r.left;

y0 = r.top;

x1 = r.right;

y1 = y0;

} else if (angle == 45) {

x0 = r.left;

y0 = r.bottom;

x1 = r.right;

y1 = r.top;

} else if (angle == 90) {

x0 = r.left;

y0 = r.bottom;

x1 = x0;

y1 = r.top;

} else if (angle == 135) {

x0 = r.right;

y0 = r.bottom;

x1 = r.left;

y1 = r.top;

} else if (angle == 180) {

x0 = r.right;

y0 = r.top;

x1 = r.left;

y1 = y0;

} else if (angle == 225) {

x0 = r.right;

y0 = r.top;

x1 = r.left;

y1 = r.bottom;

} else if (angle == 270) {

x0 = r.left;

y0 = r.top;

x1 = x0;

y1 = r.bottom;

} else {

x0 = r.left;

y0 = r.top;

x1 = r.right;

y1 = r.bottom;

}

paint.setShader(new LinearGradient(x0, y0, x1, y1,

stat.colors, null, Shader.TileMode.CLAMP));

}

渐变边框,边框矩形区域要取边框间距的中间位置来绘制, 例如:

// width 表示表框宽度

float offset = width / 2f;

RectF bolderRect = new RectF();

bolderRect.set(offset, offset, getMeasuredWidth() - offset,

getMeasuredHeight() - offset);

欢迎关注我的微信公众号

璐豪笔记

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/420715
推荐阅读
相关标签
  

闽ICP备14008679号