Как я могу переопределить onDraw, чтобы взять то, что было бы нарисовано (как растровое изображение) и преобразовать его? - PullRequest
7 голосов
/ 04 мая 2010

Приведенный ниже метод работает, но, к сожалению, этот метод включает создание растрового изображения размером всего экрана, а не только области, к которой обращается Если я использую это для рисования элементов пользовательского интерфейса, он перерисовывается для каждого элемента пользовательского интерфейса . Можно ли сделать это более эффективно?

@Override
protected void onDraw(Canvas canvas) {
    //TODO: Reduce the burden from multiple drawing
    Bitmap bitmap=Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);
    Canvas offscreen=new Canvas(bitmap);
    super.onDraw(offscreen);
    //Then draw onscreen
    Paint p=new Paint();
    p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
    canvas.drawBitmap(bitmap, 0, 0, p);
}

Ответы [ 3 ]

9 голосов
/ 05 мая 2010

Следующий код будет намного эффективнее.

public class MyView extends TextView{
    private Canvas offscreen;

    public MyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //We want the superclass to draw directly to the offscreen canvas so that we don't get an infinitely deep recursive call
        if(canvas==offscreen){
            super.onDraw(offscreen);
        }
        else{
            //Our offscreen image uses the dimensions of the view rather than the canvas
            Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
            offscreen=new Canvas(bitmap);
            super.draw(offscreen);
            //Create paint to draw effect
            Paint p=new Paint();
            p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
            //Draw on the canvas. Fortunately, this class uses relative coordinates so that we don't have to worry about where this View is actually positioned.
            canvas.drawBitmap(bitmap, 0, 0, p);
        }
    }
}
8 голосов
/ 04 мая 2010

Вы пытались изменить размер создаваемого растрового изображения, чтобы он был равен только границам клипа, а не всему размеру данного холста? Я не знаю, так ли это со всеми представлениями, но я обнаружил, что метод onDraw для некоторых представлений получает холст размером с экран, независимо от фактического размера содержимого. Затем он обрезает холст, ограничивая его только левым верхним углом, рисует там, а затем переводит эту часть куда-то на экран, когда он фактически готов отобразить весь макет. Другими словами, несмотря на то, что он имеет холст размером с весь экран, он на самом деле использует только его небольшой фрагмент. Так что вы можете попробовать вместо

Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), ...)

Вы можете попробовать

Rect rect = canvas.getClipBounds();
int width = rect.width();
int height = rect.height();
Bitmap bitmap = Bitmap.createBitmap(width, height, ...); 

Таким образом вы сокращаете накладные расходы при работе с намного большим битовым массивом, чем необходимо. Примечание. На самом деле я не пытался сделать это, так что это может не сработать, но стоит попробовать.

0 голосов
/ 28 октября 2013

Я столкнулся с чем-то похожим, где canvas.getWidth () и canvas.getHeight () возвращает ширину и высоту всего экрана вместо самого представления.

Попробуйте использовать нижеприведенное:

Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);

В моем случае getWidth () и getHeight () возвращают мне размеры моего представления. Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...