已编辑:Android 将针形图像绘制到类似于米规的圆圈
Edited: Android Draw needle image to this circle similar to meter guage
到目前为止,我可以使用一些代码参考表单 Whosebug 绘制半圆。现在我想在这个半圆上画针。
我不知道该怎么做。这是半圆代码
package in.ashish29agre.Whosebug.sample.semicircle;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.view.View;
public class MyGraphView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float[] value_degree;
private int[] COLORS = { Color.GREEN, Color.RED, Color.GREEN, Color.RED };
// size of bigger half circle
RectF rectf = null;
// size of smaller half circle
// RectF rectf2 = new RectF(45, 45, 275, 275);
// size of the smallest half circle
// RectF rectf3 = new RectF(80, 80, 240, 240);
int temp = 0;
public MyGraphView(Context context, float[] values) {
super(context);
rectf = new RectF();
value_degree = new float[values.length];
for (int i = 0; i < values.length; i++) {
value_degree[i] = values[i];
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
rectf.set(100, 100, width - 100, height - 100);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
for (int i = 0; i < value_degree.length; i++) {
// set type of "brush"
paint.setStrokeWidth(128);
paint.setStyle(Paint.Style.STROKE);
// agree
if (i == 0) {
final Path path = new Path();
paint.setColor(COLORS[i]);
// draw 3 paths to show 3 curves
path.addArc(rectf, 180, value_degree[i] - 4);
// path.addArc(rectf2, 180, value_degree[i] - 5);
// path.addArc(rectf3, 180, value_degree[i] - 6);
// draw the path
canvas.drawPath(path, paint);
// disagree
} else {
temp += (int) value_degree[i - 1];
paint.setColor(COLORS[i]);
final Path path = new Path();
path.addArc(rectf, temp + 180 , value_degree[i] - 0);
// path.addArc(rectf2, temp + 180 + 5, value_degree[i] - 5);
// path.addArc(rectf3, temp + 180 + 6, value_degree[i] - 6);
// draw the path
canvas.drawPath(path, paint);
}
drawLine(canvas);
}
}
private void drawLine(Canvas canvas) {
float startAngle = 180;
float sweepAngle = 180;
Paint mPaint = new Paint();
mPaint.setStrokeWidth(22f);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
float startX = rectf.centerX();
float startY = rectf.centerY();
float radius = rectf.centerX() - 100;
float angle = (float) ((startAngle + sweepAngle / 2) * Math.PI / 180);
float stopX = (float) (startX + radius * Math.cos(angle));
float stopY = (float) (startY + radius * Math.sin(angle));
canvas.drawLine(startX, startY, stopX, stopY, mPaint);
}
}
来自 Activity 我用
称呼它
float values[] = { 10, 20, 30, 40};
LinearLayout linear = (LinearLayout) findViewById(R.id.graph_view);
values = calculateData(values);
// draw the graf
linear.addView(new MyGraphView(this, values));
这是我的activityxml代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="in.ashish29agre.Whosebug.sample.semicircle.SemiCircleActivity">
<LinearLayout
android:id="@+id/graph_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_alignParentTop="true"></LinearLayout>
</RelativeLayout>
目前视图看起来像这样现在我想添加可以从 0-180 度移动的仪表指针。
我们将不胜感激。
既然我画好了针我想做成针位图??
添加到您的class:
Matrix matrix;
Bitmap needle;
到您的 MyGraphView 构造函数:
matrix = new Matrix();
这是 onMeasure() 的结尾:
needle = decodeSampledBitmapFromResource(context.getResources(),
R.drawable.icon_resource, (int)rectf.width(), (int)rectf.height());
在 drawLine() 中:
private void drawLine(Canvas canvas) {
float startAngle = 180;
float sweepAngle = 180;
// of course you'll need to calculate the actual angle here:
float angle = (float) ((startAngle + sweepAngle / 2) * Math.PI / 180);
matrix.reset();
// move the needle to IT's center. You might need different
// values depending on your drawable, probably the axis will not
// be in the middle
matrix.postTranslate(-bitmap.getWidth() / 2, -bitmap.getWidth() / 2);
// and rotate it
matrix.postRotate(angle);
// move the needle to the semi circle's center
matrix.postTranslate(rectf.centerX(), rectf.centerY());
canvas.drawBitmap(needle, matrix, null);
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
您可能想要制作针位图的动画。这是我的代码:
RotateAnimation animation =
new RotateAnimation(
mCurrentAngle,
toAngle,
Animation.RELATIVE_TO_SELF,
pivotX,
Animation.RELATIVE_TO_SELF,
pivotY);
animation.setRepeatCount(0);
animation.setFillAfter(true);
animation.setFillEnabled(true);
animation.setInterpolator(new OvershootInterpolator());
animation.setDuration(duration);
mMeterPointer.startAnimation(animation);
其中 mMeterPointer 是指针的 ImageView。
pivotX
和 pivotY
值应位于针图像应旋转的位置。它们的值应该是 0 to 1
,例如0.5 和 0.5 如果你想让它在位图的中间旋转。
添加到@bennegeek 的回答中,你能试试这个吗
private void setAngleToNeedle() {
int value = 675;
int maxValue = 1000;
int angleDifference = 180;
int endingAngle = (int) (((float) value / maxValue) * (angleDifference));
final RotateAnimation rotateAnim = new RotateAnimation(-90, -90 + endingAngle,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 1f);
rotateAnim.setDuration(1500);
rotateAnim.setInterpolator(new LinearInterpolator());
rotateAnim.setFillAfter(true);
needleIv.startAnimation(rotateAnim);
}
到目前为止,我可以使用一些代码参考表单 Whosebug 绘制半圆。现在我想在这个半圆上画针。 我不知道该怎么做。这是半圆代码
package in.ashish29agre.Whosebug.sample.semicircle;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.view.View;
public class MyGraphView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float[] value_degree;
private int[] COLORS = { Color.GREEN, Color.RED, Color.GREEN, Color.RED };
// size of bigger half circle
RectF rectf = null;
// size of smaller half circle
// RectF rectf2 = new RectF(45, 45, 275, 275);
// size of the smallest half circle
// RectF rectf3 = new RectF(80, 80, 240, 240);
int temp = 0;
public MyGraphView(Context context, float[] values) {
super(context);
rectf = new RectF();
value_degree = new float[values.length];
for (int i = 0; i < values.length; i++) {
value_degree[i] = values[i];
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
rectf.set(100, 100, width - 100, height - 100);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
for (int i = 0; i < value_degree.length; i++) {
// set type of "brush"
paint.setStrokeWidth(128);
paint.setStyle(Paint.Style.STROKE);
// agree
if (i == 0) {
final Path path = new Path();
paint.setColor(COLORS[i]);
// draw 3 paths to show 3 curves
path.addArc(rectf, 180, value_degree[i] - 4);
// path.addArc(rectf2, 180, value_degree[i] - 5);
// path.addArc(rectf3, 180, value_degree[i] - 6);
// draw the path
canvas.drawPath(path, paint);
// disagree
} else {
temp += (int) value_degree[i - 1];
paint.setColor(COLORS[i]);
final Path path = new Path();
path.addArc(rectf, temp + 180 , value_degree[i] - 0);
// path.addArc(rectf2, temp + 180 + 5, value_degree[i] - 5);
// path.addArc(rectf3, temp + 180 + 6, value_degree[i] - 6);
// draw the path
canvas.drawPath(path, paint);
}
drawLine(canvas);
}
}
private void drawLine(Canvas canvas) {
float startAngle = 180;
float sweepAngle = 180;
Paint mPaint = new Paint();
mPaint.setStrokeWidth(22f);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
float startX = rectf.centerX();
float startY = rectf.centerY();
float radius = rectf.centerX() - 100;
float angle = (float) ((startAngle + sweepAngle / 2) * Math.PI / 180);
float stopX = (float) (startX + radius * Math.cos(angle));
float stopY = (float) (startY + radius * Math.sin(angle));
canvas.drawLine(startX, startY, stopX, stopY, mPaint);
}
}
来自 Activity 我用
称呼它float values[] = { 10, 20, 30, 40};
LinearLayout linear = (LinearLayout) findViewById(R.id.graph_view);
values = calculateData(values);
// draw the graf
linear.addView(new MyGraphView(this, values));
这是我的activityxml代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="in.ashish29agre.Whosebug.sample.semicircle.SemiCircleActivity">
<LinearLayout
android:id="@+id/graph_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_alignParentTop="true"></LinearLayout>
</RelativeLayout>
目前视图看起来像这样现在我想添加可以从 0-180 度移动的仪表指针。
我们将不胜感激。
既然我画好了针我想做成针位图??
添加到您的class:
Matrix matrix;
Bitmap needle;
到您的 MyGraphView 构造函数:
matrix = new Matrix();
这是 onMeasure() 的结尾:
needle = decodeSampledBitmapFromResource(context.getResources(),
R.drawable.icon_resource, (int)rectf.width(), (int)rectf.height());
在 drawLine() 中:
private void drawLine(Canvas canvas) {
float startAngle = 180;
float sweepAngle = 180;
// of course you'll need to calculate the actual angle here:
float angle = (float) ((startAngle + sweepAngle / 2) * Math.PI / 180);
matrix.reset();
// move the needle to IT's center. You might need different
// values depending on your drawable, probably the axis will not
// be in the middle
matrix.postTranslate(-bitmap.getWidth() / 2, -bitmap.getWidth() / 2);
// and rotate it
matrix.postRotate(angle);
// move the needle to the semi circle's center
matrix.postTranslate(rectf.centerX(), rectf.centerY());
canvas.drawBitmap(needle, matrix, null);
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
您可能想要制作针位图的动画。这是我的代码:
RotateAnimation animation =
new RotateAnimation(
mCurrentAngle,
toAngle,
Animation.RELATIVE_TO_SELF,
pivotX,
Animation.RELATIVE_TO_SELF,
pivotY);
animation.setRepeatCount(0);
animation.setFillAfter(true);
animation.setFillEnabled(true);
animation.setInterpolator(new OvershootInterpolator());
animation.setDuration(duration);
mMeterPointer.startAnimation(animation);
其中 mMeterPointer 是指针的 ImageView。
pivotX
和 pivotY
值应位于针图像应旋转的位置。它们的值应该是 0 to 1
,例如0.5 和 0.5 如果你想让它在位图的中间旋转。
添加到@bennegeek 的回答中,你能试试这个吗
private void setAngleToNeedle() {
int value = 675;
int maxValue = 1000;
int angleDifference = 180;
int endingAngle = (int) (((float) value / maxValue) * (angleDifference));
final RotateAnimation rotateAnim = new RotateAnimation(-90, -90 + endingAngle,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 1f);
rotateAnim.setDuration(1500);
rotateAnim.setInterpolator(new LinearInterpolator());
rotateAnim.setFillAfter(true);
needleIv.startAnimation(rotateAnim);
}