自定义控件--头部视差

一、项目分析

1.应用场景:个人信息界面头部图片放大效果

2.视差效果:view变化的速度和手指移动的速度不一致;


二、正式开发

1.

ParallaxListview.java

package com.weizh.parallax.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewTreeObserver;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.ListView;

import com.nineoldandroids.animation.ValueAnimator;

/**
 * Created by weizh_000 on 2016/8/23.
 */

public class ParallaxListview extends ListView {
    private ImageView imageView;
    private int maxHeight;//上限高度
    private int originalHeight;

    public ParallaxListview(Context context) {
        super(context);
    }

    public ParallaxListview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ParallaxListview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setParallaxImageView(final ImageView imageView) {
        this.imageView = imageView;

        imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                originalHeight = imageView.getHeight();//imageview的高度
                int imageHeight = imageView.getDrawable().getIntrinsicHeight();//获取图片真实高度

                //矮图片的情况,让最大高度等于imageview的高度2倍
                maxHeight = originalHeight >imageHeight? originalHeight *2:imageHeight;
            }
        });
    }

    /**
     * 在listview滑动到头的时候执行,可以获取到继续滑动的距离和方向
     * deltaX:继续滑动x方向的距离
     * deltaY:继续滑动y方向的距离     负:表示顶部到头   正:表示底部到头
     * maxOverScrollX:x方向最大可以滚动的距离
     * maxOverScrollY:y方向最大可以滚动的距离
     * isTouchEvent: true: 是手指拖动滑动     false:表示fling靠惯性滑动;
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        if (isTouchEvent && deltaY < 0) {
            //拉到头部

            int newHeight = imageView.getHeight() - deltaY/3;//deltaY/3造成下拉的时候很吃力的效果
            if (newHeight > maxHeight) newHeight = maxHeight;//高度不能超过上限

            imageView.getLayoutParams().height = newHeight;//增加头部图片的高度
            imageView.requestLayout();//使layoutparams生效
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (ev.getAction()==MotionEvent.ACTION_UP){
            //手指抬起的时候,让imageview自动恢复高度
            ValueAnimator animator = ValueAnimator.ofInt(imageView.getHeight(), originalHeight);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    int newHeight = (int) valueAnimator.getAnimatedValue();
                    imageView.getLayoutParams().height = newHeight;//改变头部图片的高度
                    imageView.requestLayout();//使layoutparams生效
                }
            });
            animator.setInterpolator(new OvershootInterpolator(3));//弹性的插值器,让恢复的时候显得有弹性
            animator.setDuration(300);
            animator.start();
        }
        return super.onTouchEvent(ev);
    }
}

2.

MainActivity.java

package com.weizh.parallax;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;

import com.weizh.parallax.widget.ParallaxListview;

public class MainActivity extends AppCompatActivity {

    private ParallaxListview myListView;
    private String[] indexArr = {"A", "B", "C", "D", "E", "F", "G", "H",
            "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
            "V", "W", "X", "Y", "Z"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
    }

    private void initData() {
        myListView.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,indexArr));
    }

    private void initView() {
        myListView =(ParallaxListview)findViewById(R.id.my_listView);
        View view = View.inflate(this, R.layout.head_view, null);
        myListView.addHeaderView(view);
        myListView.setParallaxImageView((ImageView) view.findViewById(R.id.iv_head));
        myListView.setOverScrollMode(ListView.OVER_SCROLL_NEVER);//顶部永远不显示蓝色覆盖膜
    }
}

三、效果图


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值