LibGDX alert dialog

I used the following code:

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(); 

It seems good, but he says: "import android.app.AlertDialog cannot solve." This is a standard libGDX project in Android Studio.

+6
source share
3 answers

In libgdx, you should use the scene2d dialog instead of the native Android DialogInterface. Below you can add a completely smooth dialog to the scene in libgdx with custom button images and a background image. You just need to replace your own background and the texture and font of the button image, and then call quitGameConfirm () when you are ready to display the dialog ...

 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); } 

enter image description here

+10
source

The problem is that you are trying to create an Android widget, which I suspect you are doing in the implementation of Libgdx-core. In the main implementation, there are no links to the Android SDK.

This is because it is an Android project that inherits the main project. As a result, the main project is not aware of any dependencies loaded into the Android implementation.

To overcome this, you need to create an interface between the Android project and the Core Project. This will allow you to call methods inside an Android project. The interface must be created inside the main project so that both projects have access to it.

For example, you create CrossPlatformInterface.java inside the main project. But first let me create a callback to get the feedback from the Ui stream inside the Libgdx stream. It is important to remember that Libgdx has a separate thread, the main Android thread. . If you try to launch Widgets of Android from Libgdx streams, the application will be crushed.

Let me make a callback for AlertDialog. I propose here an abstract class to be able to redefine only those methods that you need, because sometimes Alertdialog can have 1,2 or 3 buttons.

In the main project, create 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 } 

CrossPlatformInterface.java is also created in the Core Project:

 public interface CrossPlatformInterface{ public void showAlertDialog(AlertDialogCallback callback); } 

You have noticed that in the showAlertDialog method, we pass a callback to receive feedback when buttons are clicked.

Then you create a class project inside Android that will implement CrossPlatformInterface, for example:

 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(); } }); } } 

Important notes

  • CrossPlatformInterface will be created inside MainActivity (AndroidLauncher), as you will see below.
  • AlertDialog will be created in the Android UI thread. Since we get the Libgdx thread to create the AlertDialog, we need to use runOnUiThread to ensure that the AlertDialog is created in the ui thread.

Finally, how to do it:

Create the CrossPlatform interface inside the main Android operation and pass the Activity instance to the interface that is passed inside MyGdxGame:

 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); } } 

Finally, when MyGDxGame is created, we get an instance of the cross-platform interface, and we can call any functions we want to use for the android ui stream.

 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(); } } 

I think it was a lot more letters that I first intended. It may seem complicated, but actually quite simple. Well, after you have done this, everything looks simpler :). The advantage of this effort is that after you make this interface, any call to the Android widget will be a very simple and safe thread.

Hope this gives a good picture.

+3
source

It works (verified). Just go to FragmentActivity or Activity through your game constructor. You must pass something (e.g. ClassInsideAndroidProject). Why not go into a really useful item!

 //--------------------------------------------------------------------------- /** 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 */ public static void showCustomDialog(final FragmentActivity fa) //or Activity { fa.runOnUiThread(new Runnable() { // boolean[] info; @Override public void run() { LinearLayout ll_Main = new LinearLayout(fa); LinearLayout ll_Row01 = new LinearLayout(fa); LinearLayout ll_Row02 = new LinearLayout(fa); LinearLayout ll_Row09 = new LinearLayout(fa); LinearLayout ll_Row10 = new LinearLayout(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); final CheckBox checkBox = new CheckBox(fa); final CheckBox cb_debug = new CheckBox(fa); final EditText et_User = new EditText(fa); final EditText et_Pass = new EditText(fa); TextView tv_Check = new TextView(fa); TextView tv_Debug = new TextView(fa); TextView tv_User = new TextView(fa); TextView tv_Pass = new TextView(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.Builder alert = new AlertDialog.Builder(fa);//this.getActivity() alert.setTitle("Camera settings"); alert.setView(ll_Main); alert.setCancelable(false); alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(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 on libgdx thread!. Gdx.app.postRunnable( new Runnable() { public void run() { //do something with the data Gdx.app.log("INFO", "**** positiveButtonPressed works here ****"); }//run });//postRunnable }//onClick });//setPositiveButton alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); }//setPositiveButton });//setNegativeButton AlertDialog dialog = alert.create(); dialog.show(); }//run });//runOnUiThread }//showCustomDialog //-------------------------------------------------------------------------------- 
+1
source

Source: https://habr.com/ru/post/984008/


All Articles