草庐IT

android - (Android 布局)将按钮放在不规则形状图像顶部或获取图像特定区域的触摸检测(可触摸区域)的解决方案?

coder 2023-12-17 原文

在我的 Android 应用程序中,我在地球上有三个不规则形状,如下所示:

所以我将整个图像放在布局中。地球仪只是一个图像。这里没有地球仪的作用。现在我想在每个不规则形状图像的顶部放置一个按钮,这些图像是在全局范围内。

按钮始终是矩形的,但我想获取不规则形状的触摸事件,而不是矩形区域。 那么如何在这三个不规则形状上放置三个按钮,或者有什么解决方案吗?以便可以在 Activity 中处理每个按钮的不同事件?

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

有什么意见或建议吗?

我们将不胜感激。

最佳答案

我还没有测试过这个,但我认为它会起作用。我相信您必须对其进行调整并进行更正。

创建背景图像的副本,其中三个按钮是三种不同的颜色,没有锯齿,所有其他像素都是纯黑色。它必须是 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 来处理类似于按钮的触摸逻辑。它将需要跟踪状态。这是一个示例,但我不确定在多点触控时是否会中断。您可能还需要为第一根手指设置 Action 掩码并使用 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;
}

这有点粗糙,因为您需要图像的四个不同副本来表示四种可能的状态。如果您想花时间节省一些内存并使其运行得更快,您可以尝试使用单独的 ImageView 设置您的布局,以便在正确的位置覆盖三个按钮,并针对这些按钮进行图像更改。但这将非常具有挑战性,因为您必须使其与任何屏幕尺寸完美对齐。

关于android - (Android 布局)将按钮放在不规则形状图像顶部或获取图像特定区域的触摸检测(可触摸区域)的解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18433097/

有关android - (Android 布局)将按钮放在不规则形状图像顶部或获取图像特定区域的触摸检测(可触摸区域)的解决方案?的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  4. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  5. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  6. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  7. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  8. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  9. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  10. ruby-on-rails - 缺失区域;使用 :region option or export region name to ENV ['AWS_REGION' ] - 2

    我知道还有其他相同的问题,但他们没有解决我的问题。我不断收到错误:Aws::Errors::MissingRegionErrorinBooksController#create,缺少区域;使用:region选项或将区域名称导出到ENV['AWS_REGION']。但是,这是我的配置开发.rb:config.paperclip_defaults={storage::s3,s3_host_name:"s3-us-west-2.amazonaws.com",s3_credentials:{bucket:ENV['AWS_BUCKET'],access_key_id:ENV['AWS_ACCE

随机推荐