2 votes

Seamless background comme composant de vue personnalisé, onDraw n'est pas appelé par invalidate().

Les amis,

Je veux créer un arrière-plan sans couture en tant que composant de vue personnalisé.

Le problème, je l'ai découvert pendant le débogage,

La première fois que j'appelle invalidate() dans le thread, ma méthode de rappel onDraw est appelée. Les autres fois où mon thread appelle invalidate(), la méthode de rappel onDraw n'est pas appelée.

donc il passe juste sur la méthode invalidate(), comme si elle n'existait pas.

L'application affiche le png d'arrière-plan sans couture. Mais comme il est statique, il n'est pas mis à jour.

J'affiche tout mon code parce que le bogue peut se trouver en dehors du fil, là où se trouve invalidate() ou en dehors de la méthode onDraw.

J'apprécie toute forme d'aide, donc THX.

              public class MyBringBackSurface extends View implements Runnable {

Bitmap bitmapResource;
int leftFrameX, rightFrameX, startX, stopX, bitmapPixelWidth,
        bitmapPixelHight;
int pixelPerFrame = 10;
int framerate = 100;
int threadSleepTime;
int offsetYInPixel = 200;
Thread ourthread = null;
boolean isrunning = false;

Canvas c;

public MyBringBackSurface(Context context) {
    super(context);

    init();

}

public MyBringBackSurface(Context context, AttributeSet attrs) {
    super(context, attrs);

    init();

}

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

    init();

}

private void init() {

    // Set up Bitmap Resource

    bitmapResource = BitmapFactory.decodeResource(getResources(),
                    R.drawable.simelessbackground);

 //  c = new Canvas(bitmapResource);

    // Implementing leftFrameX and rightFrameX
    leftFrameX = 0;
    rightFrameX = bitmapResource.getWidth();

    // Calculating the Thread sleep time
    threadSleepTime = 1000 / framerate;

}

public void pause() { // destroy the currently running thread because
                        // anyways in the on resume will be created a
                        // new one again

    isrunning = false;
    while (true) {

        try { // goes through this thread until our thread died
            ourthread.join(); // Blocks the current Thread
                                // (Thread.currentThread()) until the
                                // receiver finishes its execution and
                                // dies.
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        break;
    }

}

public void resume() {

    isrunning = true;
    ourthread = new Thread(this);

    ourthread.start();

}

public void run() {

    while (isrunning) {

        try {
            Thread.sleep(threadSleepTime);
            // formula is 1000/ sleep time (here 5) = frame rate
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

        invalidate();

        // Add pixelPerFrame and draw again
        leftFrameX = leftFrameX - pixelPerFrame;
        rightFrameX = rightFrameX - pixelPerFrame;

        // if picture is completely out of the screen, start over again
        if (leftFrameX <= -bitmapResource.getWidth()) {
            leftFrameX = 0;
            rightFrameX = bitmapResource.getWidth();
        }
    }
}

/**
 * Render the text
 * 
 * @see android.view.View#onDraw(android.graphics.Canvas)
 */
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.drawRGB(255, 255, 255);

    // Draw Rectangle 1250 pixel
    Rect rect1000 = new Rect();
    rect1000.set(0, 0, 1250, 20);
    Paint blue = new Paint();
    blue.setColor(Color.BLUE);
    canvas.drawRect(rect1000, blue);

    // Draw first Bitmap
    Rect rectBitmapSource = new Rect(0, 0, bitmapResource.getWidth(),
            bitmapResource.getHeight());
    Rect rectBitmapDestinationFirst = new Rect(leftFrameX, offsetYInPixel,
            rightFrameX, offsetYInPixel + bitmapResource.getHeight());
    canvas.drawBitmap(bitmapResource, rectBitmapSource,
            rectBitmapDestinationFirst, null);

    // Draw second Bitmap

    Rect rectBitmapDestinationSecond = new Rect(
            (leftFrameX + bitmapResource.getWidth()), offsetYInPixel,
            (rightFrameX + bitmapResource.getWidth()), offsetYInPixel
                    + bitmapResource.getHeight());
    canvas.drawBitmap(bitmapResource, rectBitmapSource,
            rectBitmapDestinationSecond, null);

}

}

1voto

Arnold Points 615

J'ai trouvé la réponse après avoir parcouru les googledocs.

si vous voulez invalider une vue depuis l'extérieur de l'UI-Thread, vous devez utiliser la commande postinvalidate() au lieu de invalidate().

C'est ça. Ça va marcher comme un charme ! !!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X