仿微博的弹性listview

最近项目需求做一个仿微博的弹性listview,找了很多大家的分享,并没有找到完全符合自己需求的代码,自己在某位热于分享的前辈(看了太多例子,忘记是谁了,请见谅)的代码基础上做了改善,现在记录一下。

public class PullListView extends ListView implements AbsListView.OnScrollListener {


    private static final String TAG = "PullListView";


    //下拉因子,实现下拉时的延迟效果
    private static final float PULL_FACTOR = 0.5f;




    //记录刚开始下拉时的触摸位置的Y坐标
    private int startY;
    private int mlastY;
    private int y;


    //第一个可见条目的索引
    private int firstItemIndex;


    //用于实现下拉弹性效果的headView
    private View headView2;
    private View headView;


    private int currentScrollState;


    public PullListView(Context context) {
        super(context);
        init(context);
    }


    public PullListView(Context context, AttributeSet attr) {
        super(context, attr);
        init(context);
    }


    /**
     * 初始化
     *
     * @param context
     */
    private void init(Context context) {
        //创建PullListView的headview
        headView2 = new View(this.getContext());
        //默认白色背景,可以改变颜色, 也可以设置背景图片
        headView2.setBackgroundColor(Color.WHITE);
        //默认高度为0
        headView2.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, 0));


        this.addHeaderView(headView2);
        headView = View.inflate(context, R.layout.activity_main, null);
        headView.setPadding(0, dp2px(this.getContext(), -50), 0, dp2px(this.getContext(), -50));
        int mScaledTouchSlop = ViewConfiguration.get(getContext())
                .getScaledTouchSlop();
        this.addHeaderView(headView);
        this.setOnScrollListener(this);
    }




    /**
     * 覆盖onTouchEvent方法,实现下拉回弹效果
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (firstItemIndex == 0) {
            y = (int) event.getRawY();
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //记录下拉起点状态
                startY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int moveY = y - mlastY; //位移
                if (moveY > 0) {
                    int offset = (int) ((y - startY) * PULL_FACTOR);
                    Log.i(TAG, "headView.getLayoutParams().height" + headView.getMeasuredHeight());
                    Log.i(TAG, "headView" + headView.getTop());


                    if (headView.getPaddingTop() >= 0 && headView.getPaddingBottom() >= 0) {
                        int top = offset - (dp2px(this.getContext(), 300) - dp2px(this.getContext(), 200));
                        headView.setPadding(0, 0, 0, 0);
                        headView2.setLayoutParams(new AbsListView.LayoutParams(MATCH_PARENT, top));
                    } else {
                        headView.setPadding(0, offset + dp2px(this.getContext(), -50), 0, offset + dp2px(this.getContext(), -50));
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                resetPosition();
                break;
        }
        mlastY = y;
        return super.onTouchEvent(event);
    }


    private void resetPosition() {
        headView2.setLayoutParams(new AbsListView.LayoutParams(MATCH_PARENT, 0));
        ValueAnimator anim = ValueAnimator.ofInt(headView.getPaddingTop(), dp2px(this.getContext(), -50));
        anim.setDuration(200);
        anim.start();
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                headView.setPadding(0, (Integer) animation.getAnimatedValue(), 0, (Integer) animation.getAnimatedValue());
            }
        });
    }




    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    }


    public int dp2px(Context ctx, float dp) {
        float density = ctx.getResources().getDisplayMetrics().density;
        int px = (int) (dp * density + 0.5f);// 4.9->5 4.4->4
        return px;
    }


    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        currentScrollState = scrollState;
    }


    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        firstItemIndex = firstVisibleItem;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值