如何在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 矩形放置在画布上
如何在 JavaFX 中使用 HBox 将某些元素放置在画布上的特定位置? [关闭]