我使用过以下代码:
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();
看起来很好,但它说&#34;导入android.app.AlertDialog无法解决&#34;。 它是Android Studio中的标准libGDX项目。
答案 0 :(得分:11)
在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);
}
答案 1 :(得分:4)
问题是你正在尝试创建一个Android小部件,我怀疑你是在Libgdx-core实现中做的。核心实现没有任何Android SDK参考。
那是因为它是继承核心项目的Android项目。因此,核心项目不知道加载到Android实现的任何依赖项。
要解决此问题,您需要在Android项目和Core Project之间创建一个接口。这将允许您调用Android项目中的方法。 必须在核心项目内创建接口,以便两个项目都可以访问它。
例如,您在核心Project中创建了CrossPlatformInterface.java。但首先让我们创建一个回调来从Libgdx线程中的Ui线程获得反馈。 重要的是要记住,Libgdx有一个独立的线程,Android主线程!!! 如果你试图从Libgdx线程运行Android的Widgets,应用程序将会粉碎。
让我们为AlertDialog进行回调。我将在这里建议一个Abstract类,以便只能覆盖你想要的方法,因为有时Alertdialog可以有1,2或3个按钮。
在Core Project中创建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
}
在Core Project中还创建了CrossPlatformInterface.java:
public interface CrossPlatformInterface{
public void showAlertDialog(AlertDialogCallback callback);
}
您注意到在showAlertDialog方法中,我们传递回调以在按下按钮时获得反馈!
然后在Android项目中创建一个Class,它将实现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();
}
});
}
}
重要提示
最后如何执行此操作:
在Android main 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);
}
}
最后,当创建MyGDxGame时,我们得到了crossplatform接口的实例,我们可以调用我们想要的任何函数到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();
}
}
我认为这是我第一次打算写的更多。它可能看起来令人生畏,但实际上相当简单。在你完成它之后,一切看起来都比较简单:)。 这项工作的优点是在你创建这个界面后,任何对android小部件的调用都将非常容易和线程安全。
希望它能给出一幅好照片。
答案 2 :(得分:1)
这可行(已测试)。只需传入FragmentActivity或Activity即可 通过你的游戏构造函数。你必须传递一些东西(比如 ClassInsideAndroidProject)。为什么不传递一个非常有用的元素!。
//---------------------------------------------------------------------------
/** 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's 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
//--------------------------------------------------------------------------------