项目里面需要展示一个图片List 。图片高度大约100dp高 , 全屏长 , 上,垂直居中处需要显示标题文字,文字颜色纯白 。如图所示:
本来按正常来说 , 这图应该由美工提供,并且如果颜色不合适,由美工大大做类似《吃新鲜蔬菜》这张图的渐变蒙层叠加 。
但考虑到之后工作量越来越大,美工大大可能会完全忙不过来,直接不处理就由运营上图,因此可能导致白字放在了浅色图片中 , 以至于看不见字的情况 。
为了防止这种情况的发生,因此写了个自定义View来解决这个问题 。
首先这个列表的图片展示是基于开源的库,来进行的 。
接着查到的 系列包中提供了方法,可以高效的从中获取特定风格的颜色色值,该方法为:
/** 获取bitmap中的活跃颜色,如果没获取到则为默认颜色#666666 */Palette.from(bitmap).generate().getVibrantColor(Color.parseColor("#666666"))
这里我们将使用获取到的颜色作为遮罩渐变的起始颜色,为了防止获取到的颜色过浅,进行了如下处理:
int red = color >> 16 & 0xFF;int green = color >> 8 & 0xFF;int blue = color & 0xFF;if (red >= 0xA0 && green >= 0xA0 && blue >= 0xA0) {color = Color.rgb(Math.round(red * 0.8F), Math.round(green * 0.8F), Math.round(blue * 0.8F));}
这里先获取该颜色的R、G、B值,如果都大于0xA0则认为太浅会影响文字显示 , 则将R、G、B每个值都乘以0.8降低亮度 。
以上为这个码子产生的历史背景以及原因,接下来直接上码子 。
注意,该码子基于 , 如果您用的不是,请自行适配 。
首先中的build.加载与的包:
implementation 'androidx.palette:palette-ktx:1.0.0'implementation 'com.facebook.fresco:fresco:2.0.0'
然后是View.java
import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Shader;import android.net.Uri;import android.util.AttributeSet;import androidx.palette.graphics.Palette;import com.facebook.drawee.controller.AbstractDraweeControllerBuilder;import com.facebook.drawee.generic.GenericDraweeHierarchy;import com.facebook.drawee.interfaces.DraweeController;import com.facebook.drawee.view.SimpleDraweeView;import com.facebook.imagepipeline.common.ImageDecodeOptions;import com.facebook.imagepipeline.common.RotationOptions;import com.facebook.imagepipeline.request.BasePostprocessor;import com.facebook.imagepipeline.request.ImageRequest;import com.facebook.imagepipeline.request.ImageRequest.RequestLevel;import com.facebook.imagepipeline.request.ImageRequestBuilder;public class GradientSimpleDraweeView extends SimpleDraweeView {public GradientSimpleDraweeView(Context context, GenericDraweeHierarchy hierarchy) {super(context, hierarchy);}public GradientSimpleDraweeView(Context context) {super(context);}public GradientSimpleDraweeView(Context context, AttributeSet attrs) {super(context, attrs);}public GradientSimpleDraweeView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public GradientSimpleDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}@Overridepublic void setImageURI(Uri uri, Object callerContext) {AbstractDraweeControllerBuilder adcb = getControllerBuilder();adcb = adcb.setOldController(getController()).setCallerContext(callerContext);ImageRequestBuilder imageRequestBuilder = null;ImageDecodeOptions imageDecodeOptions = null;imageDecodeOptions = ImageDecodeOptions.newBuilder().build();/** 构建自定义ImageRequest,以便于对即将渲染的Bitmap进行修改 */imageRequestBuilder = ImageRequestBuilder.newBuilderWithSource(uri).setImageDecodeOptions(imageDecodeOptions).setRotationOptions(RotationOptions.autoRotate()).setLocalThumbnailPreviewsEnabled(true).setLowestPermittedRequestLevel(RequestLevel.FULL_FETCH).setProgressiveRenderingEnabled(true);/** 设置Bitmap处理器 */imageRequestBuilder.setPostprocessor(new BasePostprocessor() {@Overridepublic void process(Bitmap bitmap) {super.process(bitmap);// 获取bitmap中活跃颜色值int color = Palette.from(bitmap).generate().getVibrantColor(Color.parseColor("#666666"));// 防止颜色值过浅,对其进行条件变暗处理int red = color >> 16 & 0xFF;int green = color >> 8 & 0xFF;int blue = color & 0xFF;if (red >= 0xA0 && green >= 0xA0 && blue >= 0xA0) {color = Color.rgb(Math.round(red * 0.8F), Math.round(green * 0.8F), Math.round(blue * 0.8F));}// 创建线性渐变蒙层,这就是我们需要叠加上去的遮罩蒙层拉// 其参数为以图片y的中点为起点 , 图片宽度的75%处为终点,起点颜色为// 上面运算后的颜色,终点为透明色进行渐变,渐变模式为CLAMPLinearGradient linearGradient = new LinearGradient(0, bitmap.getHeight() / 2, (int) (bitmap.getWidth() * 0.75f), bitmap.getHeight() / 2, color, Color.TRANSPARENT, Shader.TileMode.CLAMP);Paint paint = new Paint();paint.setShader(linearGradient);// 将bitmap捆到画板上,并在画板上绘制蒙层遮罩,高度为图片高度,长度为终点(即图片宽度的75%)Canvas canvas = new Canvas(bitmap);canvas.drawRect(0, 0, (int) (bitmap.getWidth() * 0.75f), bitmap.getHeight(), paint);}});ImageRequest imageRequest = imageRequestBuilder.build();//noinspection uncheckedadcb.setImageRequest(imageRequest);DraweeController controller = adcb.build();setController(controller);}}
【自动覆盖渐变蒙层遮罩的Fresco.SimpleDraweeView】用法:
如图的第一张与第三张即为叠加了遮罩的比较明显的效果 。其实第二张也叠加了遮罩,只是遮罩蒙层的颜色与美工的遮罩蒙层颜色基本一致,不太看得出来 。
当然,毕竟是通过算法获取的活跃颜色,因此不一定满足美术规则,但至少不至于让标题看不见 。这个可以通过增加接口字段 , 来决定是否需要本地遮罩来缓解这个问题 。
- 华为手机自动关机怎么设置 手机自动关机怎么设置
- photoshop五种渐变类型 ps五种渐变类型
- 台式电脑自动下载垃圾软件怎么办 电脑自动下载垃圾软件怎么办
- 林内壁挂炉运行几分钟就停机 林内壁挂炉运行几分钟就停机自动停机显示12
- 关了自动调节亮度怎么还会黑 关掉了自动亮度调节还是变暗
- 爱奇艺怎么关掉会员的自动续费 爱奇艺怎么关闭会员自动续费?
- 福特蒙迪欧自动雨刷怎么用 福特蒙迪欧的雨刮器怎么使用?
- 传真机怎么发传真 自动传真机怎么发传真
- 河北银行信用卡怎么还 河北银行信用卡怎么还款
- 全自动洗衣机 全自动洗衣机简介