android -- 如何在圆中画一个矩形
android -- How to draw a rect in circle
我需要如下视图:
蓝色高度会根据语音更新
我知道用可以画出那个圆角矩形
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bg_send_text" />
<corners android:radius="100dip" />
</shape>
然后我写了一个 VoiceDrawable extends GradientDrawable,并使用这个代码:
public void setVoice(int voice) {
level = (float) 1.0 * voice / 100;
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
rect = getBounds();
canvas.drawRect(rect.left, rect.top + (rect.bottom - rect.top) *
(1 - level), rect.right, rect.bottom, paint);
}
但结果是:
虽然我使用:
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
那么如何实现这个视图呢?我能做什么?
您应该更改您的 PorterDuff 模式:
全部
我已经实现了这个视图:
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.GradientDrawable;
public class VoiceDrawable extends GradientDrawable {
private static final float DEFAULT_LEVEL = 0.5f;
private Paint levelPaint;
private Paint viewPaint;
private BitmapShader bitmapShader;
private Matrix shaderMatrix;
private float radius;
private float level;
public VoiceDrawable() {
super();
init();
}
private void init() {
levelPaint = new Paint();
levelPaint.setStyle(Paint.Style.FILL);
viewPaint = new Paint();
shaderMatrix = new Matrix();
}
public void setCornerRadius(float radius) {
super.setCornerRadius(radius);
this.radius = radius;
}
public void setVoice(float level) {
this.level = level;
invalidateSelf();
}
public void setLevelColor(int color) {
levelPaint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Rect rect = getBounds();
if (bitmapShader == null) {
initLevel(rect);
}
float scale = level == 0 ? 100 : (1 - level) / (1 - DEFAULT_LEVEL);
shaderMatrix.setScale(1, scale, 0, DEFAULT_LEVEL);
bitmapShader.setLocalMatrix(shaderMatrix);
float rad = Math.min(radius, Math.min(rect.width(), rect.height()) * 0.5f);
canvas.drawRoundRect(new RectF(rect), rad, rad, viewPaint);
}
private void initLevel(Rect rect) {
Bitmap bitmap = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawRect(rect.left, rect.top + rect.height() * (1 - DEFAULT_LEVEL), rect.right, rect.bottom, levelPaint);
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
viewPaint.setShader(bitmapShader);
}
}
主要思想是使用着色器。
我从 https://github.com/gelitenight/WaveView
得到灵感
我需要如下视图:
蓝色高度会根据语音更新
我知道用可以画出那个圆角矩形
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bg_send_text" />
<corners android:radius="100dip" />
</shape>
然后我写了一个 VoiceDrawable extends GradientDrawable,并使用这个代码:
public void setVoice(int voice) {
level = (float) 1.0 * voice / 100;
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
rect = getBounds();
canvas.drawRect(rect.left, rect.top + (rect.bottom - rect.top) *
(1 - level), rect.right, rect.bottom, paint);
}
但结果是:
虽然我使用:
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
那么如何实现这个视图呢?我能做什么?
您应该更改您的 PorterDuff 模式:
全部
我已经实现了这个视图:
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.GradientDrawable;
public class VoiceDrawable extends GradientDrawable {
private static final float DEFAULT_LEVEL = 0.5f;
private Paint levelPaint;
private Paint viewPaint;
private BitmapShader bitmapShader;
private Matrix shaderMatrix;
private float radius;
private float level;
public VoiceDrawable() {
super();
init();
}
private void init() {
levelPaint = new Paint();
levelPaint.setStyle(Paint.Style.FILL);
viewPaint = new Paint();
shaderMatrix = new Matrix();
}
public void setCornerRadius(float radius) {
super.setCornerRadius(radius);
this.radius = radius;
}
public void setVoice(float level) {
this.level = level;
invalidateSelf();
}
public void setLevelColor(int color) {
levelPaint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Rect rect = getBounds();
if (bitmapShader == null) {
initLevel(rect);
}
float scale = level == 0 ? 100 : (1 - level) / (1 - DEFAULT_LEVEL);
shaderMatrix.setScale(1, scale, 0, DEFAULT_LEVEL);
bitmapShader.setLocalMatrix(shaderMatrix);
float rad = Math.min(radius, Math.min(rect.width(), rect.height()) * 0.5f);
canvas.drawRoundRect(new RectF(rect), rad, rad, viewPaint);
}
private void initLevel(Rect rect) {
Bitmap bitmap = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawRect(rect.left, rect.top + rect.height() * (1 - DEFAULT_LEVEL), rect.right, rect.bottom, levelPaint);
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
viewPaint.setShader(bitmapShader);
}
}
主要思想是使用着色器。 我从 https://github.com/gelitenight/WaveView
得到灵感