基本思路:
1. 自定义ListView,在对应的activity中创建headerView,并添加到listview中,由于只需要改变背景图片的大小,所以只需要将imageView的引用传递给自定义的ListView,让其控制。
2. 在自定义listview总重新overScrollBy()方法。
3. 重写onTouchEvent()方法,当UP的时候,通过属性动画,将imageView的高度还原为原始高度。
实现代码:
public class ParallaxListviw extends ListView { private ImageView mImageView; private int mOriginalHeight;// imageView的原始高度 private int mDrawableHeight;//背景图片的高度 private int mNewHeight;//imageView的动态高度 public ParallaxListviw(Context context) { super(context); } public ParallaxListviw(Context context, AttributeSet attrs) { super(context, attrs); } public ParallaxListviw(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setImageView(ImageView imageView){ this.mImageView = imageView; if (mImageView != null){//由于imageview是在oncreate方法中设置的,因此在布局画完之后测量对应高度,否则无法得到 mImageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mOriginalHeight = mImageView.getMeasuredHeight(); mDrawableHeight = mImageView.getDrawable().getIntrinsicHeight(); mImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } } @Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { if (deltaY < 0 && isTouchEvent){ mNewHeight = mImageView.getHeight() + Math.abs(deltaY); if (mNewHeight <= mDrawableHeight){ mImageView.getLayoutParams().height = mNewHeight; mImageView.requestLayout(); } } return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_UP){ ValueAnimator valueAnimator = ValueAnimator.ofInt(mImageView.getHeight(), mOriginalHeight); valueAnimator.setDuration(500); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mImageView.getLayoutParams().height = (int) valueAnimator.getAnimatedValue(); mImageView.requestLayout(); } }); valueAnimator.setInterpolator(new OvershootInterpolator(3)); valueAnimator.start(); } return super.onTouchEvent(ev); } }在activity中的设置:
public class MainActivity extends Activity { private ParallaxListviw mPlv; private ImageView mIv_header; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPlv = (ParallaxListviw)findViewById(R.id.plv); View header = View.inflate(this,R.layout.headerview,null); mIv_header = (ImageView) header.findViewById(R.id.iv_header); mPlv.setImageView(mIv_header); ArrayAdapter arrayAdapter = new ArrayAdapter(this,R.layout.item,new String[]{"毛衣","衬衫","羽绒服"}); mPlv.addHeaderView(header); mPlv.setAdapter(arrayAdapter); } }
翻看大神的博客,发现,使用重写该方法实现下拉回弹,实际应用中bug一堆,只能做学习使用。