java 如何判断 X 和 Y 坐标是否在我的按钮内?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17931816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to tell if an X and Y coordinate are inside my button?
提问by Liam W
I have managed, with great difficulty, to make a bitmap overlay the screen. I can also get touch input, however it gets touch input for EVERYWHERE on the screen.
我已经很困难地设法使位图覆盖在屏幕上。我也可以获得触摸输入,但是它可以在屏幕上的任何地方获得触摸输入。
I want to know how I would be able to check if the touch was on my bitmap, which is visible on the screen.
我想知道如何检查触摸是否在位图上,位图在屏幕上可见。
The service and view class is below. I have thought and thought, but I couldn't think of a way to do it :(
服务和视图类如下。我想了又想,但我想不出办法来做到这一点:(
package <package>;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;
public class MyService extends Service {
ButtonView mView;
Bitmap bit;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
bit = BitmapFactory.decodeResource(getResources(), R.drawable.button);
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this);
builder.setContentTitle("Ingress Tools Running");
builder.setContentText("Click to stop Ingress Tools");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(
this, StopActivity.class), 0));
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, builder.build());
mView = new ButtonView(this, bit);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getBaseContext(), "onDestroy", Toast.LENGTH_LONG).show();
if (mView != null) {
((WindowManager) getSystemService(WINDOW_SERVICE))
.removeView(mView);
mView = null;
}
}
}
class ButtonView extends ViewGroup {
private Paint mLoadPaint;
private Rect r;
private Bitmap bit;
public ButtonView(Context context, Bitmap bit) {
super(context);
Toast.makeText(context, "HUDView", Toast.LENGTH_LONG).show();
mLoadPaint = new Paint();
mLoadPaint.setAntiAlias(true);
mLoadPaint.setTextSize(10);
mLoadPaint.setARGB(255, 255, 0, 0);
r = new Rect();
r.set(380, 134, 468, 213);
this.bit = bit;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.drawColor(Color.BLACK);
canvas.drawBitmap(bit, 100, 100, null);
}
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int area = bit.getWidth() * bit.getHeight();
//if (event.getY() <= maxY && event.getX() <= maxX) {
Toast.makeText(getContext(), "Open tools: ", Toast.LENGTH_LONG)
.show();
//}
return true;
}
}
回答by AMD
this works for any view
这适用于任何视图
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (inViewInBounds(myButtonView, (int) event.getRawX(), (int) event.getRawY())) {
// User moved outside bounds
Log.e("dispatchTouchEvent", "you touched inside button");
} else {
Log.e("dispatchTouchEvent", "you touched outside button");
}
}
return super.dispatchTouchEvent(event);
}
Rect outRect = new Rect();
int[] location = new int[2];
private boolean inViewInBounds(View view, int x, int y) {
view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains(x, y);
}
回答by Dmitry Zaytsev
Consider using FrameLayout
(or any other subclass of ViewGroup
) instead of ViewGroup
directly. Because your current implementation of onLayout
method is not correct, which will lead you to problems with displaying of child views.
考虑使用FrameLayout
(或 的任何其他子类ViewGroup
)而不是ViewGroup
直接使用。因为您当前的onLayout
方法实现不正确,这将导致您在显示子视图时出现问题。
Now, closer to your question. You should ininitialize Rect
and just store left, top, right and bottom position of your Bitmap
. As I can see, currently you're initialized r
variable, but not using it anywhere.
现在,更接近你的问题。您应该初始化Rect
并只存储您的Bitmap
. 正如我所看到的,目前您已初始化r
变量,但未在任何地方使用它。
So, you can initialize it like this:
所以,你可以像这样初始化它:
r = new Rect(100, 100, 100 + bit.getWidth(), 100 + bit.getHeight());
Now in onTouchEvent
you can just check:
现在onTouchEvent
你可以检查:
r.contains((int) event.getX(), (int) event.getY());
回答by Blackbelt
回答by MGorgon
Use if statement with method if(r.contains(x, y))
on that button which you want to check. This method will return true, when x and y point is inside rectangle r. You can also make public method within that class, so you can access it outside ButtonView class with button object reference.
if(r.contains(x, y))
在要检查的按钮上使用 if 语句和方法。当 x 和 y 点在矩形 r 内时,此方法将返回 true。您还可以在该类中创建公共方法,以便您可以使用按钮对象引用在 ButtonView 类之外访问它。
回答by Sergey Brazhnik
When the "touch event" happens, it's going through all view's tree. F.e. if you have Linear layout and ImageView on it and user touchs the screen on ImageView, then touch event intercepts and firstly it'll be handled at LinearLayour and then at the ImageView.
当“触摸事件”发生时,它会遍历所有视图的树。Fe 如果你有线性布局和 ImageView 并且用户在 ImageView 上触摸屏幕,然后触摸事件拦截,首先它会在 LinearLayour 处理,然后在 ImageView。
If you want to block event f.e. on the bitmap, then you should override onTouchEvent for Bitmap and return true value. This will mean that you handled this event and it won't be available for LinearLayout.
如果要阻止位图上的事件 fe,则应覆盖位图的 onTouchEvent 并返回 true 值。这意味着您处理了此事件,并且它不适用于 LinearLayout。
image.setOnTouchListener( new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true; // attentively read documentation for onTouc interface
}
});