Das Problem, dass Sie ist versuchen, ein Android-Widget zu erstellen, von dem ich vermute, dass es in der Libgdx-Core-Implementierung geschieht. Die Kernimplementierung enthält keine Verweise auf Android SDK.
Das ist, weil es das Android-Projekt ist, das das Kernprojekt erbt. Daher sind dem Basisprojekt keine Abhängigkeiten bekannt, die in die Android-Implementierung geladen werden.
Um dies zu überwinden Sie benötigen eine Schnittstelle zwischen Android-Projekt und Kernprojekt zu erstellen. Dadurch können Sie Methoden innerhalb des Android-Projekts aufrufen. Die Schnittstelle muss innerhalb des Kernprojekts erstellt werden, damit beide Projekte darauf zugreifen können.
Zum Beispiel erstellen Sie CrossPlatformInterface.java im Kernprojekt. Aber lasst uns zuerst einen Callback erstellen, um Feedback vom Ui-Thread innerhalb des Libgdx-Threads zu erhalten. Es ist wichtig sich daran zu erinnern, dass Libgdx einen separaten Thread für das Android-Hauptthread hat !!! Wenn Sie versuchen, Widgets von Android aus Libgdx-Threads auszuführen, wird die Anwendung vernichtet.
Lassen Sie uns den Rückruf für den AlertDialog machen. Ich werde hier eine Abstract-Klasse vorschlagen, um nur die gewünschten Methoden überschreiben zu können, da Alertdialog manchmal 1,2 oder 3 Buttons haben kann.
Im Kernprojekt erstellen 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
}
Im Kernprojekt erstellen auch CrossPlatformInterface.java:
public interface CrossPlatformInterface{
public void showAlertDialog(AlertDialogCallback callback);
}
Sie bemerken, dass in der showAlertDialog Methode, die wir den Rückruf erhalten Feedback übergeben, wenn Tasten werden gedrückt!
Sie dann eine Klasse innerhalb Android-Projekt erstellen, das die CrossPlatformInterface wie umsetzen:
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();
}
});
}
}
Wichtige Hinweise
- Die CrossPlatformInterface wird innerhalb der MainActivity (AndroidLauncher) instanziiert werden, wie Sie werden siehe unten.
- Der AlertDialog wird im Android-UI-Thread erstellt. Da wir aus dem Libgdx-Thread kommen, um den AlertDialog zu erstellen, müssen wir runOnUiThread verwenden, um sicherzustellen, dass der AlertDialog in ui thread erstellt wird.
Schließlich, wie dies auszuführen:
Instantiate Crossplatform-Schnittstelle innerhalb Android Haupt-Aktivität und die Aktivität an der Schnittstelle Instanz übergeben, die im Inneren des MyGdxGame geleitet wird:
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);
}
}
Schließlich, wenn die MyGDxGame ist erstellt wir bekommen die Instanz der Crossplatform-Schnittstelle und wir können alle Funktionen, die wir wollen, die Android-Ui-Thread aufrufen.
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();
}
}
Ich denke, es war viel mehr Schreiben, das ich zuerst beabsichtigte. Es mag entmutigend aussehen, aber eigentlich ist es ziemlich einfach. Gut nachdem du es getan hast, sieht alles einfacher aus :). Der Vorteil dieser Bemühungen ist, nachdem Sie diese Schnittstelle jeden Aufruf von Android-Widget machen wird sehr einfach und Thread sicher.
Hoffe es gibt ein gutes Bild.
Dies ist, was ich auch tun würde. Aber um ehrlich zu sein, es ist ein Albtraum! Schau dir den Code an. Ist es fair, all das für ein Popup einzugeben? – Arash
Es ist sehr kompliziert, hat viele Abhängigkeiten, Importe, die nicht gelöst werden können. Gibt es eine einfachere Lösung? – plaidshirt
Sie können alle Haut in JSON-Datei speichern. Finde einfach ein paar Tutorials. Der Code wird viel weniger sein. ;) – Aleksandrs