android 仿QQ空间listview反弹效果

思路:主要是listview有个OverScrollBy()方法,它是listview滑动到头部时候还能滑动,先获取imageview的最初高度,然后再滑动的过程中动态去计算imageview的高度,直到imageview显示图片的原始高度

package com.example.adminis.lsitview;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.ImageView;

import com.custom.widget.CustomListView;
import com.example.adminis.lsitview.adapter.MyAdapter;

import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
    private CustomListView custom_listview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        custom_listview = (CustomListView) findViewById(R.id.custom_listview);
        final View heaerView = LayoutInflater.from(this).inflate(R.layout.header_lv,null);
        final ImageView iv_header_view = (ImageView) heaerView.findViewById(R.id.iv_header_view);
        custom_listview.addHeaderView(heaerView);

        MyAdapter adapter = new MyAdapter(initData(),this);
        custom_listview.setAdapter(adapter);

        heaerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onGlobalLayout() {
                custom_listview.setView(iv_header_view);
                heaerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }

    private List<String> initData() {
        List<String> datas = new ArrayList<String>();
        for(int i=0;i<20;i++){
            datas.add("求你拉我吧,我要反弹---");
        }
        return datas;
    }
}

自定义listviewCustomListView

package com.custom.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HeaderViewListAdapter;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.com.custom.animation.ResetHeightAnimation;

/**
 * Created by Adminis on 2016/1/29.
 */
public class CustomListView extends ListView {

    private static final String TAG = "CustomListView";
    private ImageView iv_header_view;
    private int maxImgHeight;//图片的最大高度
    private int originalHeight;//imageview 图片对应的原始高度

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

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

    public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    /**
     * listview滑动到头的时候被调用
     * Add a fixed view to appear at the top of the list. If addHeaderView is
     * called more than once, the views will appear in the order they were
     * added. Views added using this call can take focus if they want.
     * <p>
     * Note: When first introduced, this method could only be called before
     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
     * called at any time. If the ListView's adapter does not extend
     * {@link HeaderViewListAdapter}, it will be wrapped with a supporting
    * @param deltaX Change in X in pixels
    * @param deltaY Change in Y in pixels
    * @param scrollX Current X scroll value in pixels before applying deltaX
    * @param scrollY Current Y scroll value in pixels before applying deltaY
    * @param scrollRangeX Maximum content scroll range along the X axis
    * @param scrollRangeY Maximum content scroll range along the Y axis
    * @param maxOverScrollX Number of pixels to overscroll by in either direction
    *          along the X axis.
            * @param maxOverScrollY Number of pixels to overscroll by in either direction
    *          along the Y axis. 滑动到头部最多还可以滑动多少
            * @param isTouchEvent true if this scroll operation is the result of a touch event.
    * @return true if scrolling was clamped to an over-scroll boundary along either
    *          axis, false otherwise. isTouch true就是手慢慢的滑动到头部 false表示一瞬间滑动到头部有惯性的

     */
    @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){
            //当前的高度+拖动的距离  动态改变imageview的高度
            int resetHeight = iv_header_view.getHeight()-deltaY;
            if(resetHeight>maxImgHeight){
                resetHeight = maxImgHeight;
            }
            iv_header_view.getLayoutParams().height = resetHeight;
            iv_header_view.requestLayout();//重新 layout --->onLayout去动态计算他的高度
        }
        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:
                ResetHeightAnimation resetHeightAnimation  = new ResetHeightAnimation(iv_header_view,originalHeight);
                startAnimation(resetHeightAnimation);
                break;
        }
        return super.onTouchEvent(ev);
    }

    public void setView(ImageView view) {
        this.iv_header_view = view;
        this.originalHeight = view.getHeight();
        maxImgHeight = iv_header_view.getDrawable().getIntrinsicHeight();
    }
}

ResetHeightAnimation是一个模拟动画在一定时间改变属性

package com.com.custom.animation;

import android.view.View;
import android.view.animation.Animation;
import android.view.animation.OvershootInterpolator;
import android.view.animation.Transformation;

/**
 * Created by Adminis on 2016/1/29.
 */
public class ResetHeightAnimation extends Animation {
    private View view;
    private int targetHeight;
    private int originalHeight;//imageview最初的高度
    private int totalHeight;
    public ResetHeightAnimation(View view,int targetHeight) {
        this.view = view;
        this.targetHeight = targetHeight;
        originalHeight = view.getHeight();
        totalHeight = targetHeight-originalHeight;
        setDuration(400);
        setInterpolator(new OvershootInterpolator());
    }

    /**
     *
     * @param interpolatedTime 动画执行的进度 默认是0--1 或者百分比 比如他是0.5表示动画执行了50%
     * @param t
     */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        int resetHeight = (int) (originalHeight+totalHeight*interpolatedTime);
        view.getLayoutParams().height = resetHeight;
        view.requestLayout();
    }
}

图:


xml文件就不必贴了,到此为止 该休息了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值