libGDX警报对话框

pla*_*irt 8 android libgdx android-alertdialog

我使用过以下代码:

 AlertDialog.Builder bld;

 if (android.os.Build.VERSION.SDK_INT <= 10) {
     //With default theme looks perfect:
     bld = new AlertDialog.Builder(AndroidLauncher.this);
 } else {
     //With Holo theme appears the double Dialog:
     bld = new AlertDialog.Builder(AndroidLauncher.this, android.R.style.Theme_Holo_Dialog_MinWidth);
 }

 bld.setIcon(R.drawable.ic_launcher);
 bld.setTitle("Exit");
 bld.setMessage("Are you sure you want to exit?");
 bld.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); }
 });
 bld.setPositiveButton("Exit", new DialogInterface.OnClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) { finish(); }
 });
 bld.setCancelable(false);
 bld.create().show();
Run Code Online (Sandbox Code Playgroud)

看起来很好,但它说"导入android.app.AlertDialog无法解决".它是Android Studio中的标准libGDX项目.

Dro*_*ter 12

在libgdx中,您应该使用scene2d对话框而不是本机Android DialogInterface.下面是如何使用自定义按钮图像和背景图像向libgdx中的舞台添加完全蒙皮的对话框.您只需要替换自己的背景和按钮图像纹理和字体,然后在准备好显示对话框时调用quitGameConfirm()...

import com.badlogic.gdx.scenes.scene2d.ui.Dialog;

public void quitGameConfirm() {

    LabelStyle style = new LabelStyle(_fontChat, Color.WHITE);
    Label label1 = new Label("Are you sure that you want to exit?", style);
    label1.setAlignment(Align.center);
    //style.font.setScale(1, -1);
    style.fontColor = Color.WHITE;

    Skin tileSkin = new Skin();
    Texture tex = new Texture(myButtontexture);
    tex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    tileSkin.add("white", tex);
    tileSkin.add("default", new BitmapFont());

    TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
    textButtonStyle.up = tileSkin.newDrawable("white");
    textButtonStyle.down = tileSkin.newDrawable("white", Color.DARK_GRAY);
    textButtonStyle.checked = tileSkin.newDrawable("white",
            Color.LIGHT_GRAY);
    textButtonStyle.over = tileSkin.newDrawable("white", Color.LIGHT_GRAY);
    textButtonStyle.font = _myTextBitmapFont;
    textButtonStyle.font.setScale(1, -1);
    textButtonStyle.fontColor = Color.WHITE;
    tileSkin.add("default", textButtonStyle);

    TextButton btnYes = new TextButton("Exit", tileSkin);
    TextButton btnNo = new TextButton("Cancel", tileSkin);

    // /////////////////
    Skin skinDialog = new Skin(Gdx.files.internal("data/uiskin.json"));
    final Dialog dialog = new Dialog("", skinDialog) {
        @Override
        public float getPrefWidth() {
            // force dialog width
            // return Gdx.graphics.getWidth() / 2;
            return 700f;
        }

        @Override
        public float getPrefHeight() {
            // force dialog height
            // return Gdx.graphics.getWidth() / 2;
            return 400f;
        }
    };
    dialog.setModal(true);
    dialog.setMovable(false);
    dialog.setResizable(false);

    btnYes.addListener(new InputListener() {
        @Override
        public boolean touchDown(InputEvent event, float x, float y,
                int pointer, int button) {

            // Do whatever here for exit button

            _parent.changeState("StateMenu");
            dialog.hide();
            dialog.cancel();
            dialog.remove();                

            return true;
        }

    });

    btnNo.addListener(new InputListener() {
        @Override
        public boolean touchDown(InputEvent event, float x, float y,
                int pointer, int button) {

            //Do whatever here for cancel

            dialog.cancel();
            dialog.hide();

            return true;
        }

    });

    TextureRegion myTex = new TextureRegion(_dialogBackgroundTextureRegion);
    myTex.flip(false, true);
    myTex.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
    Drawable drawable = new TextureRegionDrawable(myTex);
    dialog.setBackground(drawable);

    float btnSize = 80f;
    Table t = new Table();
    // t.debug();

    dialog.getContentTable().add(label1).padTop(40f);

    t.add(btnYes).width(btnSize).height(btnSize);
    t.add(btnNo).width(btnSize).height(btnSize);

    dialog.getButtonTable().add(t).center().padBottom(80f);
    dialog.show(stage).setPosition(
            (MyGame.VIRTUAL_WIDTH / 2) - (720 / 2),
            (MyGame.VIRTUAL_HEIGHT) - (MyGame.VIRTUAL_HEIGHT - 40));

    dialog.setName("quitDialog");
    stage.addActor(dialog);

}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


z3n*_*105 6

问题是您正在尝试创建一个Android小部件,但我怀疑您是在Libgdx核心实现中进行的。核心实现没有对Android SDK的任何引用。

那是因为继承核心项目的是Android项目。结果,核心项目不知道加载到Android实现的任何依赖项。

为了克服这个问题,您需要在Android项目和Core Project之间创建一个接口。这样您就可以在Android Project中调用方法。必须在核心项目内部创建接口,以便两个项目都可以访问该接口。

例如,您在核心Project中创建CrossPlatformInterface.java。但是首先让我们创建一个回调,以从Libgdx线程内的Ui线程获取反馈。重要的是要记住,Libgdx具有与Android主线程不同的线程!!!如果尝试从Libgdx线程运行Android的Widget,则应用程序将崩溃。

让我们为AlertDialog进行回调。我将在此处建议一个Abstract类,以便能够仅覆盖所需的方法,因为有时Alertdialog可以具有1,2或3个按钮。

在核心项目中创建AlertDialogCallback.java:

public abstract class AlertDialogCallback{

    public abstract void positiveButtonPressed();
    public void negativeButtonPressed(){}; // This will not be required
    public void cancelled(){}; // This will not be required

}
Run Code Online (Sandbox Code Playgroud)

在Core Project中,还创建CrossPlatformInterface.java:

public interface CrossPlatformInterface{
    public void showAlertDialog(AlertDialogCallback callback);
}
Run Code Online (Sandbox Code Playgroud)

您会注意到,在showAlertDialog方法中,我们传递了回调以在按下按钮时获得反馈!

然后,您在Android项目中创建一个将实现CrossPlatformInterface的类,如下所示:

public ClassInsideAndroidProject implements CrossPlatFormInterface{

   private AndroidLauncher mActivity; // This is the main android activity

   public ClassInsideAndroidProject(AndroidLauncher mActivity){
        this.mActivity = mActivity;
   }
   public void showAlertDialog(final AlertDialogCallback callback){

      mainActivity.runOnUiThread(new Runnable(){

        @Override
        public void run() {

            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
            builder.setTitle("Test");
            builder.setMessage("Testing");
            builder.setPositiveButton("OKAY", new OnClickListener(){

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    callback.positiveButtonPressed();

                }   
            });
            builder.setNegativeButton(negativeButtonString, new OnClickListener(){

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    callback.negativeButtonPressed();

                }

            });

            AlertDialog dialog = builder.create();
            dialog.show();
        }
    });
   }
}
Run Code Online (Sandbox Code Playgroud)

重要笔记

  1. 如下所示,CrossPlatformInterface将在MainActivity(AndroidLauncher)内部实例化。
  2. AlertDialog将在android UI线程内创建。因为我们来自Libgdx线程来创建AlertDialog,所以我们需要使用runOnUiThread来确保AlertDialog是在ui线程中创建的。

最后如何执行此操作:

在Android主Activity中实例化CrossPlatform接口,并将Activity传递给在MyGdxGame内部传递的Interface实例:

public class MainActivity extends AndroidApplication {

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

    AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
            cfg.useGL20 = false;

    initialize(new MyGdxGame(new ClassInsideAndroidProject(this)), cfg);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,当创建MyGDxGame时,我们获得了跨平台接口的实例,并且可以将所需的任何函数调用给android ui线程。

public class MyGdxGame extends Game {

ClassInsideAndroidProject crossPlatformInterface;

public MyGdxGame(ClassInsideAndroidProject crossPlatformInterface){
     this.crossPlatformInterface = crossPlatformInterface;
}

@Override
public void create() {

    crossPlatformInterface.showAlertDialog(new AlertDialogCallback(){

       @Override
       public void positiveButtonPressed(){

       //IMPORTANT TO RUN inside this method the callback from the ui thread because we want everything now to run on libgdx thread! this method ensures that.
          Gdx.app.postRunnable(new Runnable().....) 

       }
       @Override
       public void negativeButtonPressed(){

       }; // This will not be required
       @Override
       public void cancelled(){

        }; // This will not be required
    });
}

@Override
public void render() {
    super.render();
}

public void dispose() {
    super.dispose();
}

public void pause() {
    super.pause();
}
}
Run Code Online (Sandbox Code Playgroud)

我认为这是我最初打算写的东西。它可能看起来令人生畏,但实际上相当简单。在完成之后,一切看起来都变得简单了:)。这样做的好处是,在您创建此接口后,对Android小部件的任何调用都将非常简单且线程安全。

希望它能提供良好的画面。

  • 同样,scene2d为此拥有自己的一组小部件,因此我强烈不建议在libgdx项目中使用本机警报对话框。很好的说明和界面介绍,但对于警报对话框而言,这样做毫无意义。 (3认同)