我需要实现SeekBar之类的东西。我从View创建了班级继承人。我在画布上画了一个椭圆形。触摸时,此椭圆形会上下移动。我无法正确计算该点(拇指)的位置。
这是我的代码,但是已经重做了很多次并停止工作:
public class BalanceView extends View {
private Paint ovalPaint;
private Paint thumbPaint;
private float ovalBottom = 0f;
private Bitmap thumb;
private RectF oval1;
//params
private int maxValue = 18;
private float ovalPaintWidth = 2.0f;
private float ovalHeight = 60f;
//end params
private float touchX = 0f;
private float touchY = 0f;
private float mUnreachedRadius;
public BalanceView(Context context) {
super(context);
init(context, null);
}
public BalanceView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public BalanceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context ctx, @Nullable AttributeSet attrs){
if (attrs != null){
}
if (ovalPaint == null){
ovalPaint = new Paint();
ovalPaint.setAntiAlias(true);
ovalPaint.setStrokeWidth(ovalPaintWidth);
ovalPaint.setStyle(Paint.Style.STROKE);
Shader shader = new SweepGradient(10, 10, new int[]{R.color.white, R.color.black, R.color.white}, null);
ovalPaint.setShader(shader);
}
if (thumbPaint == null){
thumbPaint = new Paint();
}
thumb = BitmapFactory.decodeResource(getResources(), R.drawable.move_point);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//refershPosition();
}
@Override
protected void onDraw(Canvas canvas) {
paintOval(ovalPaint, canvas);
float cos = computeCos(touchX, touchY);
float y = calcYLocationInWheel(cos);
Log.d("balance", "cos: " + cos + " y: " + y + " touchX: " + touchX + " touchY: " + touchY + "mUnreachedRadius: " + mUnreachedRadius) ;
canvas.drawBitmap(thumb, touchX, y, thumbPaint);
super.onDraw(canvas);
}
private void paintOval(Paint paint, @NonNull Canvas canvas){
if (paint != null) {
int right = getWidth() - 30;
int left = (getWidth() - right) / 2;
float top = ovalBottom - ovalHeight;
oval1 = new RectF(left, top, right + left, ovalBottom);
canvas.drawOval(oval1, paint);
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getY() >= getTop() && event.getY() <= getBottom()) {
touchY = event.getY();
}
if (event.getX() <= oval1.right - thumb.getWidth() && event.getX() >= oval1.left) {
touchX = event.getX();
}
ovalBottom = touchY;
invalidate();
return super.dispatchTouchEvent(event);
}
private float computeCos(float x, float y) {
float width = x - oval1.width() / 2;
float height = y - oval1.height() / 2;
float slope = (float) Math.sqrt(width * width + height * height);
return height / slope;
}
private float calcYLocationInWheel(double cos) {
return oval1.bottom * (float) cos;
}
}
我这样做:
private float getY(float a, float b, float x){
// return (float) (Math.pow(b, 2d) * ((Math.pow(a, 2d) - Math.pow(x, 2d)) / Math.pow(a, 2d)));
return (float)
((Math.pow(b, 2d) / Math.pow(a, 2d)) * (Math.sqrt(b * b * (a * a - x * x))));
}
但是数据有误。