下拉刷新头部视差效果

  

头部视差效果

  1. 分析思路:先给listview头部添加ImageView,然后根据手指往下拖动的距离,去让ImageView的高度不断增高,当手指抬起的时候让ImageView恢复至最初高度
  2. 首先,自定义ParallaxListView,继承ListView
  3. 然后,给ListView填充数据,并addHeaderView,添加ImageView作为头布局:
    //1.添加头部IMageView
    View view = View.inflate(this, R.layout.layout_header, null);
    parallaxImage = (ImageView) view.findViewById(R.id.parallaxImage);
    listView.addHeaderView(view);
    //2.填充数据
    listView.setAdapter(new MyAdapter());
  4. 给ParallaxListView添加setParallaxImageView方法,让外界传入ImageView的引用,因为后面需要用到:
    private ImageView parallaxImageView;
    public void setParallaxImageView(final ImageView parallaxImageView) {
    	this.parallaxImageView = parallaxImageView;
    }
    并且在Activity中传入ImageView对象:
    //设置ImageView
    listView.setParallaxImageView(parallaxImage);
  5. 根据观察,我们需要在listview滑动到头的时候去计算手指移动的距离,但是不采用去监听onTouchEvent的move事件了,我们去重写overScrollBy方法,该方法就是在listview滑动到头的时候才调用,并且可以获取到继续滑动的距离;所以我们进行判断如下:
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
    		int scrollY, int scrollRangeX, int scrollRangeY,
    		int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { isTouchEvent:"+isTouchEvent);
    	//表示手指拖动,并且是顶部到头了,
    	if(deltaY<0 && isTouchEvent){
    		...
    	}
    	return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
    			scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }
  6. 在overScrollBy方法中判断,如果是顶部滑动到头,并且是手指继续拖动,则不断增加ImageView的高度,并且对高度作最大值的限制,代码如下:

    //根据继续滑动的距离,就是deltaY,让ImageView的高度变高
    int newHeight = parallaxImageView.getHeight()-deltaY/3;
    //对高度进行限制
    if(newHeight>maxHeight)newHeight = maxHeight;
    
    //将ImageView的高变成newHeight
    android.view.ViewGroup.LayoutParams params = parallaxImageView.getLayoutParams();
    params.height = newHeight;
    //重新设置高度
    parallaxImageView.setLayoutParams(params);
  7. 当手指抬起的时候让ImageView恢复到最初高度,首先求出最初高度,需要注意的是不能够直接get,因为可能还没有测量完,我们选择添加一个全局的布局监听器,在setParallaxImageView方法中去获取:
    parallaxImageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    		@Override
    		public void onGlobalLayout() {
    			//用完立即移除
    			parallaxImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    			originalHeight = parallaxImageView.getHeight();
    		}
    });
  8. 然后在onTouchEvent中去判断TOUCH_UP的事件,最终通过ValueAnimator实现自定义的动画,此处自定义动画的逻辑就是让ImageView的高度进行变化到指定高度:
    if(ev.getAction()==MotionEvent.ACTION_UP){
    	//让ImageView缓慢恢复到最初的高度
    	ValueAnimator animator = ValueAnimator.ofInt(parallaxImageView.getHeight()
    				,originalHeight);
    	animator.addUpdateListener(new AnimatorUpdateListener() {
    		@Override
    		public void onAnimationUpdate(ValueAnimator animator) {
    			//获取动画的值,
    			int animatedValue = (Integer) animator.getAnimatedValue();
    			//将动画的值设置给parallaxImageView的高度
    			android.view.ViewGroup.LayoutParams params = parallaxImageView.getLayoutParams();
    			params.height = animatedValue;
    			//重新设置高度
    			parallaxImageView.setLayoutParams(params);
    		}
    	});
    	//给动画添加速度插值器
    	animator.setInterpolator(new OvershootInterpolator(4));//超过一点再回来
    	animator.setDuration(350);
    	animator.start();
    }

你可能感兴趣的:(下拉刷新头部视差效果)