5

在我的 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.我怎样才能在这三个不规则形状上放置三个按钮,或者有什么解决方案吗?以便可以在活动中处理每个按钮的不同事件?

我不知道如何完成这项任务。请指导我。

有什么意见或建议吗?

任何帮助将不胜感激。

4

4 回答 4

1

我没有对此进行测试,但我认为它会起作用。我敢肯定,您将不得不对其进行调整并进行更正。

创建背景图像的副本,其中三个按钮是三种不同的颜色,没有锯齿,所有其他像素都是纯黑色。它必须是 PNG,因此它不会有 JPG 压缩伪影。这将是你的面具。您可以只使用纯红色、绿色和蓝色,因为您只有三个按钮。只要纵横比相同,它的分辨率可能低于原始图像。

子类 ImageView 并使用您的子类来绘制背景。将您的 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;
}

这有点粗略,因为您需要图像的四个不同副本来表示四种可能的状态。如果您想花时间节省一些内存并使其运行得更快,您可以尝试设置布局,为覆盖在正确位置的三个按钮设置单独的图像视图,并将这些按钮定位为图像更改。但这将是非常具有挑战性的,考虑到你必须让它完美地适应任何屏幕尺寸。

于 2013-08-28T14:30:33.503 回答
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
};
于 2013-08-25T21:49:09.803 回答
0

在 Photoshop 中切片图像,然后将该图像放入 webview 有帮助吗?

于 2013-09-03T18:23:22.977 回答
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();

你现在准备好了。

于 2013-09-04T11:39:27.477 回答