문제

I'm just starting to learn android and I searched online how can I force a onDraw update and the only method I found is invalidate. It work for a while but after that it just doesn't update anymore.

This is my code:

package com.andrewxd.test01;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class Game extends View {

    private Bitmap enemy;
    private Paint dpaint;
    private float x,y;

    public Game(Context context) {
        super(context);
        enemy = BitmapFactory.decodeResource(getResources(), R.drawable.enemy);
        enemy = Bitmap.createScaledBitmap(enemy, 300 , 300, false);
        dpaint = new Paint();
        x = 0;
        y = 0;
    }

    @Override
    protected void onDraw(Canvas canvas){
        canvas.drawBitmap(enemy, x, y, dpaint);
        Log.d("GAME", "REDRAWN");
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        x = event.getX();
        y = event.getY();
        invalidate();
        return true;
    }
}

Can somebody suggest me a better way of redrawing after the x and y changes?

도움이 되었습니까?

해결책

From the API-Docs:

The basic cycle of a view is as follows:

  • An event comes in and is dispatched to the appropriate view. The view handles the event and notifies any listeners.
  • If in the course of processing the event, the view's bounds may need to be changed, the view will call requestLayout().
  • Similarly, if in the course of processing the event the view's appearance may need to be changed, the view will call invalidate().
  • If either requestLayout() or invalidate() were called, the framework will take care of measuring, laying out, and drawing the tree as appropriate.

So, it's probably the way to do it!

다른 팁

Everything looks good, and I tried out your sample code to be sure, and it updates fine. The only difference from my code and yours is that I overrode the constructors as such and dropped your view into a layout:

public class Game extends View {

private Bitmap enemy;
private Paint dpaint;
private float x, y;

public Game(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    enemy = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
    enemy = Bitmap.createScaledBitmap(enemy, 300, 300, false);
    dpaint = new Paint();
    x = 0;
    y = 0;
}

public Game(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    // TODO Auto-generated constructor stub
}

public Game(Context context) {
    this(context, null);

}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(enemy, x, y, dpaint);
    Log.d("GAME", "REDRAWN");
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    x = event.getX();
    y = event.getY();
    invalidate();
    return true;
}

}

Layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

<com.example.gametest.Game
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</RelativeLayout>

Having the same problem. Calling invalidate with four parameters works for me:

invalidate(0,0,getWidth(),getHeight());

Looks like some bug in Android.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top