11

私の顧客はアプリケーションで次のウィジェットを望んでいます:
ここに画像の説明を入力
サーバーTextから来ます。勾配角度は、サーバーからの変数にも依存します。また、顧客はグラデーションが動的に塗りつぶされることを望んでいます (ユーザーはグラデーションが 0 からどのように塗りつぶされるかを確認する必要があります)。
2 つの画像を使用します。1 つは色付きの円、もう 1 つは灰色の円です。特定の角度で円セグメントを作成し、それをマスクとして灰色の円に適用してから、色付きの円を新しい灰色の円 (扇形が切り取られた場所) と結合します。
これが私のコードです。を呼び出して変数を初期化しinitializeVarsForCompoundImDrawing、次に を数回呼び出しmakeCompoundImage、最後に を呼び出しnullVarsForCompoundImDrawingてリソースを解放します。

private static Bitmap notColoredBitmap;
private static Bitmap coloredBitmap;
private static Bitmap notColoredWithMaskBitmap;
private static Bitmap finalBitmap;
private static Canvas notColoredWithMaskCanvas;
private static Paint paintForMask;
private static Paint smoothPaint;
private static Canvas finalCanvas;
private static RectF rectForMask;

public static void initializeVarsForCompoundImDrawing()
{
    Context context = MainApplication.getContext();
    notColoredBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.not_colored);
    coloredBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.colored);
    
    paintForMask = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintForMask.setStyle(Paint.Style.FILL);
    paintForMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    rectForMask = new RectF(0, 0, notColoredBitmap.getWidth(), notColoredBitmap.getHeight());

    smoothPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}

public static void nullVarsForCompoundImDrawing()
{
    notColoredBitmap = null;
    coloredBitmap = null;
    
    paintForMask = null;
    rectForMask = null;
    smoothPaint = null;
}

public static void makeCompoundImage(ImageView imageView, int angle)
{
    notColoredWithMaskBitmap = Bitmap.createBitmap(notColoredBitmap.getWidth(), notColoredBitmap.getHeight(), Bitmap.Config.ARGB_8888);
    notColoredWithMaskCanvas = new Canvas(notColoredWithMaskBitmap);
    notColoredWithMaskCanvas.drawBitmap(notColoredBitmap, 0, 0, smoothPaint);
    notColoredWithMaskCanvas.drawArc(rectForMask, 270, angle, true, paintForMask);

    finalBitmap = Bitmap.createBitmap(notColoredBitmap.getWidth(), notColoredBitmap.getHeight(), Bitmap.Config.ARGB_8888);
    finalCanvas = new Canvas(finalBitmap);
    finalCanvas.drawBitmap(coloredBitmap, 0, 0, smoothPaint);
    finalCanvas.drawBitmap(notColoredWithMaskBitmap, 0, 0, smoothPaint);

    imageView.setImageBitmap(finalBitmap);
}

最初の質問: このコードを改善して、使用するリソースを減らすことは可能ですか?
2 番目の質問: テキストを に追加するにはどうすればよいですかfinalBitmap(TextViewこれは の上部にImageView画像と共に表示されます)。

4

3 に答える 3

8

あなたの質問に答える: はい、もっと簡単にできます:

public class Ring extends View {
    private Bitmap mBack;
    private Paint mPaint;
    private RectF mOval;
    private Paint mTextPaint;

    public Ring(Context context) {
        super(context);
        Resources res = getResources();
        mBack = BitmapFactory.decodeResource(res, R.drawable.back);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Bitmap ring = BitmapFactory.decodeResource(res, R.drawable.ring);
        mPaint.setShader(new BitmapShader(ring, TileMode.CLAMP, TileMode.CLAMP));
        mOval = new RectF(0, 0, mBack.getWidth(), mBack.getHeight());
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(24);
        mTextPaint.setTextAlign(Align.CENTER);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.translate((getWidth() - mBack.getWidth()) / 2, (getHeight() - mBack.getHeight()) / 2);
        canvas.drawBitmap(mBack, 0, 0, null);
        float angle = 220;
        canvas.drawArc(mOval, -90, angle, true, mPaint);
        canvas.drawText("Text",
            mBack.getWidth() / 2,
            (mBack.getHeight() - mTextPaint.ascent()) / 2,
            mTextPaint);
    }
}

編集:

これは代替ソリューションです(センタリングなし、内部にテキストなし、単なる概念)

class Ring extends View {
    private Bitmap back;
    private Bitmap ring;
    private RectF oval;
    private Paint arcPaint;

    public Ring(Context context) {
        super(context);
        Resources res = getResources();
        back = BitmapFactory.decodeResource(res, R.drawable.back);
        ring = BitmapFactory.decodeResource(res, R.drawable.ring);
        arcPaint = new Paint();
        arcPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
        oval = new RectF(-1, -1, ring.getWidth()+1, ring.getHeight()+1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawARGB(0xaa, 0, 255, 0);
        canvas.drawBitmap(back, 0, 0, null);
        canvas.saveLayer(oval, null, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
        canvas.drawBitmap(ring, 0, 0, null);
        float angle = 300;
        canvas.drawArc(oval, angle-90, 360-angle, true, arcPaint);
        canvas.restore();
    }
}
于 2013-10-11T11:46:01.030 に答える
6

私のプロジェクトを例https://github.com/donvigo/CustomProgressControlsとして使用できます。github にはまだ文書化されていませんが、私のコードを理解していただければ幸いです :)

編集:円内のテキストは ではなく、TextViewを使用して描画されpaintます。

于 2013-10-11T11:24:33.797 に答える