2010-03-12 3 views
4

J'essaie de trouver un moyen de gérer correctement la mise en place d'une activité dont l'orientation est déterminée à partir des données de l'intention qui l'a lancée. C'est pour un jeu où l'utilisateur peut choisir des niveaux, dont certains sont en orientation portrait et certains sont en orientation paysage. Le problème auquel je suis confronté est que setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) ne prend pas effet tant que l'activité n'est pas complètement chargée. C'est un problème pour moi parce que je fais un peu de chargement et de traitement d'image pendant le démarrage, ce que j'aimerais faire une seule fois.Modification de l'orientation de l'écran pendant le démarrage de l'activité.

Actuellement, si l'utilisateur a choisi un niveau de paysage:

  • l'activité commence onCreate(), par défaut portrait
  • découvre d'analyser son lancement intention qu'il devrait être en orientation paysage
  • continue à tout moment jusqu'à onResume(), le chargement des informations et l'exécution d'autres tâches de configuration
  • à ce stade setRequestedOrientation intervient pour que l'application passe par onPause() à onDestroy()
  • il commence alors à nouveau à partir onCreate() et fonctionne à onResume() répéter la configuration du début

Y at-il un moyen d'éviter cela et ne l'ont pas effectuer le chargement deux fois? Par exemple, idéalement, l'activité devrait savoir avant même que onCreate ait été appelé, qu'il s'agisse de paysage ou de portrait en fonction de certaines propriétés de l'intention de lancement, mais à moins que j'aie manqué quelque chose qui n'est pas possible. J'ai réussi à hacker ensemble un moyen d'éviter de répéter le chargement en vérifiant un boolean avant les étapes de chargement fastidieuses, mais cela ne semble pas être la bonne façon de le faire. J'imagine que je pourrais remplacer onSaveInstanceState, mais cela nécessiterait beaucoup de codage supplémentaire. Y a-t-il un moyen simple de le faire?

Merci!


Solution:

Selon la réponse de Daniel, cela était en fait assez facile à corriger. J'avais juste besoin de faire quelques petits changements. Dans mon activité "menu", où le joueur choisirait quel niveau jouer, je devais juste ajouter un contrôle if/else pour choisir quelle classe serait lancée par mon intention. Cela a été fait avec un simple int représentant portrait ou paysage, déterminé lorsque le joueur a sélectionné un niveau. J'ai ensuite créé une seconde classe en étendant ma classe 'GameLogic'; c'est la classe qui contient la majeure partie du code pour le jeu lui-même, plutôt que les menus, les instructions, etc.

public class GameLandscape extends GameLogic{ 
} 

littéralement aussi simple que cela et complètement vide. De cette façon, il a hérité de tout le code de mon activité précédente où je l'avais déjà codé pour gérer les choses différemment en fonction de l'orientation. Enfin, je devais simplement ajouter une ligne au manifeste indiquant que GameLandscape fonctionnerait toujours en mode paysage et que GameLogic fonctionnerait toujours en mode portrait.

Donc, un problème simple en effet.

Répondre

6

Vous pouvez créer deux activités, l'une pour les niveaux portrait, l'autre pour les niveaux de paysage, puis définir l'orientation de l'activité dans AndroidManifest.xml à l'aide de l'attribut android:screenOrientation. Vous n'aurez même pas à dupliquer le code si vous utilisez l'héritage; utilisez votre activité actuelle comme activité de base, et créez simplement les activités paysage/portrait en tant que sous-classes de cette activité.

Je pense qu'une meilleure solution serait pour l'intention d'ouvrir l'activité correcte de ces deux, mais si vous devez avoir tout routé via l'analyse supplémentaire d'intention, vous pouvez transférer tous les niveaux à une troisième activité qui ne fait rien de plus analyser l'intention et ensuite la transmettre à l'activité appropriée.

+0

C'est une bonne idée, merci. Je vais essayer. (Je ne suis pas sûr de la façon dont j'aurais besoin d'une troisième activité - oui, j'ai besoin de traiter l'Intention pour obtenir d'autres informations stockées dans les extras, mais ce code existe déjà dans mon activité de toute façon. une 3ème activité pour choisir lequel l'envoyer, alors je pourrais juste faire cela en stockant l'orientation dans les extras pour commencer.Qu'est-ce que je comprends mal cette partie de votre réponse?: P) –

+0

Eh bien, vous avez dit comment vous utilisez l'intention de déterminer s'il faut être en mode paysage ou portrait. Si vous avez vraiment besoin de faire cela, vous pouvez utiliser une 3ème activité pour l'analyser puis l'envoyer. Mais, comme je l'ai dit, la meilleure solution serait que l'intention appelle simplement la bonne orientation en premier lieu. (Désolé si ma réponse est un peu confuse). –

+0

Cela a fonctionné un régal et était mort simple à mettre en œuvre. Détails ajoutés ci-dessous ma question pour quelqu'un d'autre qui a le même problème. –

2

Vous pouvez également remplacer onRetainNonConfigurationInstance(). Cela vous permet de stocker temporairement un élément que vous pouvez récupérer en appelant le getLastNonConfigurationInstance(). De cette façon, vous pouvez charger tout ce dont vous avez besoin et dans votre méthode onRetainNonConfigurationInstance() vous pouvez tout enregistrer dans une structure de données et le renvoyer. Le onCreate()onCreate() vous pouvez appeler getLastNonConfigurationInstance() et si cela renvoie la charge de null, charger tous vos trucs, si cela retourne quelque chose, alors vous avez tout chargé. Voici un exemple rapide:

public class MyActivity extends Activity 
{ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     DataStructure myData = (DataStructure)getLastNonConfigurationInstance(); 
     if(myData == null) 
     { 
      // Load everything in 
     } 
     else 
     { 
      // Unpack myData 
     } 
    } 

    @Override 
    public Object onRetainNonConfigurationInstance() 
    { 
     DataStructure myData = new DataStructure(); 
     // Put everything in to myData 
     return myData; 
    } 
} 
+0

Ah oui, j'avais oublié l'onRetainNonConfigurationInstance, mais cette solution semble globalement similaire à la substitution de onSaveInstanceState. Les deux nécessiteraient un peu de travail pour m'assurer que j'ai correctement sauvegardé tout. La solution de Daniel ci-dessus est tellement plus facile à faire, c'est pourquoi je l'ai choisi. –

+0

C'est la façon correcte de faire ce genre de chose quand vous avez besoin de faire un pré-traitement une fois. – MrSnowflake

Questions connexes