2012-01-26 38 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

相關問題