Android – Comment positionner la vue hors écran?

J’essaie d’animer un simple ImageView dans mon application et je veux le faire glisser depuis le bas de l’écran et arriver à une position de repos où les 50 premiers pixels de la vue sont en haut de l’écran (par exemple la position finale). de l’ImageView devrait être -50px en X). J’ai essayé d’utiliser AbsoluteLayout pour faire cela, mais cela coupe en fait les 50px supérieurs de l’ImageView, de sorte que les 50px supérieurs ne sont jamais rendus. Je dois avoir le top 50px de l’imageView visible / rendu pendant qu’il est en train de s’animer et ensuite simplement le laisser légèrement en dehors de l’écran. J’espère que je l’ai bien expliqué.

Voici ce que j’utilise actuellement en tant que mise en page et animation de diapositives (cela ne rend pas les 50 premiers pixels de l’ImageView):

Disposition:

     

Animation:

      

Merci d’avance.

J’ai trouvé une solution facile à mettre en œuvre. Il s’agit de modifier la disposition et l’activité gonflant la mise en page … voir ci-dessous:

Activité (QuickPlay.java):

 public class QuickPlay extends Activity implements AnimationListener { private ImageView myImageView; private LinearLayout LL; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.quick_play_screen); myImageView = (ImageView) this.findViewById(R.id.Clip); LL = (LinearLayout) this.findViewById(R.id.QuickPlayClipLayout); //finally Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_in_quickplay); anim.setAnimationListener(this); LL.startAnimation(anim); } @Override public void onAnimationEnd(Animation animation){} @Override public void onAnimationRepeat(Animation animation){} @Override public void onAnimationStart(Animation animation) { // This is the key... //set the coordinates for the bounds (left, top, right, bottom) based on the offset value (50px) in a resource XML LL.layout(0, -(int)this.getResources().getDimension(R.dimen.quickplay_offset), LL.getWidth(), LL.getHeight() + (int)this.getResources().getDimension(R.dimen.quickplay_offset)); } } 

Nouveau LinearLayout (CustomLinearLayout.java):

 public class CustomLinearLayout extends LinearLayout { private Context myContext; public CustomLinearLayout(Context context, AtsortingbuteSet attrs) { super(context, attrs); myContext = context; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec+((int)myContext.getResources().getDimension(R.dimen.quickplay_offset))); } } 

Mise en page (/res/layout/quick_play_screen.xml):

      

Ressource (/res/values/constants.xml):

   50dp  

Animation (/res/anim/slide_in_quickplay.xml):

      

Le programme fait maintenant exactement ce dont j’ai besoin. La mise en page entière commence à l’écran en bas, se glisse en 1 seconde et s’arrête là où le haut de la disposition est en fait à 50 pixels du haut de l’écran (c.-à-d. LL.getTop() = -50 ) et le bas de la mise en page se trouve en bas de l’écran (c.-à-d. LL.getBottom() = 530 = 480 + 50 ).

Pour positionner ma vue hors écran, j’ai utilisé le code suivant:

 View myView = /* view you want to position offscreen */ int amountOffscreen = (int)(myView.getWidth() * 0.8); /* or whatever */ boolean offscreen = /* true or false */ int xOffset = (offscreen) ? amountOffscreen : 0; RelativeLayout.LayoutParams rlParams = (RelativeLayout.LayoutParams)myView.getLayoutParams(); rlParams.setMargins(-1*xOffset, 0, xOffset, 0); myView.setLayoutParams(rlParams); 

Ce code positionnera myView offscreen par amountOffscreen, ce qui, dans ce cas, met 80% de la vue hors écran, ne laissant que 20% à l’écran.

N’utilisez pas directement la méthode layout () – Android effectuera des appels ultérieurs pour invalider votre vue pour des raisons aléatoires et seuls les layoutParams sont conservés dans des appels invalides. Si vous êtes curieux, consultez les lignes 904 à 912 de ce fichier pour voir pourquoi vous devez modifier les layoutParams.

Au lieu de cela, nous pouvons simplement donner des valeurs négatives à layout_margin (haut / gauche / droite / bas), par exemple: si vous voulez que votre vue soit en haut de l’écran,

 android:layout_marginTop="-40dp" 

C’est facile à faire si vous devez sauter sur l’utilisation d’un Canvas ; ceux qui soutiennent dessiner l’écran sans aucun problème. Cependant, ce sera plus compliqué à mettre en œuvre. Vous devez implémenter une View personnalisée et écrire votre propre animation dans le code. Essentiellement, cela se résume à une gestion graphique simple en 2D plutôt qu’à des vues utilisant des animations XML intégrées. Il y a peut-être un moyen de le faire avec XML, mais je suis beaucoup plus familier avec les canvass. Le très bon exemple de jeu Lunar Lander fourni avec le SDK est un très bon endroit pour voir comment cela est géré dans le code.

Les étapes à suivre sont les suivantes:

  1. Placez une vue personnalisée dans le fichier XML, en utilisant quelque chose comme , en définissant sa taille sur fill-parent.

  2. Définissez ensuite une classe extends SurfaceView and implements SurfaceHolder.Callback , qui extends SurfaceView and implements SurfaceHolder.Callback . (Cela vous donne access au Canvas dessin immédiatement plutôt qu’à l’aide de la méthode invalidate() . Ceci est important car invalidate () n’est actualisé que lorsque le thread est inactif, par exemple à la fin de la boucle. le faire dessiner immédiatement.)

  3. Vous pouvez ensuite implémenter une boucle qui dessine votre image en mouvement sur l’écran. La boucle doit commencer par dessiner tout l’arrière-plan (car le canevas n’est pas automatiquement effacé), puis dessiner l’image à sa nouvelle position en fonction du temps écoulé. Par exemple, si vous voulez que votre animation prenne 1 seconde, alors vous savez que si 200ms ont passé, la vue ne devrait avoir déplacé que 200/1000, ou 1/5, de sa position de départ à la position finale. .

Vous pouvez voir quelques exemples de ce que je veux dire dans mes autres réponses aux questions d’animation: réponse de base sur l’ utilité d’utiliser SurfaceView et exemple de la boucle à utiliser . Note: la deuxième question concernait la rotation et certaines des difficultés dont j’ai parlé ne vous intéresseront pas. Bonne chance!

J’avais un groupe de discussion avec des enfants et je tirais la vue vers le bas depuis l’écran – un peu comme un tiroir. Je lâcherais alors et si la marge supérieure du groupe de vues se trouvait dans la moitié supérieure de l’écran, je l’animerais en haut après que l’utilisateur ait relâché la touche.

Lorsque cela se produisait, les images des enfants du groupe de visualisation seraient recadrées pendant l’animation, mais elles seraient affichées après l’animation.

Le problème: la hauteur de viewgroup était wrap_content. J’ai résolu ce problème en définissant la hauteur à une valeur qui s’étendait avant que l’animation ne commence.