Android 避免在按下按钮时更新视图类

Android 避免在按下按钮时更新视图类,android,layout,view,sprite,runnable,Android,Layout,View,Sprite,Runnable,我有一个位图,它是在我的Sprite类中绘制的,这个位图是多张图片中的一张,所以我可以为它设置动画 当我将XML旁边的GameLayout充气时,会绘制此精灵。每次调用my GameActivity的run()方法时(在特殊情况下),这张图片会自动更新4次,因此动画完成 这一切都运行得很好,但我的问题是,如果我按下按钮(无论姜黄素是否满足),位图会跳转到下一张图片,因此,位图会自动更新,而无需我使用view.invalidate()调用它 你知道我怎样才能阻止这一切吗 游戏活动: public

我有一个位图,它是在我的
Sprite
类中绘制的,这个位图是多张图片中的一张,所以我可以为它设置动画

当我将XML旁边的
GameLayout
充气时,会绘制此精灵。每次调用my GameActivity的
run()
方法时(在特殊情况下),这张图片会自动更新4次,因此动画完成

这一切都运行得很好,但我的问题是,如果我按下按钮(无论姜黄素是否满足),位图会跳转到下一张图片,因此,位图会自动更新,而无需我使用
view.invalidate()
调用它

你知道我怎样才能阻止这一切吗

游戏活动:

public class GameActivity extends Activity implements OnClickListener, Runnable
{
private int punkte;
private int highscore;
private Handler handler = new Handler();
private int balken = 0;
private boolean abnehmend = false;
private int Klick = 0;
private boolean balkenAktiv = true;
private boolean gewartet = false;
private int versuche;
private View view;
private int counter = 0;

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    // inflate mainXML->
    View mainView = getLayoutInflater().inflate(R.layout.activity_game, null);
    // find container->
    LinearLayout container = (LinearLayout) mainView.findViewById(R.id.container);
    // initialize your custom view->
    view = new GameLayout(this);
    // add your custom view to container->
    container.addView(view);

    setContentView(mainView);

    versuche = leseVersuche();
    highscore = leseHighscore();
    setupActionBar();
    neueRunde();    

    Button button = (Button) findViewById(R.id.thebutton);
    button.setOnClickListener(this);
}

/**
 * Set up the {@link android.app.ActionBar}, if the API is available.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() 
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
    {
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.game, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    switch (item.getItemId()) 
    {
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void neueRunde()
{
    punkte = 0;
    refreshScreen();
}

private void refreshScreen()
{
    TextView tvPunkte = (TextView) findViewById(R.id.points);
    tvPunkte.setText("Punkte: " + Integer.toString(punkte));    

    TextView tvHighscores = (TextView) findViewById(R.id.highscores);
    tvHighscores.setText("Highscore: " + Integer.toString(highscore));

    TextView tvVersuche = (TextView) findViewById(R.id.versuches);
    tvVersuche.setText("Versuche: " + Integer.toString(versuche));
}

@Override
public void onClick(View v)
{
    if(Klick == 0)
    {
        handler.postDelayed(this, 0);
        Klick = 1;
    }
    else
    {
        if(Klick == 1)
        {   
            balkenAktiv = false;
            handler.postDelayed(this, 500);
            punkte = balken;
            versuche++;
            schreibeVersuche(versuche);
            highscore += punkte;
            schreibeHighscore(highscore);
            Klick = 2;
            refreshScreen();
        }
        else
        {
        if(Klick == 2)
            {
                Klick = 0;
                punkte = 0;
                balken = 0;
                ProgressBar proBar = (ProgressBar) findViewById(R.id.sprung);
                proBar.setProgress(balken);
                refreshScreen();
            }
        }
    }
}

@Override
public void run()
{   
    if(balkenAktiv == true)
    {
        gewartet = false;
        ProgressBar proBar = (ProgressBar) findViewById(R.id.sprung);
        if(abnehmend == false)
        {
            if(balken < 100)
            {
                balken+=5;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
            else if(balken == 100)
            {
                abnehmend = true;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
        }

        else if(abnehmend == true)
        {
            if(balken > 0)
            {
                balken-=5;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
            else if (balken == 0)
            {
                abnehmend = false;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
        }       
    }       
    else if (balkenAktiv == false)
    {       
        if(gewartet == true)
        {
            if(counter < 4)
            {
                counter++;
                view.invalidate();
                handler.postDelayed(this, 500);
            }
            else if (counter >= 4)
            {
                balkenAktiv = true;
                counter = 0;
            }
        }
        gewartet = true;
    }
}   

private void schreibeHighscore(int highscore)
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    SharedPreferences.Editor editor = pref.edit();
    editor.putInt("HIGHSCORE", highscore);
    editor.commit();
}

private void schreibeVersuche(int versuche)
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    SharedPreferences.Editor editor = pref.edit();
    editor.putInt("VERSUCHE", versuche);
    editor.commit();
}

private int leseVersuche()
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    return pref.getInt("VERSUCHE", 0);
}

private int leseHighscore()
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    return pref.getInt("HIGHSCORE", 0);
}   
}
精灵类:

public class Sprite 
{   
//private static final String TAG = Sprite.class.getSimpleName();

private Bitmap bitmap;      // the animation sequence
private Rect sourceRect;    // the rectangle to be drawn from the animation bitmap
private int frameNr;        // number of frames in animation
private int currentFrame;   // the current frame
private long frameTicker;   // the time of the last frame update
private int framePeriod;    // milliseconds between each frame (1000/fps)

private int spriteWidth;    // the width of the sprite to calculate the cut out rectangle
private int spriteHeight;   // the height of the sprite

private int x;              // the X coordinate of the object (top left of the image)
private int y;              // the Y coordinate of the object (top left of the image)

public Sprite(Bitmap bitmap, int x, int y, int width, int height, int fps, int frameCount) 
{
    this.bitmap = bitmap;
    this.x = x;
    this.y = y;
    currentFrame = 0;
    frameNr = frameCount;
    spriteWidth = bitmap.getWidth() / frameCount;
    spriteHeight = bitmap.getHeight();
    sourceRect = new Rect( 0, 0, spriteWidth, spriteHeight);
    framePeriod = 1000 / fps;
    frameTicker = 0l;
}

public void update(long gameTime) 
{
    if (gameTime > frameTicker + framePeriod) 
    {
        frameTicker = gameTime;
        // increment the frame
        currentFrame++;
        if (currentFrame >= frameNr) 
        {
            currentFrame = 0;
        }
    }
    // define the rectangle to cut out sprite
    this.sourceRect.left = currentFrame * spriteWidth;
    this.sourceRect.right = this.sourceRect.left + spriteWidth;
}

public void draw(Canvas canvas) 
{
    // where to draw the sprite
    Rect destRect = new Rect( x, y, x + spriteWidth, y + spriteHeight);
    canvas.drawBitmap(bitmap, sourceRect, destRect, null);
}
}

解决方案非常简单:

而不是在我使用的
run()
方法中使用
view.invalidate()
((GameLayout)视图)。update(System.currentTimeMillis())
因此我调用GameLayout类的
onDraw()

update()
isntead

通过此更改,我可以从我的
onDraw()
中删除
update()
方法,因此如果
onDraw()
得到更新,图片将更新,但不会更改

然后,我将
invalidate()
添加到我的
update()
方法中,以便它在更新后重新绘制自己

现在一切都很顺利

public class Sprite 
{   
//private static final String TAG = Sprite.class.getSimpleName();

private Bitmap bitmap;      // the animation sequence
private Rect sourceRect;    // the rectangle to be drawn from the animation bitmap
private int frameNr;        // number of frames in animation
private int currentFrame;   // the current frame
private long frameTicker;   // the time of the last frame update
private int framePeriod;    // milliseconds between each frame (1000/fps)

private int spriteWidth;    // the width of the sprite to calculate the cut out rectangle
private int spriteHeight;   // the height of the sprite

private int x;              // the X coordinate of the object (top left of the image)
private int y;              // the Y coordinate of the object (top left of the image)

public Sprite(Bitmap bitmap, int x, int y, int width, int height, int fps, int frameCount) 
{
    this.bitmap = bitmap;
    this.x = x;
    this.y = y;
    currentFrame = 0;
    frameNr = frameCount;
    spriteWidth = bitmap.getWidth() / frameCount;
    spriteHeight = bitmap.getHeight();
    sourceRect = new Rect( 0, 0, spriteWidth, spriteHeight);
    framePeriod = 1000 / fps;
    frameTicker = 0l;
}

public void update(long gameTime) 
{
    if (gameTime > frameTicker + framePeriod) 
    {
        frameTicker = gameTime;
        // increment the frame
        currentFrame++;
        if (currentFrame >= frameNr) 
        {
            currentFrame = 0;
        }
    }
    // define the rectangle to cut out sprite
    this.sourceRect.left = currentFrame * spriteWidth;
    this.sourceRect.right = this.sourceRect.left + spriteWidth;
}

public void draw(Canvas canvas) 
{
    // where to draw the sprite
    Rect destRect = new Rect( x, y, x + spriteWidth, y + spriteHeight);
    canvas.drawBitmap(bitmap, sourceRect, destRect, null);
}
}