2012-08-09 23 views
6

Mam podklasę ImageView, której używam do rysowania obrazów z zaokrąglonymi narożnikami. Kod jest oparty na this answer, i przedstawia się następująco:Wydajność podczas rysowania ImageView z zaokrąglonymi rogami

public class ImageViewRoundedCorners extends ImageView { 
    ... 
    @Override 
    protected void onDraw(Canvas canvas) { 
     Bitmap scaledBitmap = Bitmap.createBitmap(getMeasuredWidth(), 
                getMeasuredHeight(), 
                Bitmap.Config.ARGB_8888); 
     Canvas scaledCanvas = new Canvas(scaledBitmap); 
     super.onDraw(scaledCanvas); 
     drawRoundedCornerBitmap(canvas, scaledBitmap, 
           getMeasuredWidth(), getMeasuredHeight()); 

     scaledBitmap.recycle(); 
    } 

    protected void drawRoundedCornerBitmap(Canvas outputCanvas, Bitmap input, int w, int h) { 
     Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888); 
     Canvas canvas = new Canvas(output); 

     mPaint.reset(); 
     mPaint.setAntiAlias(true); 
     canvas.drawARGB(0, 0, 0, 0); 

     mPaint.setStyle(Paint.Style.FILL); 
     canvas.drawPath(mClipPath, mPaint); 

     mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
     canvas.drawBitmap(input, 0, 0, mPaint); 

     outputCanvas.drawBitmap(output, 0, 0, null); 
    } 
} 

z tym kodem, obraz jest prawidłowo sporządzony z zaokrąglonymi narożnikami. Aby uniknąć alokacji w pierwszych dwóch wierszach drawRoundedCornerBitmap, chcę narysować bezpośrednio na outputCanvas, który jest płótnem pierwotnie przekazanym do onDraw. Nowa realizacja wygląda następująco:

protected void drawRoundedCornerBitmap(...) { 
    mPaint.reset(); 
    mPaint.setAntiAlias(true); 
    outputCanvas.drawARGB(0, 0, 0, 0); 

    mPaint.setStyle(Paint.Style.FILL); 
    outputCanvas.drawPath(mClipPath, mPaint); 

    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
    outputCanvas.drawBitmap(input, 0, 0, mPaint); 
} 

Z jakiegoś powodu ten kod wydaje się ignorować tryb Porter-Duff i zamiast po prostu rysuje obraz z normalnych (nie-zaokrąglonymi narożnikami). Dlaczego tak jest? Co to jest w przypadku rysowania do pliku pośredniego Bitmap, który sprawia, że ​​oryginalny kod działa?

+0

Ja też mam ten sam problem. –

+0

znalazłeś rozwiązanie dla tego ... nawet próbuję tego samego :( –

Odpowiedz

0

Utwórz losowanie Romain Guy zrobił to za Ciebie. Nie jesteśmy fabryką linków, ale jego blog wyjaśnia go dość szeroko i zapewnia skuteczny sposób na to. Rounded Corners

Prawdziwy Podstawową zasadą jest stworzenie BitmapShader i dołączyć go do Paint obiekt, który przyciąga w zwyczaju Drawable ten sposób można stosować tylko, że Drawable do ImageView.

Posługiwanie się ciągiem oznacza, że ​​Obraz jest tylko malowany na płótnie tylko raz, co oznacza, że ​​rysowanie obrazu odbywa się tylko raz, a następnie wszystkie ImageView robi tylko skalować losowanie.

+0

Czy to nie jest taki ból, kiedy musisz skalować ten drawable w imageView? Drawable jest tworzone, a następnie rozciągane lub przycinane, co oznacza, że ​​twoje rogi będą wyglądały dziwnie, nie? – secureboot

+0

Pamiętaj, że 'ImageView' zamienia wszystko, co do niego dojdziesz, na' Drawable', podaje swój rozmiar, a następnie wywołuje 'draw()' na 'Drawable'. miałeś BitmapDrawable, to oczywiście po prostu go rozciągniesz, gdy przekażesz 'RoundedBitmapDrawable' per-se, będzie rysował na podstawie tej implementacji. –

Powiązane problemy