2013-06-23 35 views
10

Tôi đang tạo chế độ xem tùy chỉnh, đây là một loại chế độ xem thanh trượt arc.I có thể vẽ nhiều hoặc ít vòng cung dựa trên nơi người dùng chạm (trên x trục) bằng cách tính toán quét, tôi làm điều này bằng cách đầu tiên tính toán percetage nơi người dùng chạm dọc theo trục x..0% sẽ là tất cả các cách bên trái và 100% sẽ là tất cả các cách bên phải.Custom View drawArc, phát hiện cảm ứng của người dùng trên đường dẫn vẽ của arc

Tôi muốn tiến thêm một bước nữa, thay vì vẽ vòng cung dựa trên tọa độ x mà người dùng nhấn, tôi muốn làm cho nó di chuyển chỉ khi người dùng chạm vào đường dẫn vẽ vòng cung thực tế. . Tôi vẫn còn mới để xem tùy chỉnh và toán học của tôi còn hạn chế nhưng nếu tôi nhận được một số lời khuyên tôi sẽ nhờ biết ơn

how it looks when user moves there finger on the area of the rectangle as a percentage along the x axis

class ArcProgress extends View { 

    Context cx; 
    float width; 

    float height; 
    float center_x, center_y; 
    final RectF oval = new RectF(); 
    final RectF touchArea = new RectF(); 

    float sweep = 0; 
    float left, right; 
    int percent = 0; 

    public ArcProgress(Context context) { 
     super(context); 
     cx = context; 

    } 

    public int getPercentage() { 
     return percent; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     setBackgroundColor(0xfff0ebde); 

     width = (float) getWidth(); 
     height = (float) getHeight(); 

     float radius; 

     if (width > height) { 
      radius = height/3; 
     } else { 
      radius = width/3; 
     } 

     Paint paint = new Paint(); 
     paint.setAntiAlias(true); 
     paint.setColor(0xffd2c8b6); 
     paint.setStrokeWidth(35); 

     paint.setStyle(Paint.Style.STROKE); 

     center_x = width/2; 
     center_y = height/2; 

     left = center_x - radius; 
     float top = center_y - radius; 
     right = center_x + radius; 
     float bottom = center_y + radius; 

     oval.set(left, top, right, bottom); 

      //this is the background arc, it remains constant 
     canvas.drawArc(oval, 180, 180, false, paint); 

     paint.setStrokeWidth(10); 
     paint.setColor(0xffe0524d); 
      //this is the red arc whichhas its sweep argument manipulated by on touch 
     canvas.drawArc(oval, 180, sweep, false, paint); 

    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     if (event.getAction() == MotionEvent.ACTION_MOVE) { 

      float xPosition = event.getX(); 
      float yPosition = event.getY(); 
      if (oval.contains(xPosition, yPosition)) { 

       float x = xPosition - left; 
       float s = x * 100; 
       float b = s/oval.width(); 
       percent = Math.round(b); 
       sweep = (180/100.0f) * (float) percent; 

       invalidate(); 

      } else { 
       if (xPosition < left) { 
        percent = 0; 

        sweep = (180/100.0f) * (float) percent; 
        invalidate(); 
       } 
       if (xPosition > right) { 
        percent = 100; 

        sweep = (180/100.0f) * (float) percent; 
        invalidate(); 
       } 
      } 
     } 

     return true; 
    } 
} 

Trả lời

9

Điều này làm việc cho bạn? Bạn không cần nhiều Toán. Bạn có thể tính toán khoảng cách của các điểm tiếp xúc từ trung tâm của vòng cung của bạn (đó là một vòng tròn vì vậy nó dễ dàng) và so sánh với bán kính bạn đang sử dụng. Điều đó sẽ cho bạn biết nếu điểm là trên vòng cung (gần như, xem dưới đây cho trường hợp đầy đủ).

Point touchEv = ...; 
Point circleCenter = ...; 

//the radius of the circle you used to draw the arc 
float circleRadius = ...; 
//how far from the arc should a touch point treated as it's on the arc 
float maxDiff = getResources().getDimension(R.dimen.max_diff_dp); 

//calculate the distance of the touch point from the center of your circle 
float dist = Math.pow(touchEv.x-circleCenter.x,2) + Math.pow(touchEv.y- circleCenter.y,2) 
dist = Math.sqrt(dist); 

//We also need the bounding rect of the top half of the circle (the visible arc) 
Rect topBoundingRect = new Rect(circleCenter.x - circleRadius, 
      circleCenter.y - circleRadius, 
      circleCenter.x + circleRadius, 
      circleCenter.y); 


if (Math.abs(dist - circleRadius) <= maxDiff && 
    topBoundingRect.contains(touchEv.x, touchEv.y)) { 
    // the user is touching the arc 

} 
+0

tôi ước gì tôi chọn 2 câu trả lời hàng đầu, tôi sẽ bấm bạn cảm ơn một triệu – brux

+0

đừng lo lắng, vui lòng trợ giúp :) – Plato

+0

tôi thay đổi suy nghĩ của mình và làm chính xác điều này. mã hoạt động, bạn có bị IRC không? – brux

11

tôi muốn làm cho nó di chuyển chỉ khi người dùng chạm vào thực tế arc con đường hòa

Vào đầu onTouchEvent() bạn cần phải kiểm tra xem xPositionyPosition đang thực hiện một số điều kiện . Nếu có, bạn làm những thứ mà bạn đang làm bây giờ. Nếu không, return true.

Tình trạng:

Chúng tôi muốn kiểm tra xem x, y là ở chỗ nền hồ quang màu xám:

enter image description here

Hãy tính toán một cách từ (x, y) đến thời điểm đó (a, b) ở giữa:

final dist = distance(x, y, a, b) 

distance() là đơn giản Euclide dista nce giữa các điểm (x, y) và (a, b):

double distance(int x, int y, int a, int b) 
{ 
    return Math.sqrt((x - a) * (x - a) + (y - b) * (y - b)); 
} 

x, y là ở chỗ nền hồ quang màu xám, nếu y > Y && dist >= r && dist <= R.

+3

+1 cho bản vẽ :) – Plato

Các vấn đề liên quan