2012-01-26 9 views
5

Utworzono niestandardowy widok, rozszerzając widok. W onDraw() udało mi się narysować kilka okręgów i inne rzeczy. Ale teraz chcę dodać tło z zasobu (karty SD lub strumienia), które jest mapą pobraną z naszego serwera, a następnie narysować na niej. To dla Androida 8+Rysowanie tła niestandardowego widoku z pliku .png na urządzeniu z systemem 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"); 
    } 
} 

Jakoś g.setBitmap (BG) utrzymuje upadających, nie spojrzał na specyfikacje graficznych, ale w rzeczywistości jest to tylko obraz tux (nr 24 bitowe kolory) formatu PNG. Czy ktoś może mi dać wskazówki, jak dodać obraz tła, aby móc go narysować? Dziękuję.

Odpowiedz

9

W rzeczywistości nie chcesz narysować na bitmapie, którą ładujesz, po prostu chcesz narysować na płótnie, więc powinieneś użyć Canvas.drawBitmap(). Ty też nie powinieneś ładować mapy bitowej w każdym onDraw(), zrób to w konstruktorze. Spróbuj tej klasy:

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

Można również pozwolić Android narysować bitmapę w tle:

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, Dziękuję bardzo za ten czysty przykład. Dziwne, że już zrobiłem twój pierwszy przykład i jakoś nie zadziałało! Tam zacząłem się gubić. Drugi rozciąga się, aby zmieścić się w nieruchomościach widoku, dokładnie to było w końcu. Ale twój pierwszy podoba mi się znacznie lepiej, w ten sposób mogę ustawić zdjęcie bez zmiany jego rozmiaru. – AndaluZ

+0

Kiedy wypróbujesz mój pierwszy przykład, dokładnie to, co nie działa? Wyjątek (jeśli tak, jaki wyjątek)? Nic nie zostanie narysowane na ekranie? Jakiej wersji Androida używasz? Czy możesz podać dokładny kod, którego używasz, ale który nie działa? –

+0

To działa mój przyjaciel, z. Png, a także .jpg. Po twoim wpisie nadal grałem i próbowałem trochę zdjęć i odkryłem, że nie wszystkie pliki .jpeg działają. Kiedy używam małych zdjęć w formacie jpg, takich jak 50 KB, to działa, ale podczas korzystania z większych zdjęć w formacie jpg, takich jak 600 KB, tło staje się całkowicie białe. Nie wiem, czy ma to związek z rozmiarem obrazu, ponieważ te, które nie działają, mają znacznie większy rozmiar niż nieruchomość mojego widoku. Użycie funkcji setBackgroundDrawable() działa, ale zmniejsza się również do rozmiaru nieruchomości View. – AndaluZ

0

Obawiam się, że dostaniesz OutOfMemoryError, ponieważ onDraw jest wywoływany wiele razy podczas cyklu życia widoku i za każdym razem przydzielasz pamięć dla nowej bitmapy. Po prostu stwórz członka bg (być może - statycznego) swojej klasy i załaduj go tylko raz - w swoim konstruktorze widoku. I nie zapomnij zregenerować bitmapy podczas odłączania widoku.

+0

Cóż, to dzieje się po raz pierwszy, mam umieścić punkt przerwania na: BG = BitmapFactory. dekodowanie (plik); Podczas debugowania występuje wyjątek na g.setBitmap (bg); Otrzymuję wyjątek IllegalStateException, ale nie mogę pobrać więcej informacji o tym wyjątku. Obawiam się, że ma to związek z rozmiarem lub gęstością bitmapy, ale moja wiedza jest ograniczona, jeśli chodzi o grafikę. – AndaluZ

+0

Ok, dowiedziałem się, że bg = BitmapFactory.decodeFile (plik); zwraca niezmienną bitmapę, co oznacza, że ​​nie mogę jej narysować. Czy ktoś może podać mi prosty przykład, jak załadować obraz z pliku (lub bytearray) i umieścić go jako obraz tła niestandardowego widoku, więc mogę go narysować w procedurze onDraw() widoku? Prosty przykład, dziękuję. – AndaluZ

+0

Mogę zaproponować dwa sposoby robienia takich rzeczy: 1) wewnętrznie wywołać View.setBackgroundDrawable() (wcześniej trzeba utworzyć BitmapDrawable z bitmapy); 2) wywołaj g.drawBitmap() zamiast g.setBitmap(). W tym przypadku nie zastępujesz źródła canvas, ale narysuj do niego. – OleGG