android 仿QQ空间listview反弹效果

来源:互联网 发布:seo新手入门教程 编辑:程序博客网 时间:2024/06/04 17:43

思路:主要是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 0