Skip to content Skip to sidebar Skip to footer

Libgdx Alert Dialog

I have used code below: AlertDialog.Builder bld; if (android.os.Build.VERSION.SDK_INT <= 10) { //With default theme looks perfect: bld = new AlertDialog.Builder(And

Solution 1:

In libgdx you should use a scene2d dialog instead of the native Android DialogInterface. Below is how you would add a completely skinned dialog to the stage in libgdx with custom button images and background image. You would just need to substitute your own background and button image textures and font, then call quitGameConfirm() when you're ready to display the dialog...

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

publicvoidquitGameConfirm() {

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

    SkintileSkin=newSkin();
    Texturetex=newTexture(myButtontexture);
    tex.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    tileSkin.add("white", tex);
    tileSkin.add("default", newBitmapFont());

    TextButton.TextButtonStyletextButtonStyle=newTextButton.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);

    TextButtonbtnYes=newTextButton("Exit", tileSkin);
    TextButtonbtnNo=newTextButton("Cancel", tileSkin);

    // /////////////////SkinskinDialog=newSkin(Gdx.files.internal("data/uiskin.json"));
    finalDialogdialog=newDialog("", skinDialog) {
        @OverridepublicfloatgetPrefWidth() {
            // force dialog width// return Gdx.graphics.getWidth() / 2;return700f;
        }

        @OverridepublicfloatgetPrefHeight() {
            // force dialog height// return Gdx.graphics.getWidth() / 2;return400f;
        }
    };
    dialog.setModal(true);
    dialog.setMovable(false);
    dialog.setResizable(false);

    btnYes.addListener(newInputListener() {
        @OverridepublicbooleantouchDown(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();                

            returntrue;
        }

    });

    btnNo.addListener(newInputListener() {
        @OverridepublicbooleantouchDown(InputEvent event, float x, float y,
                int pointer, int button) {

            //Do whatever here for cancel

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

            returntrue;
        }

    });

    TextureRegionmyTex=newTextureRegion(_dialogBackgroundTextureRegion);
    myTex.flip(false, true);
    myTex.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
    Drawabledrawable=newTextureRegionDrawable(myTex);
    dialog.setBackground(drawable);

    floatbtnSize=80f;
    Tablet=newTable();
    // 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);

}

enter image description here

Solution 2:

The problem is that you are trying to create an Android widget which I suspect you are doing it in the Libgdx-core implementation. The core implementation does not have any references to Android SDK.

That is because it is the Android project which inherits the core project. As a result the core project is not aware of any dependencies loaded to the Android implementation.

To overcome this you need to create an interface between Android project and Core Project. That will allow you to call methods inside the Android Project. The interface must be created inside the core Project in order for both projects to have access to it.

For example you create CrossPlatformInterface.java inside core Project. But first let's create a callback to get feedback from the Ui Thread inside the Libgdx Thread. It is important to remember that Libgdx has a seperate thread that Android main thread!!! If you try to run Widgets of Android from Libgdx threads the Application will crush.

Let's make the callback for the AlertDialog. I will suggest an Abstract class here in order to be able to override only the methods you want because sometimes Alertdialog can have 1,2 or 3 buttons.

In Core Project create AlertDialogCallback.java:

publicabstractclassAlertDialogCallback{

    publicabstractvoidpositiveButtonPressed();
    publicvoidnegativeButtonPressed(){}; // This will not be requiredpublicvoidcancelled(){}; // This will not be required

}

In Core Project also create CrossPlatformInterface.java:

publicinterfaceCrossPlatformInterface{
    publicvoidshowAlertDialog(AlertDialogCallback callback);
}

You notice that in the showAlertDialog method we pass the callback to get feedback when buttons are pressed!

Then you create a Class inside Android project that will implement the CrossPlatformInterface like:

public ClassInsideAndroidProject implementsCrossPlatFormInterface{

   private AndroidLauncher mActivity; // This is the main android activitypublicClassInsideAndroidProject(AndroidLauncher mActivity){
        this.mActivity = mActivity;
   }
   publicvoidshowAlertDialog(final AlertDialogCallback callback){

      mainActivity.runOnUiThread(newRunnable(){

        @Overridepublicvoidrun() {

            AlertDialog.Builderbuilder=newAlertDialog.Builder(mActivity);
            builder.setTitle("Test");
            builder.setMessage("Testing");
            builder.setPositiveButton("OKAY", newOnClickListener(){

                @OverridepublicvoidonClick(DialogInterface dialog, int which) {

                    callback.positiveButtonPressed();

                }   
            });
            builder.setNegativeButton(negativeButtonString, newOnClickListener(){

                @OverridepublicvoidonClick(DialogInterface dialog, int which) {

                    callback.negativeButtonPressed();

                }

            });

            AlertDialogdialog= builder.create();
            dialog.show();
        }
    });
   }
}

Important notes

  1. The CrossPlatformInterface will be instantiated inside the MainActivity (AndroidLauncher) as you will see below.
  2. The AlertDialog will be created inside the android UI thread. Because we are coming from the Libgdx thread to create the AlertDialog we need to use runOnUiThread to ensure the AlertDialog is created in ui thread.

Finally how to execute this:

Instantiate CrossPlatform interface inside Android main Activity and pass the Activity to the Interface instance which is passed inside the MyGdxGame:

publicclassMainActivityextendsAndroidApplication {

    @OverridepublicvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AndroidApplicationConfigurationcfg=newAndroidApplicationConfiguration();
            cfg.useGL20 = false;

    initialize(newMyGdxGame(newClassInsideAndroidProject(this)), cfg);
    }
}

Finally when the MyGDxGame is created we get the instance of the crossplatform interface and we can the call any functions we want to the android ui thread.

publicclassMyGdxGameextendsGame {

ClassInsideAndroidProject crossPlatformInterface;

publicMyGdxGame(ClassInsideAndroidProject crossPlatformInterface){
     this.crossPlatformInterface = crossPlatformInterface;
}

@Overridepublicvoidcreate() {

    crossPlatformInterface.showAlertDialog(newAlertDialogCallback(){

       @OverridepublicvoidpositiveButtonPressed(){

       //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(newRunnable().....) 

       }
       @OverridepublicvoidnegativeButtonPressed(){

       }; // This will not be required@Overridepublicvoidcancelled(){

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

@Overridepublicvoidrender() {
    super.render();
}

publicvoiddispose() {
    super.dispose();
}

publicvoidpause() {
    super.pause();
}
}

I think it was much more writing I first intended. It might look daunting but actually is fairly simple. Well after you've done it everything looks simpler :). The advantage of this effort is after you make this interface any call to android widget will be very easy and thread safe.

Hope it gives a good picture.

Solution 3:

This works (tested). Simply pass in the FragmentActivity or Activity via your game constructor. You have to pass something in (like ClassInsideAndroidProject). Why not pass in a really useful element !.

//---------------------------------------------------------------------------/**  INSIDE the libgdc core, create a custom NATIVE android dialog
         * :- breaks the rules somewhat for the core,
         *  but if you ONLY using Android, why not use android Native!
         *   @member_var  private final FragmentActivity m_fa; 
         * @constructor public xx_your_app_xx(FragmentActivity m_fa) 
         *{
         *  this.m_fa = m_fa;
         *}
         *  @called_with if(m_fa != null) showCustomDialog(m_fa);
         * @param fa
         */publicstaticvoidshowCustomDialog(final FragmentActivity fa)//or Activity 
        {
            fa.runOnUiThread(newRunnable()
            {
    //          boolean[] info;@Overridepublicvoidrun()
                {
                    LinearLayoutll_Main=newLinearLayout(fa);
                    LinearLayoutll_Row01=newLinearLayout(fa);
                    LinearLayoutll_Row02=newLinearLayout(fa);
                    LinearLayoutll_Row09=newLinearLayout(fa);
                    LinearLayoutll_Row10=newLinearLayout(fa);

                    ll_Main.setOrientation(LinearLayout.VERTICAL);
                    ll_Row01.setOrientation(LinearLayout.HORIZONTAL);
                    ll_Row02.setOrientation(LinearLayout.HORIZONTAL);
                    ll_Row09.setOrientation(LinearLayout.HORIZONTAL);
                    ll_Row10.setOrientation(LinearLayout.HORIZONTAL);

                    finalCheckBoxcheckBox=newCheckBox(fa);
                    finalCheckBoxcb_debug=newCheckBox(fa);
                    finalEditTextet_User=newEditText(fa);
                    finalEditTextet_Pass=newEditText(fa);

                    TextViewtv_Check=newTextView(fa);
                    TextViewtv_Debug=newTextView(fa);
                    TextViewtv_User=newTextView(fa);
                    TextViewtv_Pass=newTextView(fa);

                    tv_Check.setText("rotation lock: ");
                    tv_Debug.setText("debug: ");
                    tv_User.setText("Username: ");
                    tv_Pass.setText("Password: ");

                    ll_Row01.addView(tv_Check);
                    ll_Row01.addView(checkBox);

                    ll_Row02.addView(tv_Debug);
                    ll_Row02.addView(cb_debug);

                    ll_Row09.addView(tv_User);
                    ll_Row09.addView(et_User);

                    ll_Row10.addView(tv_Pass);
                    ll_Row10.addView(et_Pass);

                    ll_Main.addView(ll_Row01);
                    ll_Main.addView(ll_Row02);
    //              ll_Main.addView(ll_Row09);//              ll_Main.addView(ll_Row10);

                    AlertDialog.Builderalert=newAlertDialog.Builder(fa);//this.getActivity()
                    alert.setTitle("Camera settings");
                    alert.setView(ll_Main);
                    alert.setCancelable(false);
                    alert.setPositiveButton("Ok", newDialogInterface.OnClickListener() 
                    {
                        @OverridepublicvoidonClick(DialogInterface dialog, int which) 
                        {
    //                      info1[0] = checkBox.isChecked();//                      info1[1] = cb_debug.isChecked();//                      String user = et_User.getText().toString();//                      String pass = et_Pass.getText().toString();//do something with the data
                            Gdx.app.log("INFO", "**** positiveButtonPressed works here too! ***");
                            Toast.makeText(fa,
                                    "checkBox: " + checkBox.isChecked() +
                                    ", cb_debug: " + cb_debug.isChecked(),
                                    Toast.LENGTH_LONG).show();
                            //IMPORTANT TO RUN inside this {} means everything now  run's on libgdx thread!.
                            Gdx.app.postRunnable( newRunnable() 
                               {
                                    publicvoidrun() 
                                    {
                                        //do something with the data
                                        Gdx.app.log("INFO", "**** positiveButtonPressed works here ****");
                                    }//run
                                });//postRunnable
                        }//onClick
                    });//setPositiveButton
                    alert.setNegativeButton("Cancel", newDialogInterface.OnClickListener() 
                    {   
                        @OverridepublicvoidonClick(DialogInterface dialog, int which) 
                        {
                            dialog.dismiss();
                        }//setPositiveButton
                    });//setNegativeButtonAlertDialogdialog= alert.create();
                    dialog.show();
                }//run
            });//runOnUiThread
        }//showCustomDialog//--------------------------------------------------------------------------------

Post a Comment for "Libgdx Alert Dialog"