在我的Android应用程序中,我在全球范围内有三个不规则形状,如下所示:
所以我将整个图像放在布局中。Globe is just an image .There is no role of globe here.
现在我想在全球各个不规则形状的图像上放置一个按钮。
按钮总是长方形但I want to get touch event for irregular shape,not for rectangular area.
那么如何在这三个不规则形状上放置三个按钮或者有任何解决方案?以便在活动中处理每个按钮的不同事件?
我不知道如何完成这项任务。请指导我。
有任何建议或意见吗?
任何帮助将不胜感激。
答案 0 :(得分:1)
我没有测试过这个,但我认为它会起作用。我相信你必须调整它并进行更正。
创建背景图像的副本,其中三个按钮是三种不同的颜色,没有锯齿,所有其他像素都是纯黑色。它必须是PNG,因此它不会有JPG压缩工件。这将是你的面具。因为你只有三个按钮,所以你可以使用纯红色,绿色和蓝色。只要纵横比相同,它的分辨率可能低于原始图像。
Subclass ImageView并使用您的子类来绘制背景。将您的掩码图像的子类化版本作为位图传递。
class TouchMaskImageView extends ImageView {
...constructors
public void setTouchMask(Bitmap mask){
this.mMask = mask;
}
public interface OnTouchedListener{
public void onTouched(MotionEvent event, int colorTouched);
public void onTouchCanceled();
}
public void setOnTouchedListener(OnTouchedListener listener){
this.mOnTouchedListener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (mOnTouchedListener != null && mMask != null ) {
if (x >=0 && x < (float)getWidth() &&
y >=0 && y < (float)getHeight()) {
//Next two lines will be more complicated if
// you aren't using scaleType fitXY
int maskX = (int) x * mMask.getWidth() / getWidth();
int maskY = (int) y * mMask.getWidth() / getHeight();
int maskColor = mask.getPixel(maskX, maskY);
mOnTouchedListener.onTouched(event, maskColor);
} else if (event.getAction()==MotionEvent.UP){
//released finger outside image view
mOnTouchedListener.onTouchCanceled();
}
}
}
}
现在您可以创建一个OnTouchedListener来处理类似于按钮的触摸逻辑。它需要跟踪状态。这是一个例子,但我不确定当有多点触摸时这是否会破坏。您可能还需要为第一个手指设置动作蒙版,并使用getActionMasked()而不是getAction()。
public void onTouched(MotionEvent event, int colorTouched){
switch(mState){
case STATE_WAITING:
if (event.getAction()==MotionEvent.ACTION_DOWN){
switch (colorTouched){
case 0xffff0000: //red
mTouchMaskImageView.setImageResource(R.drawable.redButtonDown);
mState = STATE_LATCHED_RED;
break;
case 0xff00ff00: //green
mTouchMaskImageView.setImageResource(R.drawable.greenButtonDown);
mState = STATE_LATCHED_GREEN;
break;
case 0xff0000ff: //blue
mTouchMaskImageView.setImageResource(R.drawable.blueButtonDown);
mState = STATE_LATCHED_BLUE;
break;
}
}
break;
case STATE_LATCHED_RED:
switch (event.getAction()){
case (MotionEvent.ACTION_MOVE):
if (colorTouched = 0xffff0000)
mTouchMaskImageView.setImageResource(R.drawable.redButtonDown);
else
mTouchMaskImageView.setImageResource(R.drawable.defaultImage);
break;
case (MotionEvent.ACTION_UP)
if (colorTouched = 0xffff0000)
performRedButtonAction();
mTouchMaskImageView.setImageResource(R.drawable.defaultImage);
mState = STATE_WAITING;
break;
}
break;
case etc. for other two latched colors...
break;
}
}
public void onTouchCanceled(){
mTouchMaskImageView.setImageResource(R.drawable.defaultImage);
mState = STATE_WAITING;
}
这有些粗糙,因为您需要四个不同的图像副本来表示四种可能的状态。如果您想节省一些内存并使其运行得更快,您可以尝试使用单独的图像视图设置布局,使三个按钮重叠在正确的位置,并针对图像更改进行定位。但这将是非常具有挑战性的,考虑到你必须使它完美地适合任何屏幕尺寸。
答案 1 :(得分:0)
FLAG_WINDOW_IS_OBSCURED
旗帜过去对我来说效果很好,但可能需要一些合作才能做到正确。这可能值得一试,但说实话,我还不确定它究竟是如何确定什么是不被遮挡的,所以它可能不适用于此。
static OnTouchListener listenerMotionEvent = new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if ( (motionEvent.getFlags() | MotionEvent.FLAG_WINDOW_IS_OBSCURED) != MotionEvent.FLAG_WINDOW_IS_OBSCURED ) {
return false;
// View is not obscured so we pass on the event
}
// Process the motion event here and return true if you consume it
};
答案 2 :(得分:0)
在Photoshop中切片图像,然后将该图像放在webview帮助中吗?
答案 3 :(得分:0)
从上面的答案中,我得到了提示,最后我得到了解决方案如下:
我所做的是:
在xml文件中使用RelativeLayout
使用ImageView,如下所示:
<ImageView
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/glob2"
android:layout_marginBottom="24dp"
android:layout_marginLeft="80.5dp"
android:contentDescription="@string/profile_picture_description"
android:src="@drawable/pick_matches_background" />
这里我相应地设置了保证金(左/右/下/上)。
在活动中,
声明
Bitmap btmp; and
ImageView img;
在onCreate方法中,
// initialized image view
img = (ImageView) findViewById(R.id.btn1);
img.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// call your method here
}
});
StateListDrawable sdCreateTrip = (StateListDrawable) img
.getDrawable();
btmp = ((BitmapDrawable) sdCreateTrip.getCurrent())
.getBitmap();
你现在准备好了。