解析下拉图片放大

来源:互联网 发布:农业银行软件开发待遇 编辑:程序博客网 时间:2024/05/06 12:16

原理:

生成一个FrameLayout,然后装载ImageView,在手指按下的时候设置初始值mLastMotionY、mActivePointerId、mMaxScale、mLastScale;在手指移动的时候动态的改变localLayoutParams.height;当手指抬起时,生成一个Runnable,设置缩放动画,更改localLayoutParams.height


public class PullToZoomListView extends ListView implements AbsListView.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;//下拉-1 - 0            Log.e("getInterpolation", "f | " + f);            return 1.0F + f * (f * (f * (f * f)));        }    };    int mActivePointerId = -1;    private FrameLayout mHeaderContainer;//头部布局容器    private int mHeaderHeight;//头部控件的高度    private ImageView mHeaderImage;    float mLastMotionY = -1.0F;//监听手指在Y轴的移动    float mLastScale = -1.0F;//下拉:-1 - 2    float mMaxScale = -1.0F;//3    private AbsListView.OnScrollListener mOnScrollListener;    private ScalingRunnalable mScalingRunnalable;//缩放动画    private int mScreenHeight;//屏幕高度    private ImageView mShadow;    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() {        Log.e(TAG, "endScraling");        if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight)            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);//生成一个FrameLayout,装载下面两个ImageView        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) {        Log.e(TAG, "onSecondaryPointerUp = " + paramMotionEvent.getAction() + "");        int i = (paramMotionEvent.getAction()) >> 8;        if (paramMotionEvent.getPointerId(i) == this.mActivePointerId)            if (i != 0) {                int j = 1;                this.mLastMotionY = paramMotionEvent.getY(0);                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 boolean onInterceptTouchEvent(MotionEvent paramMotionEvent) {        return super.onInterceptTouchEvent(paramMotionEvent);    }    //    protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2, int paramInt3, int paramInt4) {        super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);        Log.e(TAG, "onLayout " + " mHeaderHeight == " + this.mHeaderContainer.getHeight());        if (this.mHeaderHeight == 0)            this.mHeaderHeight = this.mHeaderContainer.getHeight();    }    //正在滚动 ; 上滑启动    @Override    public void onScroll(AbsListView paramAbsListView, int paramInt1, int paramInt2, int paramInt3) {        Log.e(TAG, "onScroll");        float f = this.mHeaderHeight - this.mHeaderContainer.getBottom();        Log.e(TAG, "f|" + f + " mHeaderContainer.getBottom()|" + this.mHeaderContainer.getBottom());        if ((f > 0.0F) && (f < this.mHeaderHeight)) {            Log.e(TAG, "1");            int i = (int) (0.65D * f);            this.mHeaderImage.scrollTo(0, -i);        } else if (this.mHeaderImage.getScrollY() != 0) {            Log.e(TAG, "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.e(TAG, "MotionEvent == " + (0xFF & ev.getAction()));        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();//触摸时y轴的点                this.mActivePointerId = ev.getPointerId(0);//0                this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);//屏幕高度/头部控件的高度                this.mLastScale = (this.mHeaderContainer.getBottom() / this.mHeaderHeight);//504/504                break;            case MotionEvent.ACTION_MOVE:                int j = ev.findPointerIndex(this.mActivePointerId);//id永远为0                if (j == -1) {                    Log.e(TAG, "Invalid pointerId=" + this.mActivePointerId + " in onTouchEvent");                } else {                    if (this.mLastMotionY == -1.0F)                        this.mLastMotionY = ev.getY(j);                    if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight) {//mHeaderHeight = 405                        ViewGroup.LayoutParams localLayoutParams = this.mHeaderContainer.getLayoutParams();                        float f = ((ev.getY(j) - this.mLastMotionY + this.mHeaderContainer.getBottom()) / this.mHeaderHeight - this.mLastScale) / 2.0F + this.mLastScale;                        //下拉:f1.0 - 2.0                        Log.e(TAG, "localLayoutParams.height = " + localLayoutParams.height + " localLayoutParams.width = " + localLayoutParams.width + " f = " + f);                        if ((this.mLastScale <= 1.0D) && (f < this.mLastScale)) {                            localLayoutParams.height = this.mHeaderHeight;                            this.mHeaderContainer.setLayoutParams(localLayoutParams);                            return super.onTouchEvent(ev);                        }                        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);                        return true;                    }                    this.mLastMotionY = ev.getY(j);                }                break;            case MotionEvent.ACTION_UP:                reset();                endScraling();                break;            case MotionEvent.ACTION_CANCEL:                int i = ev.getActionIndex();                this.mLastMotionY = ev.getY(i);                this.mActivePointerId = ev.getPointerId(i);                break;            case MotionEvent.ACTION_POINTER_DOWN://设置多点触控                onSecondaryPointerUp(ev);                this.mLastMotionY = ev.getY(ev.findPointerIndex(this.mActivePointerId));                break;            case MotionEvent.ACTION_POINTER_UP:        }        return super.onTouchEvent(ev);    }    //初始化头部控件的布局    public void setHeaderViewSize(int paramInt1, int paramInt2) {        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;    }    //用线程缩放    class ScalingRunnalable implements Runnable {        long mDuration;//持续时间        boolean mIsFinished = true;//动画是否结束        float mScale;//缩放比例        long mStartTime;//开始时间        ScalingRunnalable() {        }        //终止动画        public void abortAnimation() {            this.mIsFinished = true;        }        //开始缩放        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;                Log.e(TAG, "mTime" + " mStartTime = " + mStartTime + " ---- SystemClock.currentThreadTimeMillis() = " + SystemClock.currentThreadTimeMillis());                f2 = this.mScale - (this.mScale - 1.0F) * PullToZoomListView.sInterpolator.getInterpolation(f1);                localLayoutParams = PullToZoomListView.this.mHeaderContainer.getLayoutParams();                if (f2 > 1.0F) {//下拉:f2==2 - 1   f1==0 - 1                    Log.e(TAG, "f2>1.0" + " f2 = " + f2 + " ---- f1 = " + f1);                    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);            Log.e("startAnimation", "--------------->mScale + " + mScale + "\nBottom = " + PullToZoomListView.this.mHeaderContainer.getBottom() + "\nmHeaderHeight = " + PullToZoomListView.this.mHeaderHeight);            this.mIsFinished = false;            PullToZoomListView.this.post(this);        }    }}

0 0
原创粉丝点击