- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对编码相当陌生,对图形也是全新的。我将不胜感激,因为我无法找到我需要的答案。
我有一个扩展 View 的类。我在自定义 Canvas 中创建了几个 3 层矩形。我成功地能够触摸和移动每个矩形。我可以平移整个 Canvas 。我可以在平移后移动各个矩形。我可以缩放整个屏幕。我不能做的一件事是在缩放后移动单个矩形。缩放后我无法“找到”矩形。我准备放弃整个自定义 View 并尝试使用 ImageView 或我可以处理的东西来完成此操作,而不是尝试查看坐标所触及的内容。
我的问题是:如何在缩放后找到矩形的坐标?我的猜测是根据 Canvas 的移动或 Canvas 的比例重新计算每个矩形,但显然我'我遗漏了一些东西,因为这看起来过于复杂并且对我不起作用。
这是一些代码 - 请原谅乱七八糟的代码,我只是想把这个想法记下来。我试过在计算中使用矩阵和比例因子,但似乎都没有找到正确的位置。 (有些代码没有使用——我使用了它,但无法计算出矩形的正确位置……这是否是正确的方法?)
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(xOffset, yOffset);
canvas.scale(scaleFactor, scaleFactor);
for (RectF r: RectFs){
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
canvas.drawRoundRect(r, 20, 20,paint); //Set a border
paintShader.setStyle(Style.FILL);
paintShader.setShader(new LinearGradient(r.left, r.bottom, r.right, r.top, Color.CYAN, Color.YELLOW, Shader.TileMode.REPEAT));
canvas.drawRoundRect(r, 20, 20, paintShader);
paint.setColor(Color.BLACK);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
paint.setLinearText(true);
canvas.drawText(text, r.left+px, r.top+py, paint);
}
}
public boolean onTouchEvent(MotionEvent event) {
scaleGestureDetector.onTouchEvent(event);
touched = true;
if (!panned){
left = event.getX() - rectHeight / 2;
top = event.getY() - rectWidth / 2;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startPos.set(event.getX(), event.getY());
findWhatWasTouched();
invalidate();
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_MOVE:
if (freezeAction)
break;
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!scaleGestureDetector.isInProgress() && panned) {
xOffset += event.getX() - startPos.x;
yOffset += event.getY() - startPos.y;
} else
resetAllRectsAfterScrollOrZoom();
findWhatWasTouched();
invalidate();
startPos.set(event.getX(), event.getY());
break;
case MotionEvent.ACTION_POINTER_UP:
freezeAction = true;// When two fingers off of zoom, don't let the other finger jump everything around
break;
case MotionEvent.ACTION_UP:
if (!freezeAction){
findWhatWasTouched();
invalidate();
if (panned || zoomed)
resetAllRectsAfterScrollOrZoom();
}
liveRect = null;
panned = false;
freezeAction = false;
xOffset = 0;
yOffset =0;
break;
}
return true;
}
public void resetAllRectsAfterScrollOrZoom(){
float height, width;
for (RectF r: RectFs){
height = r.height();
width = r.width();
if (zoomed){
r.left += (xOffset * scaleFactor);
r.top += (yOffset * scaleFactor);
}else {
r.left += xOffset;
r.top += yOffset ;
}
r.right = r.left + width;
r.bottom = r.top + height;
}
}
public void findWhatWasTouched(){
boolean rectWasTouched = false;
for (RectF r: RectFs){ // Update positions due to a touch event.
if (r.contains(startPos.x, startPos.y)){
if (liveRect == null)
liveRect = r;
rectWasTouched = true;
}
}
if (!rectWasTouched)
panned = true;
if (!zoomed && !panned && liveRect != null){
float height = liveRect.height();
float width = liveRect.width();
liveRect.left = left;
liveRect.top = top;
liveRect.right = liveRect.left + width;
liveRect.bottom = liveRect.top + height; // We have a moving single rect - reset it's position here
}
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
zoomed = true;
// don't let the object get too small or too large.
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f));
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector){
zoomed = false;
}
} // End ScaleListener class
} // End view class
最大的问题是,当我朝那个方向移动时,缩放后触摸矩形会使矩形进一步向下和向右呈指数移动......这让我认为 resetAllRects 的缩放部分的数学是错误的堵塞。但是对于我的一生,我无法弄清楚。仍然不知道每次重置直角坐标是否是执行此操作的正确方法?
最佳答案
这花了我好几天的时间才弄清楚,我认为如果没有 SO,我永远无法弄清楚。特别感谢@Awais Tariq 为我提供了此处所需的线索:Get Canvas coordinates after scaling up/down or dragging in android .基本上,所有内容(移动、平移,最重要的是,检查指针位置)都必须经过可以转换新屏幕密度的计算。这是我更改的内容,以防将来有人遇到这个烂摊子:
liveRect.left = (startPos.x / scaleFactor + clipbounds.left) - width/2;
liveRect.top = (startPos.y / scaleFactor + clipbounds.top )- height/2;
liveRect.right = liveRect.left + width;
liveRect.bottom = liveRect.top + height;
这会在缩放后重新计算矩形的位置。但是,当您远离 0,0 时,指针也会呈指数“关闭”。为了更正,我在 if-check 中使用了以下公式来查看被触摸的内容:
if (r.contains(startPos.x / scaleFactor + clipbounds.left, startPos.y / scaleFactor + clipbounds.top))
使用此解决方案一切正常。我可能会返回并尝试使用布局而不是查看将 View 传递给 if-check 是否更容易。但是,就目前而言,这是可行的。对于我的新手编码员来说太复杂了,我想知道这是否可以在未来内置到 Android 中。
关于Android - 如何在缩放后找到一个 Rect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20449078/
例如,我有一个父类Author: class Author { String name static hasMany = [ fiction: Book,
代码如下: dojo.query(subNav.navClass).forEach(function(node, index, arr){ if(dojo.style(node, 'd
我有一个带有 Id 和姓名的学生表和一个带有 Id 和 friend Id 的 Friends 表。我想加入这两个表并找到学生的 friend 。 例如,Ashley 的 friend 是 Saman
我通过互联网浏览,但仍未找到问题的答案。应该很容易: class Parent { String name Child child } 当我有一个 child 对象时,如何获得它的 paren
我正在尝试创建一个以 Firebase 作为我的后端的社交应用。现在我正面临如何(在哪里?)找到 friend 功能的问题。 我有每个用户的邮件地址。 我可以访问用户的电话也预订。 在传统的后端中,我
我主要想澄清以下几点: 1。有人告诉我,在 iOS 5 及以下版本中,如果您使用 Game Center 设置多人游戏,则“查找 Facebook 好友”(如与好友争夺战)的功能不是内置的,因此您需要
关于redis docker镜像ENTRYPOINT脚本 docker-entrypoint.sh : #!/bin/sh set -e # first arg is `-f` or `--some-
我是一名优秀的程序员,十分优秀!