Android仿QQ好友詳情頁下拉頂部圖片縮放效果

Android仿QQ好友詳情頁下拉頂部圖片縮放效果
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

本文例項為大家分享了Android下拉頂部圖片縮放效果展示的具體程式碼,供大家參考,具體內容如下

效果圖

效果分析

1 向下滑動,頭部的圖片隨著手指滑動不斷變大

2 向上滑動,不斷的向上移動圖片,直到圖片不可見

3 當頂部圖片不可見時,向上滑動,滑動ListView

實現思路

1 由於這個View分上下兩部分,垂直排列,可以通過繼承LinearLayout實現::自定義一個DragImageView,該View繼承LinearLayout


public DragImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// 預設該View垂直排列
setOrientation(LinearLayout.VERTICAL);
// 用於配合處理該View的慣性滑動
mScroller = new OverScroller(context);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mMaximumVelocity = ViewConfiguration.get(context)
.getScaledMaximumFlingVelocity();
mMinimumVelocity = ViewConfiguration.get(context)
.getScaledMinimumFlingVelocity();
}

2 onMeasure中設定內容檢視的高度


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
LayoutParams params = (LayoutParams) getChildAt(1).getLayoutParams();
// 頭部可以全部隱藏,所以內容檢視的高度即為該控制元件的高度
params.height = getMeasuredHeight();
}

3 設定ImageView的ScaleType屬性


@Override
protected void onFinishInflate() {
super.onFinishInflate();
imageView = (ImageView) getChildAt(0);
// 隨著手指滑動,圖片不斷放大(寬高都大於或者等於ImageView的大小),並居中顯示:
// 根據上邊的分析,CENTER_CROP:可以使用均衡的縮放影象(保持影象原始比例),使圖片的兩個座標(寬、高)都大於等於 相應的檢視座標(負的內邊距),影象則位於檢視的中央
imageView.setScaleType(ScaleType.CENTER_CROP);
listView = (ListView) getChildAt(1);
}

4 事件攔截


@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();
// 確保是垂直滑動
if (Math.abs(currentY - downY) > Math.abs(currentX - downX)) {
View childView = listView.getChildAt(listView
.getFirstVisiblePosition());
// 有兩種情況需要攔截:
// 1 圖片沒有完全隱藏
// 2 圖片完全隱藏,但是向下滑動,並且ListView滑動到頂部
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處理


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;
}
// 當圖片沒有完全顯示,並且向下滑動時,繼續整個view使圖片可見
scrollBy(0, -deltyY);
} else {
// 當圖片完全顯示,並且向下滑動時,則不斷的放大圖片(通過改變ImageView)的高度
LayoutParams layoutParams = (LayoutParams) getChildAt(0)
.getLayoutParams();
layoutParams.height = layoutParams.height   deltyY / 2;
getChildAt(0).setLayoutParams(layoutParams);
}
} else {
// 當圖片還處於放大狀態,並且向上滑動時,繼續不斷的縮小圖片的高度,使圖片縮小
if (getChildAt(1).getTop() > imageHeight) {
LayoutParams layoutParams = (LayoutParams) getChildAt(0)
.getLayoutParams();
layoutParams.height = layoutParams.height   deltyY / 2;
getChildAt(0).setLayoutParams(layoutParams);
} else {
// 當圖片處於正常狀態,並且向上滑動時,移動整個View,縮小圖片的可見範圍
if (getScrollY() - deltyY > imageHeight) {
scrollBy(0, imageHeight - getScrollY());
return true;
}
scrollBy(0, -deltyY);
}
}
downY = currentY;
downX = currentX;
return true;
}
}

6 onTouchEvent的ACTION_UP處理


if (ev.getAction() == MotionEvent.ACTION_UP) {
// 當圖片處於放大狀態時鬆手,使圖片緩慢的縮回到原來的狀態
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的使用

相關文章

Android 開發 最新文章