垂直方向的viewPager

垂直方向的viewpager,网上也有些许实现。大多是自定义ViewGoup的,这样的话就要自己做view复用的事情了。

但我思考了下发现listview不也可以做这事情吗!!于是就尝试着去实现了下,发现还真可以,效果也棒棒的。。。。。

这里写图片描述

看效果是不是跟ViewPager没区别,也有回滚和快速切换。哈哈、、、最主要的是代码没几行。

有下面几个问题需要解决
1.怎么让item占满整个屏幕
2.怎么滚动listview(listview滚动跟scrollview还是有区别的)
3.兼容到2.2(虽然4以下的手机基本见不到了,好多公司还是要兼容到2.2的)

1.怎么让item占满整个屏幕

刚开始我考虑使用onMeasure里面做下手机,但发现没效果,后看了下源码`
  private void measureScrapChild(View child, int position, int widthMeasureSpec) {
        LayoutParams p = (LayoutParams) child.getLayoutParams();
        if (p == null) {
            p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
            child.setLayoutParams(p);
        }
        p.viewType = mAdapter.getItemViewType(position);
        p.forceAdd = true;

        int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
                mListPadding.left + mListPadding.right, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }
  if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }

就是这几句代码,如果不设置LayoutParams那么测量方式都是UNSPECIFIED

所以onMeasure这里通过几种测量方式的改变来做是做不了,只能忘LayoutParams方向动手。

要设置LayoutParams可以在getview的时候设置下,也是可以的。但能不能再onmeasure之前设置呢?这样就可以不用每次都设置了,也是可以的,但是就是有个问题,如果listview不是全屏怎么办?要怎么取到listview的高度?暂时没有想到方法,如果有方法的请告知。。感激不尽啊。

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub

        for (int i = 0; i < getChildCount(); i++) {
            View childView = getChildAt(i);
            childView.getLayoutParams().height=200;
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

上面就是在Onmeasure里面做的测试代码

所以最后还是决定在getview里面做

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub

            // 只是测试 不考虑性能

            View v = new View(VerticalViewPagerActivity.this);

            v.setBackgroundColor((int) (Color.RED * Math.random()));

            AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                    AbsListView.LayoutParams.MATCH_PARENT,
                    displayMetrics.heightPixels);
            v.setLayoutParams(params);

            return v;
        }

是不是也很easy啊,没什么可说的,是吧。

2.怎么滚动listview

这个滚动使用Scroller也是可以的,做法应该不难,这里我采用的是Animation,动画来做的

// 动画辅助scroller
        scrollAnimation = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime,
                    Transformation t) {
                // TODO Auto-generated method stub
                super.applyTransformation(interpolatedTime, t);
                int deltaY = (int) (interpolatedTime * scrollDest - haseScrollValue);
                if (Math.abs(deltaY) == Math.abs(scrollDest)) {
                    deltaY = 0;
                }
                //listview 滚动辅助类 在v4包里
                listViewAutoScrollHelper.scrollTargetBy(0, deltaY);
                haseScrollValue += deltaY;
            }
        };

当然使用属性动画是最简单的 ,但是3.0以下不支持,要导入第三方兼容库,对方法数是一个挑战。

最后就是滑动了。

在down 和move事件都可以交给listview来做,我们要处理的就是up事件。

@Override
    public boolean onTouchEvent(MotionEvent ev) {

        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);
        int action = ev.getAction();

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            downY = ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            if (downY == 0) {
                downY = ev.getY();
            }
            break;
        case MotionEvent.ACTION_UP:
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int initialVelocity = (int) velocityTracker.getXVelocity();
            final int destY = (int) (ev.getY() - downY);
            if (Math.abs(initialVelocity) > mMinimumVelocity
                    && Math.abs(destY) > mTouchSlop) {// 一定要滚动到下一页
                final View childView = getChildAt(0);
                if (childView == null)
                    return true;
                if (destY > 0) {// 向下滚
                    switchPager(childView.getTop());
                } else {// 向上滚
                    switchPager(childView.getBottom());
                }

            } else {// 根据临界值判断是否要滚动
                checkScrollReset();
            }

            if (mVelocityTracker != null) {
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            }
            downY = 0;
            return true;
        }

        return super.onTouchEvent(ev);
    }

就是最基本的滚动操作了。把down和move都交给listview自己处理,up事件咱来处理,就是有viewpager的滑动效果了。

好了,垂直滚动的viewpager就完成了。

源代码

点击下载http://download.csdn.net/detail/u013171787/9351767

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值