我有一个自定义视图,我在这个大圆圈的边缘画了一个大圆圈和一个小圆圈。
我想移动小圆圈,因此只想为小圆圈设置一个ontouch听众。
有些人可以告诉我如何只为小圆圈设置ontouch监听器。
public class ThermoView extends View{
private ImageView mThermostatBgrd;
private ImageView mCurTempArrow;
private ImageView mSetPointIndicator;
public static final int THEMROSTAT_BACKGROUND = 0;
public static final int THEMROSTAT_CURR_TEMP = 1;
public static final int THEMROSTAT_SET_POINT = 2;
private float mViewCentreX;
private float mViewCentreY;
private float mThermostatRadius;
private Canvas mCanvas;
private Paint mPaint;
private Paint mPaintCurTemp;
private Paint mPaintSetTemp;
private Paint mPaintOverrideTemp;
private Paint mPaintCurTempIndicator;
private Boolean mManualOverride = false;
private double mManualOverrideAngle;
private int mMaxTemp = 420;
private int mMinTemp = 120;
private RectF mCurrTempBox;
private float mCurTempCircleX;
private float mCurTempCircleY;
private Matrix mMatrix;
public double getManualOverrideAngle() {
return mManualOverrideAngle;
}
public void setManualOverrideAngle(double mManualOverrideAngle) {
this.mManualOverrideAngle = mManualOverrideAngle;
}
public RectF getCurrTempBox() {
if (mCurrTempBox == null){
mCurrTempBox = new RectF();
}
return mCurrTempBox;
}
public void setCurrTempBox(RectF mCurrTempBox) {
this.mCurrTempBox = mCurrTempBox;
}
public Boolean getManualOverride() {
return mManualOverride;
}
public void setManualOverride(Boolean mManualOverride) {
this.mManualOverride = mManualOverride;
}
public ThermoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path smallCirle = new Path();
int viewWidth = getMeasuredWidth();
int viewHeight = getMeasuredHeight();
mViewCentreX = viewWidth/2;
mViewCentreY = viewHeight/2;
float paddingPercent = 0.2f;
int thermostatThickness = 20;
mThermostatRadius = (int) ((Math.min(mViewCentreX, mViewCentreY)*(1- paddingPercent)));
if (mPaint == null){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(thermostatThickness);
mPaint.setColor(0xffff0000);
Path arcPath = new Path();
RectF container = new RectF();
container.set(mViewCentreX - mThermostatRadius, mViewCentreY - mThermostatRadius,
mViewCentreX + mThermostatRadius, mViewCentreY + mThermostatRadius);
arcPath.addArc(container, 120, 300);
canvas.drawPath(arcPath, mPaint);
int dummyCurTemp = 200;
if (mPaintCurTemp == null){
mPaintCurTemp = new Paint(Paint.ANTI_ALIAS_FLAG);
}
mPaintCurTemp.setTextAlign(Align.CENTER);
mPaintCurTemp.setTextSize(100);
canvas.drawText(String.valueOf(dummyCurTemp), mViewCentreX, mViewCentreY, mPaintCurTemp);
if (this.mManualOverride == false){
double angle = (360-120-(300/(mMaxTemp - mMinTemp))*(dummyCurTemp-mMinTemp))*(Math.PI/180);
this.mCurTempCircleX = (float) (mViewCentreX + mThermostatRadius*(Math.cos(angle)));
this.mCurTempCircleY = (float) (mViewCentreY - mThermostatRadius*(Math.sin(angle)));
if (mCurrTempBox == null){
mCurrTempBox = new RectF();
}
if (mPaintCurTempIndicator == null){
mPaintCurTempIndicator = new Paint(Paint.ANTI_ALIAS_FLAG);
}
mPaintCurTempIndicator.setStyle(Paint.Style.STROKE);
mPaintCurTempIndicator.setStrokeWidth(thermostatThickness/2);
mPaintCurTempIndicator.setColor(Color.GREEN);
mCurrTempBox.set(mCurTempCircleX-50, mCurTempCircleY-50, mCurTempCircleX+50, mCurTempCircleY+50);
smallCirle.addCircle(mCurTempCircleX, mCurTempCircleY, 50, Direction.CW);
canvas.drawPath(smallCirle, mPaintCurTempIndicator);
}else{
if (mCurrTempBox == null){
mCurrTempBox = new RectF();
}
if (mPaintCurTempIndicator == null){
mPaintCurTempIndicator = new Paint(Paint.ANTI_ALIAS_FLAG);
}
if (mMatrix == null){
mMatrix = new Matrix();
}
//mMatrix.reset();
mMatrix.postRotate((float) (mManualOverrideAngle), mViewCentreX,mViewCentreY);
//mMatrix.postTranslate(mViewCentreX, mViewCentreY);
mPaintCurTempIndicator.setStyle(Paint.Style.STROKE);
mPaintCurTempIndicator.setStrokeWidth(thermostatThickness/2);
mPaintCurTempIndicator.setColor(Color.GREEN);
canvas.concat(mMatrix);
smallCirle.addCircle(mCurTempCircleX, mCurTempCircleY, 50, Direction.CW);
canvas.drawPath(smallCirle, mPaintCurTempIndicator);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialX = event.getX();
mInitialY = event.getY();
RectF touchedAt = new RectF(mInitialX-10, mInitialY-10, mInitialX+10, mInitialY+10);
RectF indicatorAt = mThermoStatView.getCurrTempBox();
if (RectF.intersects(indicatorAt, touchedAt)){
this.isIndicatorSelected = true;
mThermoStatView.setManualOverride(true);
}
break;
case MotionEvent.ACTION_MOVE:
if (this.isIndicatorSelected == true){
float angle = (float) (180*Math.atan2(event.getY() - mThermostatHeight/2, event.getX() - mThermostatWidth/2) / Math.PI);
mThermoStatView.setManualOverrideAngle(angle);
mThermoStatView.invalidate();
//mThermoStatView.requestLayout();
}
break;
case MotionEvent.ACTION_UP:
if (this.isIndicatorSelected == true){
this.isIndicatorSelected = false;
}
break;
}
return true;
}
}
答案 0 :(得分:5)
试试这个(这是我已发布的MyView的一个小修改版本,作为您上一个问题的答案):
public class MyView extends View {
private final static String TAG = "Main.MyView";
private static final float CX = 0;
private static final float CY = 0;
private static final float RADIUS = 20;
private static final float BIGRADIUS = 50;
private static final int NORMAL_COLOR = 0xffffffff;
private static final int PRESSED_COLOR = 0xffff0000;
private Paint mPaint;
private Path mSmallCircle;
private Path mCircle;
private Matrix mMatrix;
private float mAngle;
private int mSmallCircleColor;
public MyView(Context context) {
super(context);
mPaint = new Paint();
mSmallCircle = new Path();
mSmallCircle.addCircle(BIGRADIUS + RADIUS + CX, CY, RADIUS, Direction.CW);
mSmallCircleColor = NORMAL_COLOR;
mCircle = new Path();
mCircle.addCircle(0, 0, BIGRADIUS, Direction.CW);
mMatrix = new Matrix();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
mSmallCircleColor = NORMAL_COLOR;
invalidate();
return false;
}
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
float r = 0;
if (action == MotionEvent.ACTION_DOWN) {
float[] pts = {
BIGRADIUS + RADIUS + CX, CY
};
mMatrix.mapPoints(pts);
r = (float) Math.hypot(event.getX() - pts[0], event.getY() - pts[1]);
}
if (r < RADIUS) {
mSmallCircleColor = PRESSED_COLOR;
mAngle = (float) (180 * Math.atan2(event.getY() - h2, event.getX() - w2) / Math.PI);
invalidate();
return true;
}
return false;
}
@Override
protected void onDraw(Canvas canvas) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mMatrix.reset();
mMatrix.postRotate(mAngle);
mMatrix.postTranslate(w2, h2);
canvas.concat(mMatrix);
mPaint.setColor(0x88ffffff);
canvas.drawPath(mCircle, mPaint);
mPaint.setColor(mSmallCircleColor);
canvas.drawPath(mSmallCircle, mPaint);
}
}
答案 1 :(得分:0)
您可以获取触摸点的矩形和内圈的矩形(位置),并检查它们是否与Intersects方法交叉。
http://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html#intersects(java.awt.Rectangle)
如果接触点与您的圆相交,您的画布onTouchListener可以执行任何操作。
e.g:
// Create a rectangle from the point of touch
Rect touchpoint = new Rect(x,y,10,10);
// Create a rectangle from the postion of the circle.
Rect myCircle=new Rect(10,10,20,20);
if (Rect.intersects(myCircle,touchpoint)){
Log.d("The circle was touched");
}