2011-02-15 108 views
2

我需要一個建議如何實現Android的下的下列功能的Android圖片:與可點擊區域

  • 我需要一個代表像圖(從離散數學)的圖像,與頂點和邊,在那裏我可以點擊每個頂點或邊緣並觸發不同的動作。

請告訴我如何做到這一點(也許用imagebuttons)或其他方法來表示此功能。

+0

我沒有實際使用過你的建議,但看看[JFreeChart](http://www.jfree.org/jfreechart/)是否能滿足你的需求。 – jacknad 2011-02-15 20:19:49

+0

我的意思是「圖形」就像我說的離散數學一樣。我需要一個線條和節點的圖像,它們都可以點擊。 – o15a3d4l11s2 2011-02-15 20:24:38

回答

9

我很無聊,所以我編碼了這個粗糙的例子... 它假設點之間的直邊。

public class App extends Activity 
{ 
    PlotView plot; 
    @Override 
    public void onCreate(Bundle sis) 
    { 
     super.onCreate(sis); 
     plot = new PlotView(this); 
     setContentView(plot); 
    } 

    public class PlotView extends View 
    { 
     Paint paint1 = new Paint(); 
     Paint paint2 = new Paint(); 
     Point[] points = new Point[10]; 

     public PlotView(Context context) 
     { 
      super(context); 
      paint1.setColor(Color.RED); 
      paint2.setColor(Color.BLUE); 
      for (int i = 0; i < points.length; i++) 
      { 
       points[i] = new Point(); 
       points[i].x = (float) (Math.random() * 320); 
       points[i].y = (float) (Math.random() * 480); 
      } 
      Arrays.sort(points); 
     } 

     @Override 
     protected void onDraw(Canvas canvas) 
     { 
      canvas.drawColor(Color.WHITE); 
      for (int i = 0; i < points.length; i++) 
      { 
       if (i < points.length - 1) 
       { 
        canvas.drawLine(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y, paint2); 
       } 
       canvas.drawCircle(points[i].x, points[i].y, 5, paint1);    
      } 
      super.onDraw(canvas); 
     } 

     @Override 
     public boolean onTouchEvent(MotionEvent event) 
     { 
      switch(event.getAction()) 
      { 
       case MotionEvent.ACTION_DOWN: 
       { 
        float x = event.getX(); 
        float y = event.getY(); 

        int hitPoint = -1; 
        int closestLeft = -1; 
        int closestRight = -1; 

        for (int i = 0; i < points.length; i++) 
        { 
         float dx = x - points[i].x; 
         float dy = y - points[i].y; 

         if(i < points.length - 1) 
         { 
          if(points[i].x < x && x < points[i + 1].x) 
          { 
           closestLeft = i; 
           closestRight = i + 1; 
          } 
         } 

         if (Math.abs(dx) <= 16.0f && Math.abs(dy) <= 16.0f) 
         { 
          hitPoint = i; 
          break; 
         } 
        } 
        if (hitPoint != -1) 
        { 
         Toast.makeText(getContext(), "Hit Point: " + hitPoint, Toast.LENGTH_SHORT).show();      
        } 
        else       
        if(closestLeft != -1 && closestRight != -1) 
        { 
         float dx = points[closestLeft].x - points[closestRight].x; 
         float dy = points[closestLeft].y - points[closestRight].y; 

         final float u = ((x - points[closestLeft].x) * dx + (y - points[closestLeft].y) * dy)/(dx * dx + dy * dy); 

         float px = points[closestLeft].x + u * dx; 
         float py = points[closestLeft].y + u * dy; 

         if (Math.abs(x - px) <= 16.0f && Math.abs(y - py) <= 16.0f) 
         { 
          Toast.makeText(getContext(), "Hit Line Between: " + closestLeft + " & " + closestRight, Toast.LENGTH_SHORT).show(); 
         } 
        }     
       } 
      } 
      return super.onTouchEvent(event); 
     } 

     public class Point implements Comparable<Point> 
     { 
      float x; 
      float y; 
      @Override 
      public int compareTo(Point other) 
      { 
       if (x < other.x) return -1; 
       if (x > other.x) return 1; 
       return 0; 
      } 
     }  
    } 
} 
2

我能想象如何與SurfaceView做到這一點:

  • 創建Vertex類,除其他事項外,有一個X,Y座標代表在哪裏畫的頂點。如果您的頂點是一個圓形的png圖像,則圖像的左上角x,y座標將存儲在Vertex類中。
  • 讓您的所有頂點在List中,並遍歷並繪製每個頂點。
  • 邊緣比較複雜,因爲它們可能是交叉的或是曲折的。
    • 假設它們是直線,那麼您可以有一個Edge類,它包含起始x,y和結束x,y座標。
    • 可以通過EdgeList A S迭代,並繪製線條相應

爲了檢測當它們在用戶點擊,則應該重寫onTouch方法和檢查event.rawX()event.rawY()值以查看它們是否匹配Vertex或Edge類。

  • Vertex類,您可以檢查是否x <= event.rawX <= x + image_widthy <= event.rawY <= y + image_height

  • Edge,您可以檢查是否event.rawX, event.rawY座標由兩個座標的你存儲在形成的線發現類Edge

我已經使用類似的方法繪製遊戲中的一組節點。我不太確定如何去做邊緣 - 我所概述的方法只有在直線時不會交叉。

我相信有更好的方法來使用openGL來做到這一點,但我之前沒有使用過openGL。

希望你能從中得到一些想法。

2

我想你可能是最好關閉用SurfaceView:

http://developer.android.com/reference/android/view/SurfaceView.html

和處理的onTouchEvent()作爲一個整體的表面,鍵盤映射到圖像中潛在的實體。如果您正在計算繪圖,那麼您應該很容易創建一個可觸摸區域的地圖,並抓取觸摸事件的X和Y,以確定它是否與圖像中的元素相對應。

如果你真的有一個圖像,例如已處理的PNG,你需要一些方法來攜帶觸摸事件區域。取決於圖像的來源。

1

根據機器人的幫助下,「引到View,是您最佳的選擇,當你想繪製簡單的圖形不需要動態改變,不是性能密集型遊戲的一部分。」例如,這是製作蛇或國際象棋遊戲時的正確方法。所以我沒有看到建議使用SurfaceView來實現這一點,它只會使事情過度複雜化。

對於可覆蓋的可點擊區域public boolean onTouchEvent(MotionEvent event)其中管理點擊的x和y座標以標識點擊區域。