2012-01-26 22 views
5

我通过从视图延伸创建了自定义视图。在onDraw()我设法画出一些圈子和其他东西。但是现在我想从一个资源(SD卡或流)添加一个背景,这个背景实际上是我从服务器上下载的一张地图,并且可以在其上绘制。这是为Android 8+从Android上的.png文件中绘制自定义视图的背景

@Override 
protected void onDraw(Canvas canvas) { 
    Canvas g = canvas; 
    String file = "/mnt/sdcard/download/tux.png"; 
    Bitmap bg = null; 
    try { 
     bg = BitmapFactory.decodeFile(file); 
     g.setBitmap(bg); 
    } catch (Exception e) { 
     Log.d("MyGraphics", "setBitmap() failed according to debug"); 
    } 
} 

不知何故g.setBitmap(BG)不断失败了,我还没有看的图像规格,但实际上它只是PNG格式的图片礼服(无24位色)。 有人可以给我一些提示如何添加背景图片,以便我可以使用它? 谢谢。

回答

9

您实际上不想绘制您加载的位图,您只是想在画布上绘制它,所以您应该使用Canvas.drawBitmap()。你也真的不应该在每个onDraw()中加载一个位图,而是在构造函数中进行。试试这个类:

package com.example.android; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.util.AttributeSet; 
import android.view.View; 

public class CustomView extends View { 
    private final Bitmap mBitmapFromSdcard; 

    public CustomView(Context context) { 
     this(context, null); 
    } 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mBitmapFromSdcard = BitmapFactory.decodeFile("/mnt/sdcard/download/tux.png"); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     Canvas g = canvas; 
     if (mBitmapFromSdcard != null) { 
      g.drawBitmap(mBitmapFromSdcard, 0, 0, null); 
     } 
    } 
} 

您也可以让Android为绘制位图背景:

package com.example.android; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.view.View; 

public class CustomView extends View { 
    public CustomView(Context context) { 
     this(context, null); 
    } 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     Bitmap bm = BitmapFactory.decodeFile("/mnt/sdcard/download/tux.png"); 
     if (bm != null) { 
      setBackgroundDrawable(new BitmapDrawable(bm)); 
     } 
    } 
} 
+0

Martin, 非常感谢你为这个明确的例子。奇怪,我已经做了你的第一个例子,不知何故,它不工作!那是我开始迷路的地方。第二个是适应视野的房地产,这正是最终的结果。但你的第一个我更喜欢它,这样我可以在不修改尺寸的情况下定位图片。 – AndaluZ

+0

当你尝试我的第一个例子时,究竟是什么不起作用?一个例外(如果是这样,什么例外)?屏幕上没有绘制任何东西?你在运行什么Android版本?你能提供你想要的确切代码吗? –

+0

它可以与我的朋友一起工作,包括.png和.jpg。在您发布后,我仍然在播放并尝试一些图片,发现并非所有的.jpeg文件都能正常工作。当我使用像50 KB这样的小JPG图片时,它可以工作,但是当使用像600 KB这样的更大的JPG图片时,背景变成完全白色。我不知道它是否与图像大小有关,导致那些不起作用的图像比我的视图的房地产大得多。使用setBackgroundDrawable()确实有效,但它也会缩小到视图的实际大小。 – AndaluZ

0

恐怕你得到了OutOfMemoryError,导致在视图生命周期中多次调用onDraw,并且每次你为新的位图分配内存。只需让你的类的bg成员(也许是静态的)并只加载一次 - 在你的视图的构造函数中。并且不要忘记在视图的分离上回收位图。

+0

好了,这种情况在第一时间,我把一个断点:BG = BitmapFactory。解码(文件);调试时,g.setBitmap(bg)发生异常;我得到一个IllegalStateException,但无法检索有关此异常的更多信息。我担心它与位图的大小或密度有关,但在图形方面我的知识是有限的。 – AndaluZ

+0

好的,我发现,bg = BitmapFactory.decodeFile(file);返回一个不可变的位图,这意味着我不能在它上面绘制。有人可以给我提供一个简单的例子,说明如何从文件(或字节数组)加载图像,并将其作为自定义视图的背景图像,以便我可以在视图的onDraw()处理程序中使用它。只是一个简单的例子,谢谢。 – AndaluZ

+0

我可以提出两种制作方法: 1)内部调用View.setBackgroundDrawable()(以前需要从位图创建BitmapDrawable); 2)调用g.drawBitmap()而不是g.setBitmap()。在这种情况下,您并不是取代画布来源,而是将其吸入。 – OleGG