package com.hdl.sdk.sourceos.qrcode; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.util.AttributeSet; import android.view.View; import androidx.annotation.Nullable; import androidx.annotation.Px; import java.util.concurrent.atomic.AtomicBoolean; /** * Created by Tong on 2021/12/2. * 二维码View */ public class QrCodeView extends View { private static final int DEF_MARGIN = 0; private int mWidth; private int mHeight; private String mContent; private int mMargin = DEF_MARGIN; private Bitmap drawBitmap; private Canvas drawCanvas; private Paint paint; private final AtomicBoolean isDraw = new AtomicBoolean(false); private DrawThread mDrawThread; public QrCodeView(Context context) { this(context, null); } public QrCodeView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public QrCodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (drawBitmap != null) { canvas.drawBitmap(drawBitmap, getPaddingLeft(), getPaddingTop(), paint); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mHeight = h - getPaddingTop() - getPaddingBottom(); mWidth = w - getPaddingStart() - getPaddingEnd(); if (drawBitmap == null || (drawBitmap.isRecycled() || drawBitmap.getWidth() != mWidth || drawBitmap.getHeight() != mHeight)) { drawBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); drawCanvas = new Canvas(drawBitmap); startDraw(); } } public void setContent(String content) { setContent(content, DEF_MARGIN); } public void setContent(String content, @Px int margin) { this.mContent = content; startDraw(); this.mMargin = margin; } public String getContent() { return mContent; } public void startDraw() { if (mContent == null || isDraw.get()) return; isDraw.set(true); mDrawThread = new DrawThread(); mDrawThread.start(); } private void init() { paint = new Paint(Paint.ANTI_ALIAS_FLAG); } private class DrawThread extends Thread { @Override public void run() { while (isDraw.get()) try { if (drawCanvas != null) { drawCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); int size = Math.min(mHeight, mWidth); QRCodeUtils.createQRCode(drawBitmap, mContent, size, size, mMargin); postInvalidate(); isDraw.set(false); } } catch (Exception e) { e.printStackTrace(); } finally { if (isDraw.get()) { try { Thread.sleep(200L); } catch (Exception ignore) { } } } } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (drawBitmap != null) { drawBitmap.recycle(); } isDraw.set(false); if (mDrawThread != null) { mDrawThread.interrupt(); } } }