自定义View______商品详情界面效果(纪录片)

开头:每天记录一下自己学习到了什么,在此记录一下,这样才不会忘记。

1.思路是这样的。
1.1 自定义一个ViewGroup,里面嵌套两个ScollerView实现商品详情模仿图。
1.2 当第一个ScollerView 下拉到最底部的时候在向上滑动,就滑动到第二页,当第二页滑动到最顶部的时候,在滑动就滑动到第一页。

说了这么多的滑动那就不可能是生硬的滚动,而是很循环渐进的效果。
在这里需要考虑一下,
我们怎么滑动?怎么在规定时间滑动到目的地?滑动的距离?
我们可能第一时间会想到ScrollTo/ScrollBy吧?
(ScrollTo/ScrollBy 是对ViewGroup的内容进行位移的)
如果大家想问下它们之间有什么区别的话,其实也可以直接看源码


    public void scrollTo(int x, int y) {
        if (mScrollX != x || mScrollY != y) {
            int oldX = mScrollX;
            int oldY = mScrollY;
            mScrollX = x;
            mScrollY = y;
            invalidateParentCaches();
            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
            if (!awakenScrollBars()) {
                postInvalidateOnAnimation();
            }
        }
    }


    public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }

这里发现ScrollyBy 和 ScrollTo 之间的并没有什么很大的区别,那么mScrollX和mScrollY有时什么啦?
这里说明下
mScrollX的值总是等于View左边缘和View内容左边缘在水平方向的距离
mScrollY的值总是等于View上边缘和View内容上边缘竖直方向距离。
他们只能改变View内容的位置而不能改变内容在布局的位置,

但是试过的朋友可能会感觉到这个效果是不是有点快了,没有一点前奏啦。
那就要试试这个两个方法搭配了。
/**
* startX—> X 开始位置
* startY—> Y 开始位置
* dx—–> X位移距离
* dy—–> Y位移距离
*/
1.startScroll(int startX, int startY, int dx, int dy) ;
2.computeScroll()

第一种方法大家其实可以看到其中源码

    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        mMode = SCROLL_MODE;
        mFinished = false;
        mDuration = duration;
        mStartTime = AnimationUtils.currentAnimationTimeMillis();
        mStartX = startX;
        mStartY = startY;
        mFinalX = startX + dx;
        mFinalY = startY + dy;
        mDeltaX = dx;
        mDeltaY = dy;
        mDurationReciprocal = 1.0f / (float) mDuration;
    }

怎么可以这样,这不只是初始化一些参数吗?也没有什么牛X的方法可以调用

那么接下来就的看 computeScroll()的功能啦

第二个方法是在我们draw事件中会调用computeScroll()方法,而computerScroll()方法可以获取当前的scrollX和ScrollY;
然后再通过通过ScollerTo方法,接着调用postInvalidate() 来实现滑动,不过这个时候调用postInvalidate()它会再次触发重绘这样一直反复到是否结束 ;
通过这该方法来判断
scroller.computeScrollOffset(),
那就来看下这个方法具体实现

   @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            postInvalidate();
        }
    }

过了一天的晚上

晚上一直在实现这个功能了,正在接入项目中,赶脚还不错。
想说下思路吧。
由于是我自己写的ViewGroup,所以我就需要进行对其中的子控件进行定位置,我定的位置走向就是竖直排列。
排列子View位置前还需要走的一个流程就是 onMeasure
如果不懂的话,可以看到 View测绘事件
这是我排列的代码 —–》好吧 我承认我有借鉴linerLayout的 vertical 排列规则。

  @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childTop = 0;
        int count = getChildCount();
        //设置布局 将子试图顺序竖屏显示。
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                final int childWidth = child.getMeasuredWidth();
                final int childHeight = child.getMeasuredHeight();
                Log.d(TAG, "childHeight=" + childHeight);
                child.layout(0, childTop, childWidth, childTop + childHeight);
                /**
                 * 记录Top高度
                 */
                childTop += childHeight;
            }
        }
    }

1

—- 排列顺序ok了,那么我们接下来就是处理什么时候向上滚动,什么时候想下滚动了
1.在第一页滚动到底,然后手指向上位移,那么就滚动到第二页。
2.第二页手指向下位移,并且已经到头部了,就滚动到第一页。
3.滚动的长度大小。

2

(这里需要有分发事件概念)
声明:我是艺术探索的读者

如果满足以上的条件,就需要ViewGroup自己去处理,子类滚动,以及滚动的方向。
这里给出伪代码—很经典的列子

public boolean dispatchTouchEvent(MotionEvent ev){
   boolean consume=false;
   if(onInterceptTouchEvent(ev)){
      consume=onTouchEvent(ev);
   }eles{
       consume=child.dispatchTouchEvent(ev);
   }
    return consume;
}

明天写 拦截事件,和 OnTouchEvent。
(赶脚处理的不好,需要思考一下)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值