如何在android中为画布中心的项目放置一个onclick事件?

Posted

技术标签:

【中文标题】如何在android中为画布中心的项目放置一个onclick事件?【英文标题】:How to put an onclick event for the item coming at the center of the canvas in android? 【发布时间】:2013-09-20 06:36:19 【问题描述】:

我已经实现了下面的代码来获取循环滚动中的项目,其中我使用 Canvas 放置了项目。我得到这样的布局。 我需要在画布中心的项目上有一个 onclick 侦听器,并显示一条包含图像详细信息的 toast 消息。我如何确定出现在中心的图像并在其上设置点击监听器???? onclick 应该只在中心项目上,而不是其余项目上。

谁能帮我解决这个问题???

提前致谢!!

public class CircleScrollListView extends SurfaceView implements
    SurfaceHolder.Callback, OnGestureListener 
private GestureDetector mGestureDetector;
private Thread mThread;
private ArrayList<CircleDrawItem> datas = new ArrayList<CircleDrawItem>();
int[] playerDrawableResourceIds = new int[]  R.drawable.ronaldo,
        R.drawable.zindance, R.drawable.congvinh, R.drawable.huynhduc,
        R.drawable.gerrard, R.drawable.nagatomo, R.drawable.messi,
        R.drawable.minhphuong, R.drawable.neymar, R.drawable.ronaldo_beo,
        R.drawable.ronaldinho, R.drawable.xavi ;
public int mCenterX;
public int mCenterY;
public int mRadius;
public double mStartAngleInRadian = Math.PI / 4;
private boolean isStop = false;

public CircleScrollListView(Context context, AttributeSet attrs) 
    super(context, attrs);
    mGestureDetector = new GestureDetector(context, this);
    getHolder().addCallback(this);
    this.setFocusable(true);


@Override
public boolean onTouchEvent(MotionEvent event) 
    mGestureDetector.onTouchEvent(event);
    return true;


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) 


public static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) 
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) 

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    

    return inSampleSize;


public static Bitmap decodeSampledBitmapFromResource(Resources res,
        int resId, int reqWidth, int reqHeight) 

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);


private double calculateScrollAngle(float px1, float py1, float px2,
        float py2) 
    double radian1 = Math.atan2(py1, px1);
    double radian2 = Math.atan2(py2, px2);
    double diff = radian2 - radian1;
    return diff;


@Override
public void surfaceCreated(SurfaceHolder holder) 

    setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.MATCH_PARENT));

    Global.density = getResources().getDisplayMetrics().density;
    Global.dw = getResources().getDisplayMetrics().widthPixels;
    Global.dh = getResources().getDisplayMetrics().heightPixels;
    Global.dp = Global.density / 1.5f;

    // For circle data
    mCenterX = (int) (Global.dw / 2.0f);
    mCenterY = (int) (Global.dh);
//      mCenterX = (int) (Global.dp * 200);
//      mCenterY = (int) (Global.dh / 2.0f);
    mRadius = (int) (300 * Global.dp);
    mStartAngleInRadian = Math.PI / 4;

    for (int i = 0; i < playerDrawableResourceIds.length; i++) 
        CircleDrawItem circleDrawItem = new CircleDrawItem();
        circleDrawItem.mIconBitmap = decodeSampledBitmapFromResource(
                getResources(), playerDrawableResourceIds[i], 50, 50);
        circleDrawItem.mAngle = mStartAngleInRadian +i * Math.PI / 10;
        datas.add(circleDrawItem);
    

    mThread = new Thread(new Runnable() 
        @Override
        public void run() 
            while (!isStop) 
                draw();
            
        
    );

    mThread.start();


protected void draw() 
    Canvas canvas = getHolder().lockCanvas();
    if (canvas == null) 
        return;
    
    canvas.save();
    canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setFilterBitmap(true);
    paint.setAntiAlias(true);

    for (int i = 0; i < datas.size(); i++) 
        canvas.save();
        CircleDrawItem item = datas.get(i);
        double x = mCenterX + Math.cos(item.mAngle) * mRadius;
        double y = mCenterY - Math.sin(item.mAngle) * mRadius;
        canvas.drawBitmap(item.mIconBitmap,
                (int) x - item.mIconBitmap.getWidth() / 2, (int) y
                        - item.mIconBitmap.getHeight() / 2, paint);
        canvas.restore();
    
    canvas.restore();
    getHolder().unlockCanvasAndPost(canvas);


@Override
public void surfaceDestroyed(SurfaceHolder holder) 
    isStop = true;


@Override
public boolean onDown(MotionEvent e) 
    return false;


@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) 
    return false;


@Override
public void onLongPress(MotionEvent e) 



@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) 
    float tpx = e1.getY();
    float tpy = e2.getX();
    float disx = (int) distanceY;
    float disy = (int) distanceX;
    double scrollAngle = calculateScrollAngle(tpx, tpy, tpx + disx, tpy
            + disy);
    for (int i = 0; i < datas.size(); i++) 
        datas.get(i).mAngle += scrollAngle;
    
    return true;


@Override
public void onShowPress(MotionEvent e) 


@Override
public boolean onSingleTapUp(MotionEvent e) 
    return false;


【问题讨论】:

【参考方案1】:

我们开始;我在 Java 方面没有太多经验,但我应该能够帮助您了解如何操作。

在您的代码中创建一个带有 posX、posY、宽度和高度的小方块。尝试获取您的图像坐标。现在比较它们。图片和你的小方块在同一位置吗?

你明白这背后的原因吗?

【讨论】:

以上是关于如何在android中为画布中心的项目放置一个onclick事件?的主要内容,如果未能解决你的问题,请参考以下文章

Android camera2.params.face 矩形放置在画布上

QGraphicsScene,如何根据中心点放置项目

如何在 JavaFX 中使用 HBox 将某些元素放置在画布上的特定位置? [关闭]

如何在特定的 LinearLayout 中添加 Canvas?

如何在 JavaScript 中为画布指定颜色空间?

如何控制画布在文档中的放置位置?