Coder Social home page Coder Social logo

bl_stroke_width about backgroundlibrary HOT 6 CLOSED

AlbertZyc avatar AlbertZyc commented on July 21, 2024
bl_stroke_width

from backgroundlibrary.

Comments (6)

AlbertZyc avatar AlbertZyc commented on July 21, 2024

只有ImageView会有这个问题,边框绘制了但是被图片压在下面了。。。。

from backgroundlibrary.

AlbertZyc avatar AlbertZyc commented on July 21, 2024

可以先用padding相同宽度临时解决这个问题...

from backgroundlibrary.

JavaNoober avatar JavaNoober commented on July 21, 2024

这个框架本质上还是view.setbackground,尽量不要在imageview上使用

from backgroundlibrary.

AlbertZyc avatar AlbertZyc commented on July 21, 2024

但是圆角图片 图片边框是很常用的功能啊...

from backgroundlibrary.

AlbertZyc avatar AlbertZyc commented on July 21, 2024

这个框架本质上还是view.setbackground,尽量不要在imageview上使用
大佬 我在BLImageView的基础上,对图片做了额外的处理,可以将边框盖在上面,但是破坏你的设计结构,你看能不能改改,也能支持边框和内容增加间距

1656595964(1)

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.

JavaNoober avatar JavaNoober commented on July 21, 2024

你这种写法我觉得还是不太好,onDraw里面还创建对象,性能就差很多。你非要用的话还不如直接imageView外面包一层FrameLayout然后封装一下,那样bug少性能也不会差太多

from backgroundlibrary.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.