2012-01-26 31 views
5

Tôi đã tạo Chế độ xem tùy chỉnh bằng cách mở rộng từ Chế độ xem. Trong onDraw(), tôi đã vẽ một số vòng kết nối và các nội dung khác. Nhưng bây giờ tôi muốn thêm một nền tảng từ một tài nguyên (thẻ sd hoặc một dòng) mà thực sự là một bản đồ tôi tải về từ máy chủ của chúng tôi và hơn vẽ trên đó. Đó là dành cho Android 8+Vẽ nền của Chế độ xem tùy chỉnh từ tệp .png trên Android

@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"); 
    } 
} 

Bằng cách nào đó g.setBitmap (bg) giữ không, tôi đã không nhìn vào thông số kỹ thuật hình ảnh, nhưng thực chất nó chỉ là một hình ảnh tux (không 24 bit màu) của định dạng PNG. Ai đó có thể cho tôi một số mẹo về cách thêm hình nền để tôi có thể vẽ trên đó không? Cảm ơn bạn.

Trả lời

9

Bạn thực sự không muốn vẽ vào bitmap bạn tải, bạn chỉ muốn vẽ nó trên Canvas, vì vậy bạn nên sử dụng Canvas.drawBitmap(). Bạn cũng thực sự không nên tải một Bitmap trong mỗi onDraw(), thay vào đó hãy thực hiện nó trong hàm tạo. Hãy thử lớp này:

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); 
     } 
    } 
} 

Bạn cũng có thể cho Android vẽ bitmap trong nền:

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, Cảm ơn bạn rất nhiều vì ví dụ rõ ràng này. Lạ thật, tôi đã làm ví dụ đầu tiên của bạn và bằng cách nào đó nó không hoạt động! Đó là nơi tôi bắt đầu bị lạc. Thứ hai là kéo dài để phù hợp trong bất động sản của xem, đó là chính xác những gì đã cuối cùng. Nhưng lần đầu tiên tôi thích nó tốt hơn nhiều, bằng cách này tôi có thể định vị hình ảnh mà không sửa đổi kích thước của nó. – AndaluZ

+0

Khi bạn thử ví dụ đầu tiên của tôi, chính xác những gì không hoạt động? Một ngoại lệ (nếu có, ngoại lệ nào)? Không có gì được vẽ trên màn hình? Bạn đang chạy phiên bản Android nào? Bạn có thể cung cấp mã chính xác bạn sử dụng mà bạn mong đợi để làm việc nhưng điều đó không? –

+0

Nó hoạt động với bạn của tôi, với .png cũng như .jpg. Sau bài viết của bạn tôi vẫn đang chơi và thử một số hình ảnh và phát hiện ra rằng không phải tất cả các tệp .jpeg đều hoạt động. Khi tôi sử dụng hình ảnh jpg nhỏ như 50 KB nó hoạt động, nhưng khi sử dụng hình ảnh jpg lớn hơn như 600 KB nền biến hoàn toàn trắng. Tôi không biết liệu nó có liên quan đến kích thước hình ảnh hay không, khiến những người không hoạt động có kích thước lớn hơn nhiều so với bất động sản của tôi. Sử dụng setBackgroundDrawable() không hoạt động, nhưng nó cũng co lại thành kích thước bất động sản của View. – AndaluZ

0

Tôi sợ rằng bạn nhận được OutOfMemoryError, gây ra onDraw được gọi nhiều lần trong suốt vòng đời xem và mỗi lần bạn phân bổ bộ nhớ cho bitmap mới. Chỉ cần làm cho thành viên bg (có thể - tĩnh) của lớp của bạn và tải nó chỉ một lần - trong constructor của khung nhìn của bạn. Và đừng quên tái chế bitmap khi tách khỏi chế độ xem.

+0

Vâng, điều này xảy ra ở lần đầu tiên, tôi đã đặt một breakpoint trên: bg = BitmapFactory. giải mã (file); Trong khi gỡ lỗi, ngoại lệ xảy ra trên g.setBitmap (bg); Tôi nhận được một IllegalStateException, nhưng không thể truy xuất thêm thông tin về ngoại lệ này. Tôi sợ nó phải làm với kích thước hoặc mật độ bitmap, nhưng kiến ​​thức của tôi bị giới hạn khi nói đến đồ họa. – AndaluZ

+0

Ok, tôi phát hiện ra rằng bg = BitmapFactory.decodeFile (file); trả về một bitmap không thay đổi, có nghĩa là tôi không thể vẽ nó. Có thể ai đó vui lòng cung cấp cho tôi một ví dụ đơn giản làm thế nào để tải một hình ảnh từ một tập tin (hoặc một bytearray) và đặt nó như là một hình nền của một View tùy chỉnh, vì vậy tôi có thể vẽ nó trong onDraw() handler của view? Chỉ là một ví dụ đơn giản, cảm ơn bạn. – AndaluZ

+0

Tôi có thể đề xuất hai cách làm như vậy: 1) gọi nội bộ View.setBackgroundDrawable() (trước đây bạn cần tạo BitmapDrawable từ bitmap); 2) gọi g.drawBitmap() thay vì g.setBitmap(). Trong trường hợp này, bạn không thay thế nguồn vải, nhưng vẽ vào đó. – OleGG

Các vấn đề liên quan