我有一个三角形图像,其一条边与圆形的方向始终相同。 必须根据用户滑动/拖动在圆圈周围移动此图像。因此,它必须旋转(使其边缘与圆圈方向相同)并同时围绕圆圈旋转。
如何实现此功能?
更新:我的自定义视图如下:
public class ThermoView extends FrameLayout{
private ImageView mThermoBgrd;
private ImageView mCurTempArrow;
public static final int THEMROSTAT_BACKGROUND = 0;
public static final int THEMROSTAT_CURR_TEMP = 1;
public ThermostatView(Context context, AttributeSet attrs) {
super(context, attrs);
mThermoBgrd = new ImageView(context);
mThermoBgrd.setImageResource(R.drawable.circle_icon);
addView(mThermoBgrd, ThermostatView.THEMROSTAT_BACKGROUND);
mCurTempArrow = new ImageView(context);
mCurTempArrow.setImageResource(R.drawable.ruler_triangle_icon);
mCurTempArrow.setScaleType(ImageView.ScaleType.MATRIX);
addView(mCurTempArrow, ThermostatView.THEMROSTAT_CURR_TEMP, new LayoutParams(50, 50));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
int currTempHeight = mCurTempArrow.getMeasuredHeight();
int currTempWidth = mCurTempArrow.getMeasuredWidth();
int parentWidth = right - left;
int parentHeight = bottom - top;
int padding = currTempHeight;
//We need square container for the circle.
int containerLeft = padding;
int containerTop = parentHeight - parentWidth + padding;
int containerRight = parentWidth - padding;
int containerBottom = parentHeight - padding;
int containerWidth = containerRight - containerLeft;
int containerHeight = containerBottom - containerTop;
//place the arrow indicating current temperature
int curTempLeft = containerRight - ((containerWidth/2) + currTempWidth/2);
int curTempTop = containerTop - (currTempHeight/2);
int curTempRight = curTempLeft + currTempWidth;
int curTempBottom = curTempTop + currTempHeight;
mCurTempArrow.layout(curTempLeft, curTempTop, curTempRight, curTempBottom);
}
答案 0 :(得分:3)
尝试这个(它使用路径而不是位图,但想法是一样的):
public class MyView extends View {
private Paint mPaint;
private Path mTriangle;
private Path mCircle;
private Matrix mMatrix;
private float mAngle;
public MyView(Context context) {
super(context);
mPaint = new Paint();
mPaint.setStrokeWidth(10);
mPaint.setStyle(Style.STROKE);
mTriangle = new Path();
mTriangle.moveTo(0, -21);
mTriangle.lineTo(0, 21);
mTriangle.lineTo(36, 0);
mTriangle.close();
mCircle = new Path();
mCircle.addCircle(0, 0, 50, Direction.CW);
mMatrix = new Matrix();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mAngle = (float) (180 * Math.atan2(event.getY() - h2, event.getX() - w2) / Math.PI);
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mMatrix.reset();
mMatrix.postTranslate(w2, h2);
canvas.concat(mMatrix);
mPaint.setColor(0xaaff0000);
canvas.drawPath(mCircle, mPaint);
mMatrix.reset();
mMatrix.postTranslate(60, 0);
mMatrix.postRotate(mAngle);
canvas.concat(mMatrix);
mPaint.setColor(0xaa00ff00);
canvas.drawPath(mTriangle, mPaint);
}
}
答案 1 :(得分:0)
由于我不知道你是使用open GL还是标准canevas,我真的不能给你一些工作代码。但一般的想法是(假设您存储了三角形(x,y)的当前位置,并且存储了圆圈的中心(cx,cy)。
执行以下操作:
v = (cx-x, cy-y) // v is the normal vector of your triangle: it faces the center of the circle
triangle.translate(v) // translate to the center of the circle
triangle.rotate(angle) // rotate the triangle on itself
v.rotate(angle) // apply the same rotation on the normal vector
triangle.translate(-v) // translate back on the circle, but since v is rotated, the position will be updated
我希望它足够清楚,祝你好运
修改强> 首先,你应该真正尝试更准确:在你的第一篇文章中,你没有说三角形是一个图像(这很重要)。然后你不说你当前的渲染是什么,什么有用,有什么不可用。我会更容易帮助您了解您的程序当前显示的内容。
从您的代码中,我假设您正确放置了三角形图像,但它没有旋转。首先,尝试添加
//place the arrow indicating current temperature
int curTempLeft = containerRight - ((containerWidth/2) + currTempWidth/2);
int curTempTop = containerTop - (currTempHeight/2);
int curTempRight = curTempLeft + currTempWidth;
int curTempBottom = curTempTop + currTempHeight;
mCurTempArrow.setRotate(angle); // rotate the image. angle is in degrees
mCurTempArrow.layout(curTempLeft, curTempTop, curTempRight, curTempBottom);
如果你不知道角度,你可能需要从三角形的先前位置计算它