简单视差特效的实现

基本思路:

   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一堆,只能做学习使用。


你可能感兴趣的:(android基础)