Android的ListView弹动效果,且解决了元素较少是不能弹动的问题

1.继承ListView,重写overScrollBy方法,调用super.overScrollBy()方法,替换maxOverScrollY参数

优点:简单

缺点:当元素数目较少时,弹动无效

import android.content.Context;  
import android.util.AttributeSet;  
import android.util.DisplayMetrics;  
import android.widget.ListView;  
/** 
 * 弹性ListView。 
 * @author E 
 */  
public class FlexiListView extends ListView{  
    //初始可拉动Y轴方向距离  
    private static final int MAX_Y_OVERSCROLL_DISTANCE = 100;  
    //上下文环境  
    private Context mContext;  
    //实际可上下拉动Y轴上的距离  
    private int mMaxYOverscrollDistance;  
      
    public FlexiListView(Context context){  
        super(context);  
        mContext = context;  
        initBounceListView();  
    }  
      
    public FlexiListView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        mContext = context;  
        initBounceListView();  
    }  
      
    public FlexiListView(Context context, AttributeSet attrs, int defStyle) {  
        super(context, attrs, defStyle);  
        mContext = context;  
        initBounceListView();  
    }  
      
    private void initBounceListView(){  
        final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();  
            final float density = metrics.density;  
        mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE);  
    }  
      
    @Override  
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,   
            int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {   
        //实现的本质就是在这里动态改变了maxOverScrollY的值  
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxYOverscrollDistance, isTouchEvent);    
    }  
      
}

 2.通过重写onTouchEvent方法,实现弹动效果,解决了元素较少时,不能弹动问题

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;

public class IpListView extends ListView implements Runnable {
    private float mLastDownY = 0f;
    private int mDistance = 0;
    private int mStep = 10;
    private boolean mPositive = false;
    private boolean mIsBounces;

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

    public IpListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mIsBounces) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (mLastDownY == 0f && mDistance == 0) {
                    mLastDownY = event.getY();
                }
                break;

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (mDistance != 0) {
                    mStep = 1;
                    mPositive = mDistance >= 0;
                    this.post(this);
                    return true;
                }

                mLastDownY = 0f;
                mDistance = 0;
                break;

            case MotionEvent.ACTION_MOVE:
                if (mLastDownY != 0f) {
                    mDistance = (int) (mLastDownY - event.getY());
                    if ((mDistance < 0 && getFirstVisiblePosition() == 0 && getChildAt(
                            0).getTop() == 0)) {
                        mDistance /= 2;
                        scrollTo(0, mDistance);
                        return true;
                    } else if (mDistance > 0
                            && getLastVisiblePosition() == getCount() - 1) {
                        final View bottomChildView = getChildAt(getLastVisiblePosition()
                                - getFirstVisiblePosition());
                        if (getHeight() >= bottomChildView.getBottom()) {
                            mDistance /= 2;
                            scrollTo(0, mDistance);
                            return true;
                        }
                    }
                }
                mDistance = 0;
                break;
            }
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void run() {
        mDistance += mDistance > 0 ? -mStep : mStep;
        scrollTo(0, mDistance);
        if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {
            scrollTo(0, 0);
            mDistance = 0;
            mLastDownY = 0f;
            return;
        }
        mStep += 1;
        this.postDelayed(this, 10);
    }

    public void setBounces(boolean isBounces) {
        this.mIsBounces = isBounces;
    }
}

 

posted @ 2017-02-16 12:03  叫我什么大人  阅读(711)  评论(0编辑  收藏  举报