2013-06-23 14 views
10

के ड्रॉ पथ पर उपयोगकर्ता स्पर्श का पता लगाएं मैं एक कस्टम व्यू बना रहा हूं जो कि एक प्रकार का आर्क स्लाइडर प्रगति दृश्य है। मैं उपयोगकर्ता को स्पर्श करने के आधार पर चाप के अधिक या कम खींच सकता हूं (x पर धुरी) स्वीप की गणना करके, मैं पहली बार उस परिक्रमा की गणना करके ऐसा करता हूं जहां उपयोगकर्ता एक्स अक्ष के साथ छूता है .0% बायीं ओर सभी तरह से होगा और 100% दाहिने ओर सभी तरह से होगा।कस्टम व्यू drawArc, आर्क

मैं इसे एक कदम आगे ले जाना चाहता हूं, बजाय उपयोगकर्ता द्वारा दबाए गए एक्स समन्वय के आधार पर चाप को खींचने के बजाय, मैं इसे केवल तब स्थानांतरित करना चाहता हूं जब उपयोगकर्ता वास्तविक आर्क ड्रा पथ पर छूता है, इसलिए यह और यथार्थवादी है । मैं अभी भी कस्टम दृश्य और मेरे गणित के लिए नए सीमित है हूँ, लेकिन मैं आभारी धन्यवाद

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; 
    } 
} 

उत्तर

9

हो सकता है अगर मैं कुछ सुझाव प्राप्त करता है आप के लिए यह काम करता है? आपको बहुत सारे गणित की आवश्यकता नहीं है। आप अपने चाप के केंद्र से टच पॉइंट की दूरी की गणना कर सकते हैं (यह एक सर्कल है इसलिए यह आसान है) और उस त्रिज्या के साथ तुलना करें जिसका आप उपयोग कर रहे हैं। यह आपको बताएगा कि बिंदु चाप पर है (लगभग, पूर्ण मामले के लिए नीचे देखें)।

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

मेरी इच्छा है कि मैं 2 शीर्ष उत्तरों का चयन करूंगा, मैं आपको क्लिक करूँगा धन्यवाद लाखों – brux

+0

कोई चिंता नहीं, मदद करने में प्रसन्नता :) – Plato

+0

मैंने अपना दिमाग बदल दिया और यह सही बना दिया क्योंकि मुझे अभी भी पूरी तरह से मेरे सिर को नहीं मिला है लेकिन आपका कोड काम करता है, क्या आप किसी भी मौके से आईआरसी पर हैं? – brux

11

मैं इसे ले जाने के केवल जब उपयोगकर्ता वास्तविक चाप ड्रा पथ

पर छू लेती है onTouchEvent() की शुरुआत आप की जाँच करने के लिए कि क्या xPosition और yPosition कुछ शर्त को पूरा कर रहे जरूरत पर बनाना चाहते । यदि हां, तो आप सामान करते हैं, जो आप अभी कर रहे हैं। यदि नहीं, return true

शर्त:

हम चाहे एक्स जाँच करना चाहते हैं, वाई कि ग्रे चाप पृष्ठभूमि में कर रहे हैं:

enter image description here

की है कि बात करने के लिए (एक्स, वाई) से एक दूरी की गणना करते हैं (ए, बी) के केंद्र में:

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

distance() एक सरल इयूक्लिडियन dista है अंक (एक्स, वाई) और (ए, बी) के बीच nce:

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

एक्स, वाई यदि y > Y && dist >= r && dist <= R, कि ग्रे चाप पृष्ठभूमि में हैं।

+3

+1 :) – Plato

संबंधित मुद्दे