自定义视差特效

先放一个效果图:



好了,看见这个效果,想知道怎么实现吗,一起来看看吧


一     类继承Listview


/**
 *
 * 继承式控件,覆写构造方法,
 * 覆写overScrollBy方法
 * 暴露方法,去得到外界的ImageView,测量ImageView的高度
 * 覆写onTouchEvent方法
 * 代码实现
  */

public class ParallaxListView extends ListView{
    private int drawableHeight;
    private ImageView fangfa;
    private int orignalHeight;
   //重写三个方法
   public ParallaxListView(Context context) {
       this(context,null);
    }

    public ParallaxListView(Context context, AttributeSet attrs) {
       this(context,attrs,0);
    }

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

//定义一个方法
    public void setFangfa(ImageView fangfa) {
        this.fangfa = fangfa;
        //获取图片的原始高度
        drawableHeight = fangfa.getDrawable().getIntrinsicHeight();
        //获取 imageview 的原始高度以便回弹
         orignalHeight = fangfa.getHeight();
    }
//重写,滑动到listview两端时被回调
    //重要参数  deltay isTouchEvent

    /**
     * 当滑动的超出上,,,右最大范围时回调
     *
     * @param deltaX         x方向的瞬时偏移量,左边到头,向右拉为负,右边到头,向左拉为正
     * @param deltaY         y方向的瞬时偏移量,顶部到头,向下拉为负,底部到头,向上拉为正
     * @param scrollX        水平方向的永久偏移量
     * @param scrollY        竖直方向的永久偏移量
     * @param scrollRangeX   水平方向滑动的范围
     * @param scrollRangeY   竖直方向滑动的范围
     * @param maxOverScrollX 水平方向最大滑动范围
     * @param maxOverScrollY 竖直方向最大滑动范围
     * @param isTouchEvent   是否是手指触摸滑动, true为手指, false为惯性
     * @return
     */

    @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){
            //deltay的负值改为绝对值,赋给控件图,达到视差效果
            int newHeight = (int) (fangfa.getHeight() + Math.abs(deltaY));
            //把新的高度付给控件
            fangfa.getLayoutParams().height = newHeight;
            //解决图无线发达的问题,不能超过本身高度
            if(newHeight<=drawableHeight){
                fangfa.getLayoutParams().height = newHeight;
                fangfa.requestLayout();
            }

        }

        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    //重写方法
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
    //手指抬起时执行一系列操作
            case MotionEvent.ACTION_UP:
                int currentHeight = fangfa.getHeight();
                //属性动画
                final ValueAnimator animator = ValueAnimator.ofInt(currentHeight, orignalHeight);

                //动画更新监听
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
                        float fraction = animator.getAnimatedFraction();
                        //获取中间值 ,赋给控件新高度
                        Integer animatedValue = (Integer)animator.getAnimatedValue();
                        //使新的高度生效
                        fangfa.getLayoutParams().height = animatedValue;
                        fangfa.requestLayout();

                    }

                });
                //动画的回弹效果,值越大,回弹的越厉害
                animator.setInterpolator((new OvershootInterpolator(1)));
                //设置动画执行时间
                animator.setDuration(500);
                animator.start();
                break;
        }
        return super.onTouchEvent(ev);
    }
}

二     去MainActivity 的Xml文件布局


<com.example.myapplication.ParallaxListView
    android:id="@+id/plv"
    android:scaleType="centerCrop"     !!重要属性
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</com.example.myapplication.ParallaxListView>

三     MainActivity

public class MainActivity extends AppCompatActivity {

    private ParallaxListView plv;
    private ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       //控件id
        plv = (ParallaxListView) findViewById(R.id.plv);
         //lisview添加一个头布局文件,布局变成对象
        View headerView = View.inflate(this, R.layout.header, null);
        //头部控件id
        image = (ImageView) headerView.findViewById(R.id.image);
        //添加头部布局
        plv.addHeaderView(headerView);
        
        //View界面全部绘制完毕后,去得到已经绘制的宽和高
        image.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                plv.setFangfa(image);
                //释放资源
                image.getViewTreeObserver().removeGlobalOnLayoutListener(this);


            }
        });
         //使用LisrviewArrayAdapter添加文本的item
        //listview设置数据

        plv.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,Chess.NAMES));

    }
}

四     头部布局


<ImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:scaleType="centerCrop"
    android:src="@drawable/a99"/>  !!图片自己找

五     定义了一个类,为ListView添加数据


public class Chess {

    public static final String[] NAMES = new String[]{"宋江", "卢俊义", "吴用",
            "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
            "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
            "雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
            " 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
            "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
            "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
            "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
            "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
            "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
            "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜",
            "时迁", "段景柱"};


      这样就可以做出一个视差特效的效果,可以应用在很多地方,写的可能不太好,请

大神多多指教。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值