如何在Android的ImageView上绘制线条?

6
我正在尝试开发一个简单的地图应用程序,它将在屏幕上显示一张地图。当用户在屏幕上移动光标时,我想在我的地图上显示2条垂直的线。我尝试了很多示例来了解这个问题,但不幸的是没有成功。我该怎么做呢?
正如之前提到的一个问题here,我已经尝试过了,但没有得到答案。有人能指导我吗?
我的main.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    <ImageView android:id="@+id/main_imagemap"
        android:src="@drawable/worldmap"
        android:clickable="true"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>

我的活动文件(我刚刚开始使用它...)

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

public class LineMapActivity extends Activity 
{


    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ImageView map_image = (ImageView)findViewById(R.id.main_imagemap);

    }
}

就像在那个链接中一样,我也添加了MyImageView。

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.widget.ImageView;

public class MyImageView extends ImageView
{

    public MyImageView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        canvas.drawLine(0, 0, 20, 20, p);
        super.onDraw(canvas);
    }
}

现在我该如何将这个MyImageView添加到我的应用程序中呢?

为什么你不使用MapView和覆盖物呢?看看这个教程:http://codemagician.wordpress.com/2010/05/06/android-google-mapview-tutorial-done-right/ - MikeIsrael
不,我只是一个新手在Andriod上.. 我只是从drawables中添加了一张图片。我只想学习如何在图像上方绘制线条.. 就像旧的黑莓手机一样。 - Dil Se...
好的,检查一下我的答案,它应该能给你想要的结果。 - MikeIsrael
3个回答

4

最终我找到了一个解决方案。这是一个简单的程序,它在图像上画一条线。

以下是我的main.xml文件(com.ImageDraw.MyImageView是我的自定义视图,下面是代码):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    <com.ImageDraw.MyImageView android:id="@+id/main_imagemap"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>

这里是主要活动:

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity 
{
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

这是我的自定义图片视图(MyImageView):

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MyImageView extends SurfaceView implements SurfaceHolder.Callback
{
    private CanvasThread canvasthread;

    public MyImageView(Context context) {
        super(context);
        getHolder().addCallback(this);
        canvasthread = new CanvasThread(getHolder(), this);
        setFocusable(true);
    }

    public MyImageView(Context context, AttributeSet attrs)
    {
        super(context,attrs);
        getHolder().addCallback(this);
        canvasthread = new CanvasThread(getHolder(), this);
        setFocusable(true);
    }

    protected void onDraw(Canvas canvas) {
        Log.d("ondraw", "ondraw");
        Paint p = new Paint();
        Bitmap mapImg = BitmapFactory.decodeResource(getResources(), R.drawable.mybitmap);
        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(mapImg, 0, 0, null);
        p.setColor(Color.RED);
        canvas.drawLine(0, 0, 100, 100, p);
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    public void surfaceCreated(SurfaceHolder holder) {
        canvasthread.setRunning(true);
        canvasthread.start();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        canvasthread.setRunning(false);
        while (retry)
        {
            try
            {
                canvasthread.join();
                retry = false;
            }
            catch (InterruptedException e) {
                // TODO: handle exception
            }
        }
    }
}

最后,这是我的CanvasThread:

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class CanvasThread extends Thread
{
    private SurfaceHolder surfaceHolder;
    private MyImageView myImageView;
    private boolean run = false;

    public CanvasThread(SurfaceHolder s, MyImageView m)
    {
        surfaceHolder = s;
        myImageView = m;
    }

    public void setRunning(boolean r)
    {
        run = r;
    }

    public void run()
    {
        Canvas c;
        while(run)
        {
            c=null;
            try
            {
                c= surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    myImageView.onDraw(c);
                }
            }
            finally
            {
                if(c!=null)
                {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
}

你可以在这个教程中找到更多细节,它涉及到如何在你的安卓应用程序中使用画布。

2
特别感谢MikeIsrael,他给了我很大的帮助...还有那个网站也要感谢。 - Dil Se...
1
看起来不错。如果以后您发现需要保留原始图像,您可以将一个ImageView与MyImageView重叠使用。祝好运! - MikeIsrael
你可以在xml中使用RelativeLayout和align属性进行重叠,只需搜索相关信息即可找到大量资料。然后,你可以仅在顶部的ImageView上绘制,如果需要擦除,则保留底部不变。 - MikeIsrael
还有一个疑问,我该如何在图像下方添加按钮和文本。当我尝试这样做时,它没有显示在屏幕上。我已经尝试在图像上方添加,对我来说效果很好...我想画布/ SurfaceView 正在占据整个高度和宽度。我该如何将其限制在图像上?或者这可能吗? - Dil Se...
mybitmap是什么? - Tom11
显示剩余2条评论

1
你收到这个错误是因为你试图将 ImageView 对象转换成 MyImageView 对象。

那么我需要如何实现我在问题中提供的链接中的MyImageView?还是你能展示一下我如何在ImageView上面画线? - Dil Se...
亲爱的,我已经更新了我的问题。希望你能理解我所问的内容。再次描述一下,我想要一个可以将图像作为背景显示并且可以在其上绘制线条的应用程序。所有这些代码都是我的实验,不确定这些代码是否有效。 - Dil Se...

1

只需修复XML文件,将对象包含进去,而不是像ImageView一样(请注意,com.your.package.MyImageView应该是包含您的类的包的完整包名,然后是类名)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    <com.your.package.MyImageView android:id="@+id/main_imagemap"
        android:src="@drawable/worldmap"
        android:clickable="true"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>

我有一个名为com.mymap的包; 因此,我修改了我的xml为<com.mymap.MyImageView.. 但现在我遇到了一个错误,导致我强制关闭。 - Dil Se...
这并不真正有帮助,您需要粘贴整个堆栈跟踪以找出错误发生的位置。 - MikeIsrael
尝试使用e.printStackTrace()方法,应该会在您的logcat中以红色(如果是警告,则为黄色)打印出来。这是非常基础的Java知识,难道您还没有学过基础的Java课程吗? - MikeIsrael
我在我的一些应用程序中使用相同类型的关联,因此在xml中使用自定义对象肯定是有效的,它可能是其中一个属性,尝试将其注释掉,只保留宽度和高度,看看错误是否仍然存在,并且请仔细检查您列出的包名.类名。 - MikeIsrael
谢谢Mike,我终于明白了。感谢您的帮助。请检查我在这里放置的答案,并在我错的情况下进行更正。 - Dil Se...
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接