Проблемы при рисовании в SurfaceView

Я экспериментирую с SurfaceView в Android и пытаюсь создать простое приложение для рисования, в котором вы «рисуете», касаясь его. У меня есть поток для обработки рисунка на холсте, но я сталкиваюсь с некоторыми проблемами производительности. Я прочитал на http://developer.android.com/guide/topics/graphics/index.html, что вам нужно перекрасить всю поверхность, поэтому я попытался сохранить все точки касания в массиве mPoints с плавающей запятой, а затем каждый раз перерисовывать их. Проблема в том, что когда накапливается много очков, это становится очень медленным. Вот код для этого:

    @Override
    public void run() { 

        while(mIsRunning) {
            Canvas c = null;
            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    int size = mPoints.getSize();
                    for(int i = 0; i < size; i += 2) {
                        c.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                            
                    }   
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }

Однако, когда я обновил его, чтобы он очистил массив с плавающей запятой и рисовал только новые точки касания, это вызвало много мерцания. Насколько я могу судить, это потому, что Android использует двойную буферизацию. Я не уверен, как обойти эти проблемы.


person Corey Sunwold    schedule 19.12.2010    source источник


Ответы (2)


попробуйте записать в растровое изображение, а затем каждый раз перерисовывать растровое изображение. Возможно, вы можете сохранить запись последних 10 точек или что-то, чтобы разрешить отмену и т. Д.

person Adil    schedule 19.12.2010
comment
У вас есть примеры того, как это сделать? - person Corey Sunwold; 19.12.2010

Основываясь на ответе Адиля, это то, что я придумал и, кажется, работает. Кажется, что он не совсем улавливает каждую точку, если вы пытаетесь нарисовать непрерывную линию точек, поэтому он нуждается в некоторой дальнейшей оптимизации, но он выполняет свою работу:

    @Override
    public void run() {
        mDrawing = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);       
        Canvas tempCanvas = new Canvas();
        tempCanvas.setBitmap(mDrawing);

        Canvas c = null;
        while(mIsRunning) {
            int size = mPoints.getSize();
            for(int i = 0; i < size; i += 2) {
                tempCanvas.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                           
            }    

            mPoints.empty();

            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    c.drawBitmap(mDrawing, 0, 0, mPaint);
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }
person Corey Sunwold    schedule 20.12.2010