Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Como criar um dialog em um SurfaceView

Galera, boa noite. Estou adicionando novas funcionalidades no flappy bird que é ensinado em um curso de Android, mas me surgiu uma dúvida: Ao detectar o game over, tem algum modo de eu conseguir subir um alertdialog ou botões para ver se o usuário quer reiniciar o jogo ou sair dele? já pesquisei muito na internet mas não achei nenhuma resposta ou algo que me serviu.

Segue o código da tela em anexo.

Obrigado

package com.example.aidan.jumper.engine;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import com.example.aidan.jumper.R;
import com.example.aidan.jumper.activities.RecordesActivity;
import com.example.aidan.jumper.dao.RecordesDAO;
import com.example.aidan.jumper.elements.Cano;
import com.example.aidan.jumper.elements.Canos;
import com.example.aidan.jumper.elements.GameOver;
import com.example.aidan.jumper.elements.Passaro;
import com.example.aidan.jumper.elements.Pontuacao;
import com.example.aidan.jumper.graphics.Tela;

/**
 * Created by Aidan on 8/21/2017.
 */

public class Game extends SurfaceView implements Runnable,View.OnTouchListener{
    private boolean isRunning = true;
    private SurfaceHolder holder = getHolder();
    private Passaro passaro;
    private Canos canos;
    private Bitmap background;
    private Tela tela;
    private Pontuacao pontuacao;
    private Som som;
    private Context context;
    private boolean somLigado;
    private AlertDialog.Builder alert;

    public Game(Context context, boolean somLigado) {
        super(context);
        tela = new Tela(context);
        som = new Som(context);
        this.somLigado = somLigado;
        this.context = context;
        inicializaElementos();
        setOnTouchListener(this);
    }

    private void inicializaElementos() {
        passaro = new Passaro(tela,context,som,this.somLigado);
        pontuacao = new Pontuacao(som,somLigado);
        canos = new Canos(tela,pontuacao,context);


        Bitmap back = BitmapFactory.decodeResource(getResources(), R.drawable.background);
        background = Bitmap.createScaledBitmap(back, back.getWidth(),tela.getAltura(),false);
    }

    @Override
    public void run() {
        while(isRunning){
            if(!holder.getSurface().isValid()){
                continue;
            }

            Canvas canvas = holder.lockCanvas();
            canvas.drawBitmap(background,0,0,null);
            passaro.desenhaNoCanvas(canvas);
            passaro.cai();

            canos.desenhaNoCanvas(canvas);
            canos.move();

            pontuacao.desenhaNoCanvas(canvas);

            if(new VerificadorDeColisao(passaro,canos).temColisao()){
                if(somLigado){
                    som.tocaSom(Som.gameover);
                }
                new GameOver(tela).desenhaNoCanvas(canvas);
                isRunning = false;
                verificaRecorde();
                Intent intent = new Intent(context,RecordesActivity.class);
            }

            holder.unlockCanvasAndPost(canvas);
        }
    }

    private void chamaDialog() {
        alert = new AlertDialog.Builder(context);
        alert.setTitle("Perdeu");
        alert.setIcon(R.mipmap.ic_launcher);
        alert.setMessage("Mensagem");
        alert.setCancelable(false);
        alert.setNegativeButton("Sair do jogo", new DialogInterface.OnClickListener(){

            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Toast.makeText(context,"Saindo do jogo",Toast.LENGTH_SHORT).show();
            }
        });
        alert.setPositiveButton("Jogar novamente", new DialogInterface.OnClickListener(){

            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Toast.makeText(context,"Iniciando novo jogo",Toast.LENGTH_SHORT).show();
            }
        });
        AlertDialog alertDialog = alert.create();
        alertDialog.show();
    }

    private void verificaRecorde() {
        RecordesDAO dao = new RecordesDAO(context);
        if(dao.verificaNovoRecorde(pontuacao.getPontuacao())){
            dao.insere(pontuacao.getPontuacao());
        }
        dao.close();
    }

    public void inicia() {
        isRunning = true;
    }

    public void pausa() {
        isRunning = false;
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        passaro.pula();
        return false;
    }
}
1 resposta
solução!

Olá Aidan,

A única restrição ao uso do AlertDialog nesse caso é a necessidade de mostrar o dialog na thread principal do Android. Para fazer isso basta fazer um ajuste no final do seu método chamaDialog(), mais especificamente na parte que você cria o AlertDialog:

        postDelayed(new Runnable() {
            @Override
            public void run() {
                AlertDialog alertDialog = alert.create();
                alertDialog.show();
            }
        }, 100);

Com esta alteração, estamos pedindo para executar o código de criação do dialog na thread principal da aplicação. Assim o Android não derruba a aplicação.