66 votes

Android - Comment positionner View hors écran?

Je suis en train d'animer un simple ImageView dans mon application et je veux le faire glisser à partir du bas de l'écran et d'en venir à une position de repos où le haut 50px de la vue est en haut de l'écran (par exemple, la position finale de l'ImageView devrait être -50px en X). J'ai essayé d'utiliser le AbsoluteLayout pour ce faire, mais cela coupe le haut de 50px de l'ImageView tels que le haut 50px est jamais rendu. J'ai besoin d'avoir le dessus 50px de l'ImageView visible/rendu alors que c'est de l'animation et puis il suffit de le faire venir à un reste légèrement hors de l'écran. J'espère que je vous ai expliqué que suffisamment bien.

Voici ce que j'utilise actuellement pour la mise en page et de le glisser dans l'animation (actuellement, cela ne rend pas le top 50px de l'ImageView):

Mise en page:

<?xml version="1.0" encoding="utf-8"?>
   <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_height="fill_parent" 
      android:layout_width="fill_parent" 
      android:id="@+id/QuickPlayClipLayout">
      <ImageView android:id="@+id/Clip"
         android:background="@drawable/clip" 
         android:layout_width="fill_parent" 
         android:layout_height="wrap_content" 
         android:layout_y="-50dp">
      </ImageView>
   </AbsoluteLayout>

Animation:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
   <translate android:fromYDelta="100%p" 
       android:toYDelta="0"
       android:duration="1000"/>
   <alpha android:fromAlpha="0.0" 
       android:toAlpha="1.0"
       android:duration="1000" />
</set>

Merci à l'avance.

33voto

RyanM Points 3099

J'ai trouvé une solution à ce qui devrait être facile à mettre en œuvre. Il implique la modification de l'agencement et de l'Activité de gonflage de la mise en page... voir ci-dessous:

L'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, AttributeSet 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):

<?xml version="1.0" encoding="utf-8"?>
   <com.games.mygame.CustomLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_height="fill_parent" 
      android:layout_width="fill_parent" 
      android:id="@+id/QuickPlayClipLayout">
      <ImageView android:id="@+id/Clip"
         android:background="@drawable/clip" 
         android:layout_width="fill_parent" 
         android:layout_height="wrap_content">
      </ImageView>
   </com.games.mygame.CustomLinearLayout>

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

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="quickplay_offset">50dp</dimen>
</resources>

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

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
   <translate android:fromYDelta="100%p" 
       android:toYDelta="0"
       android:duration="1000"/>
   <alpha android:fromAlpha="0.0" 
       android:toAlpha="1.0"
       android:duration="1000" />
</set>

Le programme fait exactement ce que je dois faire. Toute la mise en page commence hors de l'écran, au fond, de diapositives en en 1 s et atteint une position de repos où le haut de la mise en page est en fait 50px en haut de l'écran (c'est à dire LL.getTop() = -50) et le bas de la mise en page est posé au bas de l'écran (c'est à dire LL.getBottom() = 530 = 480 + 50).

30voto

esilver Points 7768

Pour la position de mon point de vue à l'é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 sera à la position de mavue à l'écran par amountOffscreen, qui dans ce cas met 80% de l'affichage à l'écran ne laissant que 20% à l'écran.

Ne pas utiliser la mise en page() la méthode directement Android fera suite à des appels à l'annulation de votre vue pour des raisons aléatoires et seulement layoutParams sont conservées à travers invalider les appels. Si vous êtes curieux, découvrez les lignes de 904 à 912 de ce fichier pour voir pourquoi vous devez modifier le layoutParams.

9voto

Steve Haley Points 26928

C'est facile à faire si vous faites sauter à l'aide d'un Canvas; ceux de soutien de dessin hors de l'écran sans aucun problème. Cependant, il sera plus compliqué à mettre en œuvre. Vous aurez besoin de mettre en œuvre une coutume View et écrire votre propre animation dans le code. Essentiellement, cela se résume à de simples graphiques 2D à la manipulation plutôt que de Vues à l'aide de XML intégré animations. Il y a peut être un moyen de le faire avec le XML, mais je suis beaucoup plus familier avec des toiles. Un très bon endroit pour voir comment c'est traité dans le code est le Lunar Lander jeu de l'exemple fourni avec le SDK.

À peu près les étapes que vous devez suivre sont:

  1. Mettre un affichage personnalisé dans le fichier XML, en utilisant quelque chose comme <your.package.AnimatingView>, définissant sa taille à remplir-parent.

  2. Puis de définir une AnimatingView classe, qui extends SurfaceView and implements SurfaceHolder.Callback. (Cela vous donne accès à l'élaboration Canvas immédiatement plutôt que par l'utilisation de l' invalidate() méthode. Ceci est important parce que invalidate() actualise uniquement lorsque le thread est inactif, par exemple, à la fin de la boucle. Pour mettre en œuvre votre animation, vous devez avoir le dessin immédiatement.)

  3. Vous pouvez ensuite mettre en œuvre une boucle qui attire votre image en mouvement à travers l'écran. La boucle doit commencer par le dessin de l'ensemble de fond (parce que la toile n'est pas automatiquement effacés) puis dessiner l'image à sa nouvelle position en se basant sur le temps qui a passé. Par exemple, si vous voulez que votre animation de prendre 1 seconde à faire, alors vous savez que si 200ms ont passé, la vue ne devrait avoir déplacé 200/1000, ou 1/5, de la voie à partir de sa position initiale à la position finale.

Vous pouvez voir quelques exemples de ce que je veux dire dans mes autres réponses à l'animation des questions de base: réponse au sujet de l' utilité de l'aide de SurfaceView et et exemple de la boucle à utiliser. Remarque: la deuxième question portait sur la rotation, et donc certaines des difficultés que j'ai parlé de ne pas être pertinentes pour vous. Bonne chance!

2voto

AIQB Points 101

J'ai eu un viewgroup avec les enfants et a été en faisant glisser le point de vue sur l'écran, vers le bas, un peu comme un tiroir. Je puis laisser aller, et si le viewgroup haut de marge dans la moitié supérieure de l'écran, je voudrais animer vers le haut après que l'utilisateur a relâché la touche.

Lorsque cela s'est produit les images dans la viewgroup enfants pourraient obtenir recadrée au cours de l'animation, mais serait alors apparaissent après l'animation.

Le problème: viewgroup de hauteur a été wrap_content. J'ai résolu ce problème en définissant la hauteur d'une valeur qui s'étendait hors de l'écran avant de l'animation a commencé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X