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

Android, um das Vergrößern des oberen Bildes beim Ziehen der Freundesdetailsseite von QQ nachzuahmen

Dieser Artikel teilt den spezifischen Code für die Anzeigeeffekt von Android, bei dem das obere Bild beim Ziehen vergrößert wird, mit Ihnen, für Ihre Referenz, die spezifische Inhalte sind wie folgt

Effektbild

Effektanalyse

1 Scrollen Sie nach unten, das obere Bild vergrößert sich kontinuierlich mit dem Finger

2 Scrollen Sie nach oben, bewegen Sie das Bild ständig nach oben, bis das Bild unsichtbar ist

3 Wenn das obere Bild unsichtbar ist, scrollen Sie nach oben, scrollen Sie die ListView

Implementierungsansatz

1 Da da dieser View in zwei Teile geteilt ist, vertikal angeordnet, kann durch Vererbung von LinearLayout realisiert werden: Ein benutzerdefinierter DragImageView, der von LinearLayout abgeleitet ist

public DragImageView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // The default view is vertically arranged
  setOrientation(LinearLayout.VERTICAL);
  // Used to cooperate with the handling of the inertial sliding of this View
  mScroller = new OverScroller(context);
  mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
  mMaximumVelocity = ViewConfiguration.get(context)
        .getScaledMaximumFlingVelocity();
  mMinimumVelocity = ViewConfiguration.get(context)
        .getScaledMinimumFlingVelocity();
  }

2 Set the height of the content view in onMeasure

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  LayoutParams params = (LayoutParams) getChildAt(1).getLayoutParams();
  // The header can be completely hidden, so the height of the content view is equal to the height of the control
  params.height = getMeasuredHeight();
}

3 Set the ScaleType attribute of ImageView

@Override
protected void onFinishInflate() {
  super.onFinishInflate();
  imageView = (ImageView) getChildAt(0);
  // As the finger slides, the picture keeps zooming in (both width and height are greater than or equal to the size of ImageView), and it is displayed in the center:
  // According to the analysis above, CENTER_CROP: You can use an even zoom of the image (keeping the original image ratio), so that the two coordinates (width, height) of the image are all greater than or equal to the corresponding view coordinates (negative inner padding), and the image is located in the center of the view
  imageView.setScaleType(ScaleType.CENTER_CROP);
  listView = (ListView) getChildAt(1);
}

4 Event 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();
    // Stellen Sie sicher, dass es sich um einen vertikalen Swipe handelt
    if (Math.abs(currentY - downY) > Math.abs(currentX - downX)) {
      View childView = listView.getChildAt(listView
          .getFirstVisiblePosition());
      // Es gibt zwei Fälle, die abgefangen werden müssen:
      // 1 Das Bild ist nicht vollständig versteckt
      // 2 Das Bild ist vollständig versteckt, aber nach unten gescrollt und der ListView scrollt auf den obersten Punkt
      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 onTouchEvent-ACTION_MOVE-Verarbeitung

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;
          }
          // Wenn das Bild nicht vollständig angezeigt wird und nach unten gescrollt wird, wird die gesamte View fortgesetzt, damit das Bild sichtbar wird
          scrollBy(0, -deltyY);
        } else {
        // Wenn das Bild vollständig angezeigt wird und nach unten gescrollt wird, wird das Bild ständig vergrößert (durch Ändern der Höhe des ImageView)
          LayoutParams layoutParams = (LayoutParams) getChildAt(0)
              .getLayoutParams();
          layoutParams.height = layoutParams.height + deltyY / 2;
          getChildAt(0).setLayoutParams(layoutParams);
        }
      } else {
      // Wenn das Bild immer noch im Vergrößerungsmodus ist und nach oben gestrichen wird, verkleinern Sie kontinuierlich die Höhe des Bildes, damit das Bild kleiner wird
        if (getChildAt(1).getTop() > imageHeight) {
          LayoutParams layoutParams = (LayoutParams) getChildAt(0)
              .getLayoutParams();
          layoutParams.height = layoutParams.height + deltyY / 2;
          getChildAt(0).setLayoutParams(layoutParams);
        } else {
        // Wenn das Bild im Normalzustand ist und nach oben gestrichen wird, bewegen Sie den gesamten View und verkleinern Sie den sichtbaren Bereich des Bildes
          if (getScrollY() - deltyY > imageHeight) {
            scrollBy(0, imageHeight - getScrollY());
            return true;
          }
          scrollBy(0, -deltyY);
        }
      }
      downY = currentY;
      downX = currentX;
      return true;
    }
  }

6 Verarbeitung von ACTION_UP in onTouchEvent

if (ev.getAction() == MotionEvent.ACTION_UP) {
  // Wenn das Bild im Vergrößerungsmodus ist, lassen Sie los, damit das Bild langsam in den ursprünglichen Zustand zurückziehen kann
  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();
  }
  // 当现在图片处于正常状态,并且图片没有完全隐藏,并且松手时滑动的速度大于可惯性滑动的最小值,让View产生惯性滑动效果
  if (getChildAt(1).getTop() == imageHeight
      && getScrollY() != imageHeight) {
    mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
    int velocityY = (int) mVelocityTracker.getYVelocity();
    if (Math.abs(velocityY) > mMinimumVelocity) {
      fling(-velocityY);
    }
    recycleVelocityTracker();
  }

总结

这里主要有两个学习的点

1 图片缩放的处理,事件的拦截

2 View的惯性滑动:主要是结合OverScroller的使用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

声明:本文内容来源于网络,版权归原作者所有。内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#oldtoolbag.com(在发邮件时,请将#更换为@进行举报,并提供相关证据。一经查实,本站将立即删除涉嫌侵权内容。)

Vermutlich gefällt Ihnen