现在的位置: 首页 > 综合 > 正文

ListView 下拉回弹效果(类似知乎日报首页效果)

2018年02月15日 ⁄ 综合 ⁄ 共 2480字 ⁄ 字号 评论关闭

项目中需要做一个类似效果,就在StickyListHeaders的基础上写了一部分代码

效果图解释:

下拉,header中ViewPager中的图片变大,松开手,会有个回弹效果。

      

      

上代码:

public class HeaderListView extends StickyListHeadersListView {

    private Scroller scroller;

    private int len = 50;

    private boolean scrollerType = false;

    private ViewPager viewPager;

    float startY;

    int bottom;

    public HeaderListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        scroller = new Scroller(context);

    }

    public HeaderListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        scroller = new Scroller(context);

    }

    public HeaderListView(Context context) {
        super(context);
        scroller = new Scroller(context);

    }

    @Override
    public void addHeaderView(View v, Object data, boolean isSelectable) {
        viewPager = (ViewPager) v.findViewById(R.id.header);
        super.addHeaderView(v, data, isSelectable);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        float currentY = ev.getY();

        Log.e("currentY", currentY + "");
        Log.e("viewPager.getBottom()", viewPager.getBottom() + "");

        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:

            startY = currentY;
            bottom = viewPager.getBottom();
            break;
        case MotionEvent.ACTION_MOVE:

            if (startY > bottom && viewPager.isShown() && viewPager.getTop() >= 0) {

                int y = (int) (bottom + (currentY - startY) / 2.5f);
                Log.e("ACTION_MOVE", "y =" + y);

                if (y < viewPager.getBottom() + len && y >= bottom) {

                    viewPager.setLayoutParams(new RelativeLayout.LayoutParams(new RelativeLayout.LayoutParams(viewPager
                            .getWidth(), y)));
                }
                scrollerType = false;

            }
            break;
        case MotionEvent.ACTION_UP:

            scrollerType = true;
            Log.e("ACTION_UP", "" + (bottom - viewPager.getBottom()));

            scroller.startScroll(viewPager.getLeft(), viewPager.getBottom(), 0 - viewPager.getLeft(), bottom
                    - viewPager.getBottom(), 200);
            invalidate();
            break;

        }

        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public void computeScroll() {

        if (scroller.computeScrollOffset()) {
            int x = scroller.getCurrX();
            int y = scroller.getCurrY();
            viewPager.layout(0, 0, x + viewPager.getWidth(), y);
            if (!scroller.isFinished() && scrollerType && y > bottom) {
                viewPager.setLayoutParams(new RelativeLayout.LayoutParams(viewPager.getWidth(), y));
            }

            invalidate();

        }
    }

}

Header中的ViewPager左右滑动和listView上下滑动有冲突,解决办法,自定义ViewPager,重写她的dispatchTouchEvent(MotionEvent ev)

public class CustomView extends RelativeLayout {

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        getParent().requestDisallowInterceptTouchEvent(true);

        return super.dispatchTouchEvent(ev);
    }

}

明白思路,自己写个下拉刷新什么的应该就不是很难了。

demo:点我下载

参考:android 中文 api (64) —— Scroller

抱歉!评论已关闭.