【问题标题】:Coordinate offset between MainActivity and Custom ViewMainActivity 和自定义视图之间的坐标偏移
【发布时间】:2015-01-12 07:47:25
【问题描述】:

在我的应用程序中,我使用 MainActivity 类中的 Canvas 对象绘制某些图形。之后,当用户在屏幕上滑动时,我使用自定义视图在之前创建的图形上绘制水平线和垂直线。

问题是MainActivity和CustomView之间有轻微的坐标偏移。因此,我的线条与游戏中的其他图形对象不符。为了确认这一点,我从 MainActivity 和我的 CustomView 类中进行了以下调用:

canvas.drawLine(0, 0, 50, 50, 油漆);

结果是两条平行线。 CustomView 的原点位于手机的右上角,MainActivity 类的原点有一定的偏移量。

(截图:http://i.stack.imgur.com/x3BDK.png

如果有人能指出这里可能出现的问题,我将不胜感激。

以下是相关文件:

activity_main.xml

<com.example.offsettest.CustomLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/customLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp">
</com.example.offsettest.CustomLayout>

MainActivity.java

package com.example.offsettest;

import com.rgtech.offsettest.R;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.widget.ImageView;

public class MainActivity extends Activity {
    private Bitmap bitmap;
    private Canvas mCanvas;
    private Paint paint;
    private CustomLayout customLayout; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        draw();
    }

    public void draw(){
        DisplayMetrics metrics = this.getResources().getDisplayMetrics();
        float width = metrics.widthPixels;
        float height = metrics.heightPixels;
        bitmap = Bitmap.createBitmap((int) width, (int) height, Config.RGB_565);
        mCanvas = new Canvas(bitmap);
        mCanvas.drawColor(Color.GREEN);
        paint = new Paint();
        paint.setAntiAlias(true);
        customLayout = (CustomLayout) findViewById(R.id.customLayout);
        ImageView imageView = new ImageView(this);
        imageView.setImageBitmap(bitmap);
        imageView.setPadding(0, 0, 0, 0);
        customLayout.addView(imageView);
        paint.setColor(Color.BLACK);
        mCanvas.drawLine(0, 0, 50, 50, paint);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

CustomLayout.java

package com.example.offsettest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.LinearLayout;

@SuppressLint("NewApi")

    public class CustomLayout extends LinearLayout{
        private Paint paint = new Paint();
        public CustomLayout(Context context) {
            super(context);
        }
        public CustomLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        public CustomLayout(Context context, AttributeSet attrs,int defStyle) {
            super(context, attrs, defStyle);
        }
        @Override
        public void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(canvas);
            paint.setColor(Color.BLACK);
            paint.setAntiAlias(true);
            paint.setDither(true);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeWidth(5);
            paint.setColor(Color.RED);
            canvas.drawLine(0, 0, 50, 50, paint);
        }
    }

除了这些文件,我只在Manifest文件中设置了android:theme="@android:style/Theme.NoTitleBar"。

【问题讨论】:

  • 如果您发布有问题的代码 sn-ps 会更容易可视化,包括 MainActivity 的布局 xml。
  • @JustinPowell 感谢您的意见。我已经添加了相关代码sn-p。我的 mxml 只包含自定义视图。如果您能就可能出现的问题提供一些指示,那就太好了。

标签: java android graphics coordinates


【解决方案1】:

解决此问题的最简单方法是删除图像视图或布局的根视图的填充或边距。 (如果有的话) 另一种可能性是分别使用view.getX()view.getRawX()(以及Y)计算它们左上角位置之间的偏移/距离,然后画线不是(0, 0, 50, 50),而是(offsetX, offsetY, 50 + offsetX, 50 + offsetY)

编辑:我玩弄了这段代码,然后注意到调用imageView.setAdjustViewBounds(true); 解决了这个问题。 您在 MainActivity.java 中的 draw 方法现在应该如下所示:

public void draw() {

    DisplayMetrics metrics = this.getResources().getDisplayMetrics();
    float width = metrics.widthPixels;
    float height = metrics.heightPixels;

    bitmap = Bitmap.createBitmap((int) width, (int) height, Config.RGB_565);
    mCanvas = new Canvas(bitmap);
    mCanvas.drawColor(Color.GREEN);
    paint = new Paint();
    paint.setAntiAlias(true);

    customLayout = (CustomLayout) findViewById(R.id.customLayout);
    ImageView imageView = new ImageView(this);
    imageView.setImageBitmap(bitmap);
    imageView.setPadding(0, 0, 0, 0);
    imageView.setAdjustViewBounds(true); // call this method
    customLayout.addView(imageView);

    paint.setColor(Color.BLACK);
    mCanvas.drawLine(0, 0, 50, 50, paint);
}

【讨论】:

  • 设置内边距和边距没有帮助。在我的 MainActivity 文件中,在 onTouchEvent 中,我比较了 event.getX()、event.getRawX()(和 Y)并且值相同。我创建了一个新项目,删除了所有其他附加功能,只画了两条线在我的截图中。偏移问题仍然存在。我已经为原始帖子中的所有文件添加了代码。
  • 我查看了您提到的胶印。所以 OnTouch() 方法内部的 Y 和 Raw Y 没有区别。但是在 OnTouchEvent() 方法中,虽然 X 和 RawX 值相同,但我得到 rawY 和 Y 值之间的差异为 38(即 rawY - Y = 38)。但是仅仅调整这个偏移量并不能解决问题。此外,我在 MainActivity 类中创建的画布高度为 800,而在自定义视图中传递给 dispatchDraw() 方法的画布高度为 762(同样相差 38)。请告诉我可能需要研究的区域以消除此偏移。
  • 此外,我观察到从 MainActivity 和自定义视图类绘制的线之间的 Y 偏移量随着 Y 值的增加而增加。我从主活动和我的自定义视图中尝试了一组以下调用。 mCanvas.drawLine(0.0f, 100.0f, 200.0f, 100.0f, 油漆); mCanvas.drawLine(0.0f, 200.0f, 200.0f, 200.0f, 油漆); … mCanvas.drawLine(0.0f, 200.0f, 600.0f, 600.0f, 油漆); .. 为 Y=600 绘制的两条线比为 Y=100 绘制的线相距更远。截图:oi59.tinypic.com/qyzf39.jpg
  • 我意识到,如果我对 x 和 y 值应用坐标变换并在我的自定义视图中为 MainActivity 中给定的 x 和 y 值获取相应的值,则可以解决此问题。但问题是不同手机上的偏移量不同,我无法真正想出一个通用公式来计算转换后的 x 和 y 值。我想我在这里遗漏了一些基本的东西。应该有某种方法可以强制我的 MainActivity 中的 X 和 Y 值与我的自定义视图中的值匹配。如果有人能就此提供一些指示,我将不胜感激。
猜你喜欢
  • 2016-06-28
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 2013-02-24
  • 2014-01-11
相关资源
最近更新 更多