Поверхность Android изменила неверные значения ширины / высоты - PullRequest
2 голосов
/ 07 февраля 2012

У меня есть растровое изображение, которое рисуется на поверхности и требует изменения размера при каждом повороте устройства.Из-за программных кнопок я использую этот код для получения текущих размеров (кажется, что он работает нормально):

public void getCanvasXY(){
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2){
         // HoneyComb 3.2 and up
         DisplayMetrics metrics = new DisplayMetrics();
         ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
         Global.CanvasX = metrics.widthPixels;
         Global.CanvasY = metrics.heightPixels;
    } else{
         // before HoneyComb
         Global.CanvasX = getWidth();
         Global.CanvasY = getHeight();
    }
}

Я подумал, что лучшее место для пересчета размеров и создания моего растрового изображения - это SurfaceChanged ().

@Override
    public void surfaceChanged(SurfaceHolder holder1, int format, int width, int height) {
                getCanvasXY();
                LoadBMP();
    }

Я вижу, что это вызывается более одного раза, и я получаю разные значения для CanvasX и CanvasY, когда устройство вращается.Последний раз, когда он вызывается, работает нормально, но я вижу, как onDraw () рисует мое растровое изображение и спрайты плохо меняются и, наконец, нормально.Это ужасный эффект.Как это решить?спасибо

1 Ответ

0 голосов
/ 18 июня 2012

Здесь я предполагаю, что вы имеете в виду SurfaceView, где вы используете фоновый поток для рисования на поверхности, а вы используете SurfaceHolder.CallBack (). Это не полный ответ, однако, эта проблема также мучила меня некоторое время. В моем позднем ночном поиске неисправностей мне удалось собрать обходной путь, который может быть немного более элегантным, чем ваш. В результате ничего не рисуется, пока поверхность не изменилась до своего последнего состояния, поэтому пользователь не знает, что происходит.

При изменении поверхности вы заметите, что ваша высота или ширина не изменяются на правильное значение, другими словами, поверхность результата, если она нарисована, имеет значение MalFormed. То, что вам нужно, это справочное значение того, какими должны быть ваши рост и ширина, вы можете получить это, поместив следующий код перед SetContentView () в вашей основной деятельности:

WindowManager w = getWindowManager();
   Display d = w.getDefaultDisplay();
   int Meausredwidth = d.getWidth();
   int Measuredheight = d.getHeight(); 

Теперь из ваших измеренных высоты и ширины определите, сколько вы назначаете для SurfaceView, и передайте эти значения в SurfaceView в качестве глобальных переменных. И убедитесь, что вы вызываете вышеуказанный код в onconfigurationchanged () в своей основной деятельности, чтобы эти значения каждый раз пересчитывались. Теперь на вашем SurfaceView, который должен каким-то образом реализовывать SurfaceHolder.Callback, измените свою поверхность, чтобы она выглядела следующим образом:

@Override
public void surfaceChanged(SurfaceHolder mholder, int format, int width,
        int height) {

    if (width != mWidth) {
        MalFormed = true;
        thread.setRunning(false);
        count++;

    } else if (width == mWidth) {

        if (MalFormed) {
            MalFormed = false;

            Log.d("ROTATE", "ReDraw");

            thread = new DrawingThread(this, holder, mHandler);
            thread.setRunning(true);
            thread.start();

        }

    }

}

Где mWidth - желаемая ширина. Здесь вам может потребоваться изменить оператор if в зависимости от вашей конкретной проблемы. А MalFormed - это глобальное логическое значение в вашем виде поверхности.

Теперь важно помнить, что если происходит изменение, то SurfaceChanged () вызывается до SurfaceCreated, что означает, что мы можем легко изменить любой код, который пытается взаимодействовать с потоком, в соответствии с нашими вышеупомянутыми изменениями.

Так что где бы вы ни пытались присоединиться или запустить этот фоновый поток рисования, вы должны сначала проверить, является ли поверхность MalFormed. Э.Г.

if (thread.getState() == State.TERMINATED){

            if(!MalFormed){
               holder.removeCallback(this);
               holder = getHolder();
               holder.addCallback(this);


               thread = new DrawingThread(this, holder,mHandler);
               thread.setRunning(true);

               thread.start();
            }



        }else{
            if(!MalFormed){
                thread.setRunning(true);

                try {
                    thread.join();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }


        }

Надеюсь, я где-нибудь на стадионе. Всего наилучшего.

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