Android image with clickable areas

后端 未结 4 1315
自闭症患者
自闭症患者 2021-01-03 13:52

I need an advice how to achieve the following functionality under Android:

  • I need an image that represents something like a graph (from discrete math), with ve
4条回答
  •  别那么骄傲
    2021-01-03 14:30

    I was bored, so I coded up this crude example... It assumes straight edges between points.

    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
            {
                float x;
                float y;
                @Override
                public int compareTo(Point other)
                {
                    if (x < other.x) return -1;
                    if (x > other.x) return 1;
                    return 0;
                }
            }       
        }
    }
    

提交回复
热议问题