Gestionner gracieusement le changement d'orientation d'écran pendant le début de l'activité

StackOverflow https://stackoverflow.com/questions/2434071

Question

J'essaie de trouver un moyen de gérer correctement la configuration d'une activité où son orientation est déterminée à partir des données dans l'intention qui l'a lancée. Ceci est pour un jeu où l'utilisateur peut choisir des niveaux, dont certains sont l'orientation INT Portrait et certains sont l'orientation du 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 entièrement chargée. C'est un problème pour moi car je fais du chargement et du traitement d'image pendant le démarrage, ce que je voudrais ne devoir faire qu'une seule fois.

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

  • L'activité commence sur onCreate (), défautant vers le portrait
  • découvre l'analyse de son intention de lancement qu'il devrait être dans l'orientation du paysage
  • Continue indépendamment de tout le chemin vers ONRESUME (), le chargement des informations et l'exécution d'autres tâches de configuration
  • À ce stade, SetRequeted Oorientation entre en marche afin que l'application passe via onPause () à onDestroy ()
  • Il recommence ensuite à partir d'OnCreate () et fonctionne sur onResume () répétant la configuration plus tôt

Existe-t-il un moyen d'éviter cela et de ne pas effectuer le chargement deux fois? Par exemple, idéalement, l'activité le saurait avant même que le fait de ce qu'il soit appelé, qu'il s'agisse d'un paysage ou d'un 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 à pirater ensemble un moyen d'éviter de répéter le chargement en vérifiant un boolean Avant les étapes de chargement qui prennent du temps, mais cela ne semble pas être la bonne façon de le faire. J'imagine que je pourrais l'emporter onSaveInstanceState, mais cela nécessiterait beaucoup de codage supplémentaire. Y a-t-il un moyen simple de le faire?

Merci!


La solution:

Selon la réponse de Daniel, c'était en fait assez facile à réparer. J'avais juste besoin de faire quelques petits changements. Dans mon activité «menu», où le joueur choisirait le niveau à jouer, je devais juste ajouter un chèque d'IF / autre pour choisir quelle classe serait démarrée par mon intention. Cela a été fait avec un INT simple représentant un portrait ou un paysage, déterminé lorsque le joueur a sélectionné un niveau. J'ai ensuite créé une deuxième classe étendant ma classe «gamelogic»; C'est la classe qui contenait la plupart du code du jeu lui-même, plutôt que les menus, les instructions, etc.

public class GameLandscape extends GameLogic{
}

Littéralement aussi simple 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 juste ajouter une ligne au manifeste indiquant que GamelandScape serait toujours en paysage, et Gamelogic fonctionnerait toujours dans le portrait.

Donc un simple problème en effet.

Était-ce utile?

La solution

Vous pouvez faire deux activités - l'une pour les niveaux de portrait, l'autre pour les niveaux de paysage - puis définir l'orientation de l'activité dans AndroidManifest.xml, en utilisant le android:screenOrientation attribut. 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 comme sous-classes de cette activité.

Je pense qu'une meilleure solution serait pour l'intention d'ouvrir la bonne activité de ces deux, mais si vous devez tout être acheminé via une analyse supplémentaire, vous pouvez transmettre tous les niveaux à une troisième activité qui ne fait rien de plus que d'analyser l'intention et Ensuite, transmettez-le à l'activité appropriée.

Autres conseils

Vous pouvez également remplacer onRetainNonConfigurationInstance(). Cela vous permet de stocker temporairement un article que vous pouvez récupérer en appelant getLastNonConfigurationInstance(). De cette façon, vous pouvez charger toutes les choses dont vous avez besoin et dans votre onRetainNonConfigurationInstance() Méthode Vous pouvez tout enregistrer dans une structure de données et les renvoyer. Le dans votre onCreate() tu peux appeler getLastNonConfigurationInstance() Et si cela renvoie une charge nul, chargez toutes vos affaires, si cela renvoie quelque chose, 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;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top