Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何计算Android缩放画布的坐标

如何计算Android缩放画布的坐标
EN

Stack Overflow用户
提问于 2013-07-08 14:56:54
回答 1查看 1.5K关注 0票数 0

我正在与Android项目合作。我在理解如何使用ScaleDetector和Canvas时遇到了麻烦。

我有一个名为printTable的带有矩形的列表。我在onDraw()方法中绘制屏幕上的每个矩形。然后我有第二个列表,叫做listPointer,带有矩形和矩形的id。我正在检查屏幕上绘制矩形的列表onTouchEvent。如果矩形包含X,Y I将打印有关所单击矩形的id的信息。

问题是,当我移动画布或缩放画布时,如何计算X,Y?

代码语言:javascript
运行
AI代码解释
复制
public class Painter extends View {

    //
    private static final int INVALID_POINTER_ID = -1;
    private float mPosX;
    private float mPosY;

    private float mLastTouchX;
    private float mLastTouchY;
    private int mActivePointerId = INVALID_POINTER_ID;

    private ScaleGestureDetector mScaleDetector;
    private float mScaleFactor = 1.f;
    //

    Paint paint = new Paint();

    List<Table> printTable = new ArrayList<Table>(); // lista wyświetlanych stolików

    //
    List<Pointer> listPointer = new ArrayList<Pointer>();
    //

    public Painter(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Painter(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor *= detector.getScaleFactor();

            // Don't let the object get too small or too large.
            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));

            invalidate();
            return true;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Let the ScaleGestureDetector inspect all events.
        mScaleDetector.onTouchEvent(ev);

        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: {
            final float x = ev.getX();
            final float y = ev.getY();

            mLastTouchX = x;
            mLastTouchY = y;
            mActivePointerId = ev.getPointerId(0);
            for(int i = 0; i<listPointer.size(); i++)
            {
                if(listPointer.get(i).getRectangle().contains((int)(Math.round(x)), (int)(Math.round(y))))
                {
                    if(listPointer.get(i).getIsItTable())
                    {
                        Log.e("Exc", "Stolik "+listPointer.get(i).getId());
                    }
                    else
                    {
                        Log.e("Exc", "Button "+listPointer.get(i).getId());
                    }
                }
            }
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float y = ev.getY(pointerIndex);

            // Only move if the ScaleGestureDetector isn't processing a gesture.
            if (!mScaleDetector.isInProgress()) {
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                invalidate();
            }

            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

        case MotionEvent.ACTION_UP: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = ev.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = ev.getX(newPointerIndex);
                mLastTouchY = ev.getY(newPointerIndex);
                mActivePointerId = ev.getPointerId(newPointerIndex);
            }
            break;
        }
        }

        return true;
    }

    //

    public Painter(Context context) {

        this(context, null, 0);

        paint.setColor(Color.BLACK);

        List<Table> printTable = Bridge.getTables(getContext()); 

    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas) {

        super.onDraw(canvas);
            Rect rect = null;
            RectF rectF = null;
            // czyszczenie tablicy
            listPointer.clear();

            for(int j = 0; j<printTable.size(); j++)
            {
                Table item = printTable.get(j);
                // Obsługa rozciągania

                canvas.save();
                Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
                canvas.translate(mPosX, mPosY);
                canvas.scale(mScaleFactor, mScaleFactor);

                // dodaje do tablicy stołów
                paint.setColor(getResources().getColor(R.color.green));
                rect = new Rect(item.getX1(), item.getY1(), item.getX2(), item.getY2());
                rectF = new RectF(rect);
                canvas.drawRoundRect(rectF, 0,0, paint);
                listPointer.add(new Pointer(rect, true, j));

                canvas.restore();
            }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-08 15:01:13

获取视图的矩阵。它应该包含所有的缩放和转换功能。然后将x,y坐标作为向量乘以用于缩放视图的矩阵。这应该会将预缩放/预转换坐标转换为缩放坐标。如果需要较少的乘法,您还可以将缩放后的坐标乘以该矩阵的逆矩阵,以获得缩放前的坐标。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17529827

复制
相关文章
在LaTeX中插入python代码
老师突然要求交上去的论文需要在附录加上代码,奈何我使用的LaTeX模板只能高亮显示Matlab的代码,但是我写论文的时候绝大部分代码都是用Python写的在这里实名吐槽一下Matlab的数据处理功能这么拉跨,不知道为什么还被拿来当数据挖掘课的第一语言,没办法,只能找一个方法让LaTeX里面能高亮显示Python代码。
Hsinyan
2022/06/19
6.9K0
在LaTeX中插入python代码
看ASM在代码中的强势插入
前言 我之前写过一篇AOP的文章 看AspectJ在Android中的强势插入 是通过AspectJ来实现的,本篇是『巴掌』的投稿,他通过使用ASM来讲解了在Java和Android中的AOP方法,非常值得大家学习交流~ demo地址:https://github.com/JeasonWong/CostTime 需求 实际业务开发中有很多需要不改变原业务代码,而需额外增加一些包括各种统计的需求,如APM、无数据埋点等,也就是耳熟能详的AOP,本文以统计方法耗时为例,不使用Aspectj,采
用户1907613
2018/07/20
5.1K0
python在sqlite中插入数据
python通过引入sqlite的包,就能够直接操作sqlite数据库 import sqlite3 import math cx=sqlite3.connect("mydatabase.sqli
py3study
2020/01/06
4.1K0
在文章中插入广告代码投放广告
复制以下代码到functions.php 里使用即可 function themeInit($archive) { // 判断是否是文章,如果是就插入广告 $ad_code = ' <div>这是你的广告</div> '; if ($archive->is('single')) { $archive->content = prefix_insert_after_paragraph( $ad_code, 2, $archive->content );; } } // 插入广告所需的功能代码 function
团团生活志
2022/08/16
2.7K0
python在mysql中插入null空值
python在mysql中插入null空值 sql = “INSERT INTO MROdata (MmeUeS1apId) VALUES (%s)”%‘NULL’ %s没有引号,可以将“null”中null写进数据库,达到NULL值效果。
kirin
2020/12/03
8.5K0
在latex中写python代码
大家都知道,python现在用的是越来越多了,功能强大,易于上手,如果能借助于其强大的绘图功能,latex岂不碉堡了?
py3study
2020/01/07
2K0
在latex中写python代码
看AspectJ在Android中的强势插入
什么是AOP AOP是Aspect Oriented Programming的缩写,即『面向切面编程』。它和我们平时接触到的OOP都是编程的不同思想,OOP,即『面向对象编程』,它提倡的是将功能模块化,对象化,而AOP的思想,则不太一样,它提倡的是针对同一类问题的统一处理,当然,我们在实际编程过程中,不可能单纯的安装AOP或者OOP的思想来编程,很多时候,可能会混合多种编程思想,大家也不必要纠结该使用哪种思想,取百家之长,才是正道。 那么AOP这种编程思想有什么用呢,一般来说,主要用于不想侵
用户1907613
2018/07/20
2.7K0
PPT 中插入域代码公式的方法
注意: 我们希望能够尽快以你的语言为你提供最新的帮助内容。 本页面是自动翻译的,可能包含语法错误或不准确之处。我们的目的是使此内容能对你有所帮助。可以在本页面底部告诉我们此信息是否对你有帮助吗? 请在此处查看本文的 英文版本 以便参考。
全栈程序员站长
2022/09/05
3.9K0
python中时间的加n和减n运算
   好多朋友都遇到过python推算时间的问题,有些把时间转换成整数做推算,这样遇到特殊的时间和日期就会出现错误,在python中时间的推算很简单,主要就是用到datetime.timedelta方法,进行时间的加n减n运算:
py3study
2020/01/08
1.7K0
怎样在Visio中插入大括号?
在标注类形状中就可以找到大括号了。可以看到,系统默认配置了两种大括号类型:双侧大括号和单侧大括号,大家可以根据实际需要自己选择。
狼啸风云
2021/05/17
13.1K0
怎样在Visio中插入大括号?
在 LaTeX 中插入图片「建议收藏」
原  文:Inserting Images 译  者:Xovee 翻译时间:2020年9月18日
全栈程序员站长
2022/09/05
17.6K0
在 LaTeX 中插入图片「建议收藏」
使用insert () 在MongoDB中插入数组
“insert”命令也可以一次将多个文档插入到集合中。下面我们操作如何一次插入多个文档。
MongoDB中文社区
2020/02/19
8K0
使用insert () 在MongoDB中插入数组
Chromedriver 在 Python 中查看源代码的方法
然后进行初始化: chrome = Chrome(service=Service(r"C:\Users\yhu\Downloads\chromedriver-win64\chromedriver-win64\chromedriver.exe"))
HoneyMoose
2023/09/18
2590
Chromedriver 在 Python 中查看源代码的方法
关于Python中No module n
错误信息:ModuleNotFoundError: No module named 'requests'
py3study
2020/01/06
8170
numpy在cs231n中的应用
0.作者的话1.访问数组2.broadcast机制3.np.bincount()4.np.argmax()5.联合求解6.求取精度7.作者的话
公众号guangcity
2019/09/20
2.5K0
numpy在cs231n中的应用
C# 在 webBrowser 光标处插入 html代码 .
private void BtnInsertMedia_Click(object sender, EventArgs e)         {             InWord frm = new InWord("请填入视频地址(后缀必须是.swf):");             frm.ShowDialog();             if (frm.Value != null && frm.Value != "")             {                 IHTMLDocum
跟着阿笨一起玩NET
2018/09/18
1.5K0
Starlight:帮助Python代码在Go中运行的工具
I’d like to announce starlight - https://github.com/starlight-go/starlight.
李海彬
2018/12/26
2.2K0
用 VBA 在 PPT 中批量插入图片
网上用 VBA 操作 EXCEL的 示例很多,但用 VBA 操作 PPT 的示例很少,而且通常有不少错误或者版本老旧的地方。
用户6021899
2023/08/09
1.2K1
用 VBA 在 PPT 中批量插入图片
文本或代码中 \n 和 \r 的区别
在 ASCII 码中,我们会看到有一类不可显示的字符,叫控制字符,其中就包含\r 和 \n 等控制字符。
DeROy
2020/12/02
5K0
在评论输入框中插入表情
最近在做一个后台管理系统,要求可以对前台用户的作品进行评论,而评论要可以输入表情,常规的文字输入框都是用的文本域textarea来做的,但这种输入框只能输入文字,没有办法输入表情图标,这个时候可编辑div就能起到作用了,那么如何在可编辑的div中插入表情呢?
越陌度阡
2020/11/26
4.2K0

相似问题

在StackOverflow中插入python代码

12

如何在基因组数据中插入互补碱基?

13

在n个部分后插入广告代码?

33

python中的n元树插入算法

128

在bash脚本中插入python代码

39
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档