Проблемы с обновлением холста Android - PullRequest
0 голосов
/ 26 марта 2012

Я просто не заставляю это работать. Я видел, что эта сеть не просто для исправления кода постов. Но я думаю, что это в интересах других, потому что не было никаких хороших учебников.

Итак, я вызываю холст и могу рисовать на нем методом ondraw(), но когда я пытаюсь вывести его из игрового цикла, он ничего не рисует. Я даже не получаю сообщение об ошибке.

Приложение:

public class App extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        draw d = new draw(this);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                WindowManager.LayoutParams.FLAG_FULLSCREEN);


        setContentView(d);

    }
    public void end()
    {
        App.this.finish();
    }
}

draw.java:

public class draw extends View {
    Canvas ca;
    View v;
    Paint paint;

    int width;
    int height;

    static final int MAX_GAME_SPEED=33;
    static int fps; 
    boolean running=true;



    int pw=0,ph=0;





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

            @Override
        protected void onDraw(Canvas c){
        super.onDraw(c);
        paint = new Paint(); //Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);


        //get screen size
        WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();


        width = display.getWidth();  // deprecated
        height = display.getHeight();  // deprecated







            // make the entire canvas white
            paint.setColor(Color.WHITE);
            c.drawPaint(paint);


            ca = c;
            paint.setColor(Color.BLACK);
            c.drawRect(Math.round(width/3),Math.round(height/3),Math.round((width/3)*2),Math.round((height/3)*2), paint); //position width, position height,width,height


            paint.setStyle(Paint.Style.FILL);
            paint.setAntiAlias(true);
            paint.setTextSize(30);
            paint.setColor(Color.GREEN);
            c.drawText(String.valueOf(width)+"x"+String.valueOf(height)+","+Math.round(width/3)+"x"+Math.round(height/3), 30, 200, paint);
            paint.setColor(Color.GREEN);
            c.drawText(String.valueOf(width)+"x"+String.valueOf(height)+","+Math.round(width/3)+"x"+Math.round(height/3), 30, 200, paint);


            Thread myThread = new Thread(new UpdateThread());
            myThread.start();

    }
            public void paint(Canvas c)
            {

                paint.setColor(Color.GREEN);
                c.drawRect(20, 5, 50, 100, paint);

                pw++;
                ph++;



                /*if (pw >= width || ph >= height)
                {
                    pw=0;
                    ph=0;
                }
                */

            }
            public Handler updateHandler = new Handler(){
                /** Gets called on every message that is received */
                // @Override
                public void handleMessage(Message msg) {

                   paint(ca);


                    super.handleMessage(msg);
                }
            };



            public class UpdateThread implements Runnable {

                @Override
                public void run() {
                     while(true){
                         draw.this.updateHandler.sendEmptyMessage(0);

                    }
                }

            }

    }

Ответы [ 4 ]

2 голосов
/ 26 марта 2012

Во-первых: Вы отправляете сообщения об обновлениях слишком часто. Я полагаю, что вы перегружаете свою очередь сообщений этим.

Во-вторых: Вы используете экземпляр canvas, сохраненный в методе onDraw. Я думаю, что это не правильно. Вместо этого вы можете изменить метод UpdateThread.run () на

@Override
public void run() {
    while(true){
        draw.this.postInvalidate();
    }
}

Это отправит сообщение об аннулировании и перерисовке вашего View и, следовательно, вызове вашего метода View.onDraw (Canvas) с правильным Canvas.

Также: Если вы хотите максимально полно визуализировать ваш вид, вы должны реализовать следующую последовательность:

static final int MSG_REDRAW = 1;

Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MSG_REDRAW:
            // This method invoked on UI thread - ok.
            draw.this.invalidate();
            sendEmptyMessage(MSG_REDRAW);
            break;

        default:
            super.handleMessage(msg);
            break;
        }
    }
}

и вместо планирования потока (UpdateThread) вам просто нужно отправить первое сообщение MSG_REDRAW.

0 голосов
/ 27 марта 2012

У меня были проблемы с postInvalidate и темой.прежде всего попробуйте добавить setWillNotDraw(false);, и у меня возникла проблема, когда экран изменил ориентацию - для перерисовки потребовалось много времени с помощью postInvalidate (), потому что из-за вызова этой функции мы не знаем, когда будет вызван onDraw, но это будетбыть.для моего решения и вопроса об этом посмотрите эту ссылку .

0 голосов
/ 26 марта 2012

Вам не нужен дополнительный поток.

Просто сделайте недействительным последнее предложение в onDraw, и onDraw снова будет запланирован.

0 голосов
/ 26 марта 2012

Итак, у вас есть View и в onDraw () вы создаете Thread, который выполняет рисование?Зачем?Вы должны рисовать весь поток в пользовательском интерфейсе и привязывать другие части вашей игры к другим потокам.

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