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