English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
This article shares the specific code for displaying the Android pull-down top image zoom effect with everyone for reference, the specific content is as follows
Effect Diagram
Effect Analysis
1 Slide down, the top image keeps getting larger as the finger slides
2 Slide up continuously, moving the image upwards until the image is not visible
3 When the top image is not visible, slide up, sliding ListView
Implementation Ideas
1 As this View is divided into two parts, upper and lower, vertically aligned, it can be implemented by inheriting LinearLayout: Define a custom DragImageView, which inherits LinearLayout
public DragImageView(Context context, AttributeSet attrs) { super(context, attrs); // Default the View to be vertically arranged setOrientation(LinearLayout.VERTICAL); // Used to cooperate with handling the inertia 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 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: It can use an even zoom image (keep the original image ratio), so that the two coordinates (width, height) of the image are greater than or equal to the corresponding view coordinates (negative inner padding), and the image is centered in 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(); // Ensure it is a vertical swipe if (Math.abs(currentY - downY) > Math.abs(currentX - downX)) { View childView = listView.getChildAt(listView .getFirstVisiblePosition()); // There are two cases that need to be intercepted: // 1 The image is not completely hidden // 2 The image is completely hidden, but scrolled down and the ListView is scrolled to the top 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's ACTION_MOVE handling
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; } // When the image is not fully displayed and scrolled down, continue the entire view to make the image visible scrollBy(0, -deltyY); } // When the image is fully displayed and scrolled down, the image is continuously zoomed in by changing the height of the ImageView LayoutParams layoutParams = (LayoutParams) getChildAt(0) .getLayoutParams(); layoutParams.height = layoutParams.height + deltyY / 2; getChildAt(0).setLayoutParams(layoutParams); } } // When the image is still in the zoomed state and sliding up, continue to gradually reduce the height of the image to make the image smaller if (getChildAt(1).getTop() > imageHeight) { LayoutParams layoutParams = (LayoutParams) getChildAt(0) .getLayoutParams(); layoutParams.height = layoutParams.height + deltyY / 2; getChildAt(0).setLayoutParams(layoutParams); } // When the image is in the normal state and sliding up, move the entire View to reduce the visible range of the image if (getScrollY() - deltyY > imageHeight) { scrollBy(0, imageHeight - getScrollY()); return true; } scrollBy(0, -deltyY); } } downY = currentY; downX = currentX; return true; } }
6 ACTION_UP handling of onTouchEvent
if (ev.getAction() == MotionEvent.ACTION_UP) { // When the image is in the zoomed state, release it to slowly return the image to its original state 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(); } // When the current image is in a normal state, and the image is not completely hidden, and the sliding speed is greater than the minimum inertia sliding value when the hand is released, let the View produce an inertia sliding effect if (getChildAt(1).getTop() == imageHeight && getScrollY() != imageHeight) { mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityY = (int) mVelocityTracker.getYVelocity(); if (Math.abs(velocityY) > mMinimumVelocity) { fling(-velocityY); } recycleVelocityTracker(); }
Summary
There are mainly two learning points here
1 Handling of image zoom, event interception
2 Inertia sliding of View: mainly combined with the use of OverScroller
That's all for this article. I hope it will be helpful to everyone's learning, and I also hope everyone will support the Yelling Tutorial more.
Declaration: The content of this article is from the Internet, the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, does not edit the content manually, and does not assume any relevant legal responsibility. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email for reporting. Provide relevant evidence, and once verified, this site will immediately delete the infringing content.)