Comments (6)
只有ImageView会有这个问题,边框绘制了但是被图片压在下面了。。。。
from backgroundlibrary.
可以先用padding相同宽度临时解决这个问题...
from backgroundlibrary.
这个框架本质上还是view.setbackground,尽量不要在imageview上使用
from backgroundlibrary.
但是圆角图片 图片边框是很常用的功能啊...
from backgroundlibrary.
这个框架本质上还是view.setbackground,尽量不要在imageview上使用
大佬 我在BLImageView的基础上,对图片做了额外的处理,可以将边框盖在上面,但是破坏你的设计结构,你看能不能改改,也能支持边框和内容增加间距
package com.nf.background.library.view;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.nf.background.R;
import com.nf.background.library.BackgroundFactory;
public class BLImageView extends AppCompatImageView {
private Paint paint;//用于绘制Layer
private Paint borderPaint;//用于绘制描边
int strokeWidth = 0;
//只处理一种
int radius = 0;
int strokeColor = 0;
float strokeDashWidth = 0;
float strokeGap = 0;
public BLImageView(Context context) {
super(context);
}
public BLImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public BLImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
BackgroundFactory.setViewBackground(context, attrs, this);
@SuppressLint({"Recycle", "CustomViewStyleable"})
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.background);
strokeWidth = typedArray.getDimensionPixelSize(R.styleable.background_bl_stroke_width, 0);
radius = typedArray.getDimensionPixelSize(R.styleable.background_bl_corners_radius, 0);
strokeColor = typedArray.getColor(R.styleable.background_bl_stroke_color, 0);
strokeDashWidth = typedArray.getDimension(R.styleable.background_bl_stroke_dashWidth, 0f);
strokeGap = typedArray.getDimension(R.styleable.background_bl_stroke_dashGap, 0f);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(strokeWidth);
borderPaint.setColor(strokeColor);
updateSrc();
typedArray.recycle();
}
public void updateSrc() {
Drawable drawable = this.getDrawable();
if (drawable != null) {
setImageDrawable(drawable);
}
borderPaint.setStrokeWidth(strokeWidth);
borderPaint.setColor(strokeColor);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
Log.w("FFFF", "strokeWidth =" + strokeWidth);
// 使用局部变量,降低函数调用次数
int vw = getMeasuredWidth();
int vh = getMeasuredHeight();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
// 绘制描边
if (strokeWidth != 0) {
RectF rectF = new RectF(paddingLeft, paddingTop, vw - paddingRight, vh - paddingBottom);
// 描边会有一半处于框体之外
float i = strokeWidth / 2;
// 移动矩形,以便于描边都处于view内
rectF.inset(i, i);
// 绘制描边,半径需要进行偏移 i
drawPath(canvas, rectF, borderPaint, i);
}
if ((null != drawable && drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0)) {
RectF rectF = new RectF(paddingLeft, paddingTop, vw - paddingRight, vh - paddingBottom);
// 矩形需要缩小的值
//这里可以处理 边框和内容的边距
int strokeSpace = 0;
float i = strokeWidth + strokeSpace;
// 这里解释一下,为什么要减去一个像素,因为像素融合时,由于锯齿的存在和图片像素不高,会导致图片和边框出现1像素的间隙
// 大家可以试一下,去掉这一句,然后用高清图就不会出问题,用非高清图就会出现
i = i > 1 ? i - 1 : 0;
// 矩形偏移
rectF.inset(i, i);
int layerId = canvas.saveLayer(rectF, null, Canvas.ALL_SAVE_FLAG);
// 多边形
drawPath(canvas, rectF, paint, i);
// 设置像素融合模式
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// drawable转为 bitmap
Bitmap bitmap = drawableToBitmap(drawable);
// 根据图片的大小,控件的大小,图片的展示形式,然后来计算图片的src取值范围
Rect src = getSrc(bitmap, (int) rectF.width(), (int) rectF.height());
// dst取整个控件,也就是表示,我们的图片要占满整个控件
canvas.drawBitmap(bitmap, src, rectF, paint);
paint.setXfermode(null);
canvas.restoreToCount(layerId);
} else {
super.onDraw(canvas);
}
}
private Rect getSrc(@NonNull Bitmap bitmap, int rw, int rh) {
// bw bh,bitmap 的宽高
// vw vh,view 的宽高
int bw = bitmap.getWidth();
int bh = bitmap.getHeight();
int left = 0, top = 0, right = 0, bottom = 0;
// 判断 bw/bh 与 rw/rh
int temp1 = bw * rh;
int temp2 = rw * bh;
// 相似矩形的宽高
int[] tempRect = {bw, bh};
if (temp1 == temp2) {
return new Rect(0, 0, bw, bh);
}
// tempRect 的宽度比 bw 小
else if (temp1 > temp2) {
int tempBw = temp2 / rh;
tempRect[0] = tempBw;
}
// tempRect 的宽度比 bw 大
else if (temp1 < temp2) {
int tempBh = temp1 / rw;
tempRect[1] = tempBh;
}
// tempRect 的宽度与 bw 的比值
Boolean compare = bw > tempRect[0];
// 居中 (PS 其他缩放模式没写)
left = compare ? (bw - tempRect[0]) / 2 : 0;
top = compare ? 0 : (bh - tempRect[1]) / 2;
right = compare ? (bw + tempRect[0]) / 2 : tempRect[0];
bottom = compare ? tempRect[1] : (bh + tempRect[1]) / 2;
return new Rect(left, top, right, bottom);
}
private void drawPath(Canvas canvas, RectF rectF, Paint paint, float offset) {
Path path = new Path();
path.addRoundRect(rectF,
new float[]{
radius, radius,
radius, radius,
radius, radius,
radius, radius}, Path.Direction.CW);
path.close();
canvas.drawPath(path, paint);
}
private Bitmap drawableToBitmap(Drawable drawable) {
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
//注意,下面三行代码要用到,否则在View或者SurfaceView里的canvas.drawBitmap会看不到图
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}
}
from backgroundlibrary.
你这种写法我觉得还是不太好,onDraw里面还创建对象,性能就差很多。你非要用的话还不如直接imageView外面包一层FrameLayout然后封装一下,那样bug少性能也不会差太多
from backgroundlibrary.
Related Issues (20)
- tint colorfilter无效
- Android Studio BumbleBee 没有settingsRepository\repository\templates这些目录 HOT 2
- bl_enabled_gradient_centerColor
- 混淆问题 HOT 1
- 能否增加RTL支持 HOT 3
- Support ripple drawable
- about render error HOT 2
- 大小异常 HOT 2
- Recycleview Item不生效 HOT 3
- 不支持预览 HOT 1
- 文字渐变色没生效
- 新版本Android stuio(Electric Eel | 2022.1.1) 用了本库之后 xml布局文件不能预览 HOT 1
- 某些场景下圆角不生效
- 列表item设置圆角无效,但背景色设置上去了 HOT 1
- 海外出现启动时崩溃问题 HOT 1
- elevation问题
- MultiTextColorSelectorColorCreator中对颜色值的判断有误 HOT 1
- 外部布局设置圆角,里面的布局会生效吗? HOT 1
- 关于代码设置bl_stroke_position的问题 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from backgroundlibrary.