English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Realisation de l'effet de réduction de l'image en haut du contenu de la page de détails des amis QQ Android

Ce document partage avec vous l'exemple de code spécifique pour la présentation de l'effet de zoom de l'image supérieure du bas de page Android, pour votre référence, le contenu spécifique est le suivant

Illustration

Analyse des effets

1 Faites glisser vers le bas, l'image supérieure augmente constamment de taille en suivant le déplacement du doigt

2 Faites glisser vers le haut, le déplacement continu de l'image vers le haut jusqu'à ce que l'image ne soit plus visible

3 Lorsque l'image supérieure n'est pas visible, faites glisser vers le haut, faites glisser le ListView

Approche d'implémentation

1 Étant donné que cette Vue est divisée en deux parties supérieure et inférieure, disposées verticalement, elle peut être réalisée en héritant de LinearLayout : : personnalisé une DragImageView, cette Vue hérite de LinearLayout

public DragImageView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // Par défaut, ce View est aligné verticalement
  setOrientation(LinearLayout.VERTICAL);
  // Utilisé pour coordonner le défilement en inertie de ce View
  mScroller = new OverScroller(context);
  mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
  mMaximumVelocity = ViewConfiguration.get(context)
        .getScaledMaximumFlingVelocity();
  mMinimumVelocity = ViewConfiguration.get(context)
        .getScaledMinimumFlingVelocity();
  }

2 Définir la hauteur de la vue de contenu dans onMeasure

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  LayoutParams params = (LayoutParams) getChildAt(1).getLayoutParams();
  // Le header peut être complètement caché, donc la hauteur de la vue de contenu est égale à la hauteur du contrôle
  params.height = getMeasuredHeight();
}

3 Définir l'attribut ScaleType de l'ImageView

@Override
protected void onFinishInflate() {
  super.onFinishInflate();
  imageView = (ImageView) getChildAt(0);
  // Avec le glissement du doigt, l'image s'agrandit constamment (la largeur et la hauteur sont toutes deux supérieures ou égales à la taille de l'ImageView), et est affichée au centre :
  // Selon l'analyse ci-dessus, CENTER_CROP : il est possible d'utiliser un redimensionnement équilibré de l'image (conserver les proportions d'origine de l'image), de sorte que les deux coordonnées (largeur, hauteur) de l'image soient toutes deux supérieures ou égales aux coordonnées correspondantes de la vue (marge interne négative), et que l'image soit placée au centre de la vue
  imageView.setScaleType(ScaleType.CENTER_CROP);
  listView = (ListView) getChildAt(1);
}

4 Événement d'interception

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  if (ev.getAction() == MotionEvent.ACTION_DOWN) {
    downX = (int) ev.getX();
    downY = (int) ev.getY();
  }
  if (ev.getAction() == MotionEvent.ACTION_MOVE) {
    int currentX = (int) ev.getX();
    int currentY = (int) ev.getY();
    // S'assurer que c'est un glissement vertical
    if (Math.abs(currentY - downY) > Math.abs(currentX - downX)) {
      View childView = listView.getChildAt(listView
          .getFirstVisiblePosition());
      // Il y a deux cas qui nécessitent une interception :
      // 1 L'image n'est pas complètement cachée
      // 2 L'image est complètement cachée, mais glisser vers le bas, et le ListView glisser vers le haut
      if (getScrollY() != imageHeight
          || (getScrollY() == imageHeight && currentY - downY > 0
              && childView != null && childView.getTop() == 0)) {
        initVelocityTrackerIfNotExists();
        mVelocityTracker.addMovement(ev);
        return true;
      }
    }
  }
  if (ev.getAction() == MotionEvent.ACTION_UP) {
    recycleVelocityTracker();
  }
  return super.onInterceptTouchEvent(ev);
}

5 traitement ACTION_MOVE de onTouchEvent

if (ev.getAction() == MotionEvent.ACTION_MOVE) {
    int currentX = (int) ev.getX();
    int currentY = (int) ev.getY();
    int deltyX = currentX - downX;
    int deltyY = currentY - downY;
    if (Math.abs(deltyY) > Math.abs(deltyX)) {
      if (deltyY > 0) {
        if (getScrollY() > 0) {
          if (getScrollY() - deltyY < 0) {
            scrollBy(0, -getScrollY());
            return true;
          }
          // Lorsque l'image n'est pas complètement affichée et que l'on fait glisser vers le bas, continuer tout le view pour rendre l'image visible
          scrollBy(0, -deltyY);
        }
        // Lorsque l'image est complètement affichée et que l'on fait glisser vers le bas, l'image est constamment agrandie (en changeant la hauteur de l'ImageView)
          LayoutParams layoutParams = (LayoutParams) getChildAt(0)
              .getLayoutParams();
          layoutParams.height = layoutParams.height + deltyY / 2;
          getChildAt(0).setLayoutParams(layoutParams);
        }
      }
      // Lorsque l'image est encore en état d'agrandissement et que vous faites glisser vers le haut, continuez à réduire constamment la hauteur de l'image pour réduire l'image
        if (getChildAt(1).getTop() > imageHeight) {
          LayoutParams layoutParams = (LayoutParams) getChildAt(0)
              .getLayoutParams();
          layoutParams.height = layoutParams.height + deltyY / 2;
          getChildAt(0).setLayoutParams(layoutParams);
        }
        // Lorsque l'image est en état normal et que vous faites glisser vers le haut, déplacez tout le View pour réduire la portée visible de l'image
          if (getScrollY() - deltyY > imageHeight) {
            scrollBy(0, imageHeight - getScrollY());
            return true;
          }
          scrollBy(0, -deltyY);
        }
      }
      downY = currentY;
      downX = currentX;
      return true;
    }
  }

6 traitement ACTION_UP de onTouchEvent

if (ev.getAction() == MotionEvent.ACTION_UP) {
  // Lorsque l'image est en état d'agrandissement et que vous relâchez, faites lentement l'image rétrécir pour revenir à son état d'origine
  if (getChildAt(1).getTop() > imageHeight) {
    isAnimating = true;
    ValueAnimator valueAnimator = ValueAnimator.ofInt(getChildAt(1)
        .getTop(), imageHeight);
    valueAnimator.setDuration(300);
    valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        int value = (Integer) animation.getAnimatedValue();
        LayoutParams layoutParams = (LayoutParams) getChildAt(0)
            .getLayoutParams();
        layoutParams.height = value;
        getChildAt(0).setLayoutParams(layoutParams);
      }
    });
    valueAnimator.addListener(new AnimatorListenerAdapter() {
      @Override
      public void onAnimationEnd(Animator animation) {}}
        super.onAnimationEnd(animation);
        isAnimating = false;
      }
    });
    valueAnimator.start();
  }
  // Lorsque l'image actuelle est dans un état normal, l'image n'est pas complètement cachée et que vous relâchez, si la vitesse de glissement est supérieure à la valeur minimale de glissement inertiel, laissez View produire un effet de glissement inertiel
  if (getChildAt(1).getTop() == imageHeight
      && getScrollY() != imageHeight) {
    mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
    int velocityY = (int) mVelocityTracker.getYVelocity();
    if (Math.abs(velocityY) > mMinimumVelocity) {
      fling(-velocityY);
    }
    recycleVelocityTracker();
  }

Résumé

Il y a principalement deux points d'apprentissage ici

1 Traitement du zoom sur les images, interception des événements

2 Glissement inertiel de View : principalement en combinant l'utilisation d'OverScroller

C'est tout pour cet article. J'espère que cela aidera à votre apprentissage et que vous soutiendrez également le tutoriel d'encouragement.

Déclaration : le contenu de cet article est issu du réseau, propriété de ses auteurs respectifs. Le contenu est fourni par les utilisateurs d'Internet de manière volontaire et téléchargé. Ce site ne détient pas de droits de propriété, n'a pas été édité par l'homme et n'assume aucune responsabilité juridique connexe. Si vous trouvez du contenu présumé violer les droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois confirmée, ce site supprimera immédiatement le contenu présumé enfreindre les droits d'auteur.)

Vous pourriez aussi aimer