300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Android PullToZoomListView实现放大回弹效果

Android PullToZoomListView实现放大回弹效果

时间:2022-11-10 21:50:31

相关推荐

Android PullToZoomListView实现放大回弹效果

版本号:1.0日期:.8.4版权:© kince 转载注明出处

之前看过一篇文章,链接是:能够下拉缩放HeaderView的ListView:PullToZoomInListView。

说的就是PullToZoomListView。只是这篇文章有个地方须要勘误,就是PullToZoomListView这个控件尽管是github上一个开源项目。只是最美应用并非使用这个开源项目,而是这个开源项目反编译了最美应用的代码。

可是,它这个代码是有问题的,当手指在屏幕上滑动的时候会引发onItemClick事件。

看了一下它的代码。发现是由于在onTouchEvent()方法中的MotionEvent.ACTION_MOVE中return true了,这样就会消费这个事件。所以导致了onItemClick事件。

之后我也反编译了一下最美应用,看了一下这个控件的实现,发现还有其它问题,比方少了一些变量,没有重写onInterceptTouchEvent()方法等。因此我又自己动手把这个控件丰富了一下。使其能够最大限度的接近原始代码。并且可正常使用。改动后代码例如以下:

package com.kince.android.pulltozoomlistview;import android.app.Activity;import android.content.Context;import android.os.SystemClock;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.MotionEvent;import android.view.ViewGroup;import android.view.animation.Interpolator;import android.widget.AbsListView;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.ListView;public class PullToZoomListView extends ListView implementsAbsListView.OnScrollListener {private static final int INVALID_VALUE = -1;private static final String TAG = "PullToZoomListView";private static final Interpolator sInterpolator = new Interpolator() {public float getInterpolation(float paramAnonymousFloat) {float f = paramAnonymousFloat - 1.0F;return 1.0F + f * (f * (f * (f * f)));}};int mActivePointerId = -1;private FrameLayout mHeaderContainer;private int mHeaderHeight;private ImageView mHeaderImage;float mLastMotionY = -1.0F;float mLastScale = -1.0F;float mMaxScale = -1.0F;private AbsListView.OnScrollListener mOnScrollListener;private ScalingRunnalable mScalingRunnalable;private int mScreenHeight;private ImageView mShadow;private boolean mScrollable = true;private boolean mShowHeaderImage = true;private boolean mZoomable = true;public PullToZoomListView(Context paramContext) {super(paramContext);init(paramContext);}public PullToZoomListView(Context paramContext,AttributeSet paramAttributeSet) {super(paramContext, paramAttributeSet);init(paramContext);}public PullToZoomListView(Context paramContext,AttributeSet paramAttributeSet, int paramInt) {super(paramContext, paramAttributeSet, paramInt);init(paramContext);}private void endScraling() {if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight)Log.d("mmm", "endScraling");this.mScalingRunnalable.startAnimation(200L);}private void init(Context paramContext) {DisplayMetrics localDisplayMetrics = new DisplayMetrics();((Activity) paramContext).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);this.mScreenHeight = localDisplayMetrics.heightPixels;this.mHeaderContainer = new FrameLayout(paramContext);this.mHeaderImage = new ImageView(paramContext);int i = localDisplayMetrics.widthPixels;setHeaderViewSize(i, (int) (9.0F * (i / 16.0F)));this.mShadow = new ImageView(paramContext);FrameLayout.LayoutParams localLayoutParams = new FrameLayout.LayoutParams(-1, -2);localLayoutParams.gravity = 80;this.mShadow.setLayoutParams(localLayoutParams);this.mHeaderContainer.addView(this.mHeaderImage);this.mHeaderContainer.addView(this.mShadow);addHeaderView(this.mHeaderContainer);this.mScalingRunnalable = new ScalingRunnalable();super.setOnScrollListener(this);}private void onSecondaryPointerUp(MotionEvent paramMotionEvent) {int i = (paramMotionEvent.getAction()) >> 8;Log.d("onSecondaryPointerUp", i + "");if (paramMotionEvent.getPointerId(i) == this.mActivePointerId)if (i != 0) {this.mLastMotionY = paramMotionEvent.getY(1);this.mActivePointerId = paramMotionEvent.getPointerId(0);return;}}private void reset() {this.mActivePointerId = -1;this.mLastMotionY = -1.0F;this.mMaxScale = -1.0F;this.mLastScale = -1.0F;}public ImageView getHeaderView() {return this.mHeaderImage;}public void hideHeaderImage() {this.mShowHeaderImage = false;this.mZoomable = false;this.mScrollable = false;removeHeaderView(this.mHeaderContainer);}public boolean isScrollable() {return this.mScrollable;}public boolean isZoomable() {return this.mZoomable;}public boolean onInterceptTouchEvent(MotionEvent paramMotionEvent) {if (!this.mZoomable) {return super.onInterceptTouchEvent(paramMotionEvent);}switch (paramMotionEvent.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:this.mActivePointerId = paramMotionEvent.getPointerId(0);this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);break;case MotionEvent.ACTION_UP:reset();break;case MotionEvent.ACTION_POINTER_DOWN:this.mActivePointerId = paramMotionEvent.getPointerId(paramMotionEvent.getActionIndex());break;case MotionEvent.ACTION_POINTER_UP:onSecondaryPointerUp(paramMotionEvent);break;}return super.onInterceptTouchEvent(paramMotionEvent);}protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2,int paramInt3, int paramInt4) {super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);if (this.mHeaderHeight == 0)this.mHeaderHeight = this.mHeaderContainer.getHeight();}@Overridepublic void onScroll(AbsListView paramAbsListView, int paramInt1,int paramInt2, int paramInt3) {if (this.mScrollable) {Log.d(TAG, "onScroll");float f = this.mHeaderHeight - this.mHeaderContainer.getBottom();Log.d("onScroll", "f|" + f);if ((f > 0.0F) && (f < this.mHeaderHeight)) {Log.d("onScroll", "1");int i = (int) (0.65D * f);this.mHeaderImage.scrollTo(0, -i);} else if (this.mHeaderImage.getScrollY() != 0) {Log.d("onScroll", "2");this.mHeaderImage.scrollTo(0, 0);}}if (this.mOnScrollListener != null) {this.mOnScrollListener.onScroll(paramAbsListView, paramInt1,paramInt2, paramInt3);}}public void onScrollStateChanged(AbsListView paramAbsListView, int paramInt) {if (this.mOnScrollListener != null)this.mOnScrollListener.onScrollStateChanged(paramAbsListView,paramInt);}public boolean onTouchEvent(MotionEvent ev) {Log.d(TAG, "" + (0xFF & ev.getAction()));if (!this.mZoomable) {Log.i("zoom", "zoom");return super.onTouchEvent(ev);}switch (ev.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_OUTSIDE:case MotionEvent.ACTION_DOWN:if (!this.mScalingRunnalable.mIsFinished) {this.mScalingRunnalable.abortAnimation();}this.mLastMotionY = ev.getY();this.mActivePointerId = ev.getPointerId(0);this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);this.mLastScale = (this.mHeaderContainer.getBottom() / this.mHeaderHeight);break;case MotionEvent.ACTION_MOVE:Log.d("onTouchEvent", "mActivePointerId" + mActivePointerId);int j = ev.findPointerIndex(this.mActivePointerId);if (j == -1) {Log.e("PullToZoomListView", "Invalid pointerId="+ this.mActivePointerId + " in onTouchEvent");} else {if (this.mLastMotionY == -1.0F)this.mLastMotionY = ev.getY(j);if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight) {ViewGroup.LayoutParams localLayoutParams = this.mHeaderContainer.getLayoutParams();float f = ((ev.getY(j) - this.mLastMotionY + this.mHeaderContainer.getBottom()) / this.mHeaderHeight - this.mLastScale)/ 2.0F + this.mLastScale;if ((this.mLastScale <= 1.0D) && (f < this.mLastScale)) {localLayoutParams.height = this.mHeaderHeight;this.mHeaderContainer.setLayoutParams(localLayoutParams);}this.mLastScale = Math.min(Math.max(f, 1.0F),this.mMaxScale);localLayoutParams.height = ((int) (this.mHeaderHeight * this.mLastScale));if (localLayoutParams.height < this.mScreenHeight)this.mHeaderContainer.setLayoutParams(localLayoutParams);this.mLastMotionY = ev.getY(j);}this.mLastMotionY = ev.getY(j);}break;case MotionEvent.ACTION_UP:reset();endScraling();break;case MotionEvent.ACTION_CANCEL:break;case MotionEvent.ACTION_POINTER_DOWN:int i = ev.getActionIndex();this.mLastMotionY = ev.getY(i);this.mActivePointerId = ev.getPointerId(i);break;case MotionEvent.ACTION_POINTER_UP:onSecondaryPointerUp(ev);this.mLastMotionY = ev.getY(ev.findPointerIndex(this.mActivePointerId));break;}return super.onTouchEvent(ev);}public void setHeaderViewSize(int paramInt1, int paramInt2) {if (!this.mShowHeaderImage) {return;}Object localObject = this.mHeaderContainer.getLayoutParams();if (localObject == null)localObject = new AbsListView.LayoutParams(paramInt1, paramInt2);((ViewGroup.LayoutParams) localObject).width = paramInt1;((ViewGroup.LayoutParams) localObject).height = paramInt2;this.mHeaderContainer.setLayoutParams((ViewGroup.LayoutParams) localObject);this.mHeaderHeight = paramInt2;}public void setOnScrollListener(AbsListView.OnScrollListener paramOnScrollListener) {this.mOnScrollListener = paramOnScrollListener;}public void setScrollable(boolean paramBoolean) {if (!this.mShowHeaderImage) {return;}this.mScrollable = paramBoolean;}public void setShadow(int paramInt) {if (!this.mShowHeaderImage) {return;}this.mShadow.setBackgroundResource(paramInt);}public void setZoomable(boolean paramBoolean) {if (!this.mShowHeaderImage) {return;}this.mZoomable = paramBoolean;}class ScalingRunnalable implements Runnable {long mDuration;boolean mIsFinished = true;float mScale;long mStartTime;ScalingRunnalable() {}public void abortAnimation() {this.mIsFinished = true;}public boolean isFinished() {return this.mIsFinished;}public void run() {float f2;ViewGroup.LayoutParams localLayoutParams;if ((!this.mIsFinished) && (this.mScale > 1.0D)) {float f1 = ((float) SystemClock.currentThreadTimeMillis() - (float) this.mStartTime)/ (float) this.mDuration;f2 = this.mScale - (this.mScale - 1.0F)* PullToZoomListView.sInterpolator.getInterpolation(f1);localLayoutParams = PullToZoomListView.this.mHeaderContainer.getLayoutParams();if (f2 > 1.0F) {Log.d("mmm", "f2>1.0");localLayoutParams.height = PullToZoomListView.this.mHeaderHeight;localLayoutParams.height = ((int) (f2 * PullToZoomListView.this.mHeaderHeight));PullToZoomListView.this.mHeaderContainer.setLayoutParams(localLayoutParams);PullToZoomListView.this.post(this);return;}this.mIsFinished = true;}}public void startAnimation(long paramLong) {this.mStartTime = SystemClock.currentThreadTimeMillis();this.mDuration = paramLong;this.mScale = ((float) (PullToZoomListView.this.mHeaderContainer.getBottom()) / PullToZoomListView.this.mHeaderHeight);this.mIsFinished = false;PullToZoomListView.this.post(this);}}}

关于这个控件的实现原理能够自行參考上面链接的文章,里面已经有较为仔细的解说,此处不再赘述。

实现的效果就是以下这样:

github链接:/wangjinyu501/PullToZoomListView/,假设您发现了不论什么问题。能够在文章以下留言,我会第一时间处理。欢迎交流。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。