android ScrollView smoothScrollTo源码分析


         项目中用到smoothScrollTo,在输入框中判断里用到了这个,不知道为何这会总是报空指针的错,于是在网络上搜索一番,没有看到理想的结果。于是乎静下心来去看源码吧。


     

/** 
     * Like {@link #scrollTo}, but scroll smoothly instead of immediately. 
     * 
     * @param x the position where to scroll on the X axis 
     * @param y the position where to scroll on the Y axis 
     */  
    public final void smoothScrollTo(int x, int y) {  
        smoothScrollBy(x - mScrollX, y - mScrollY);  
    }  


     首先看看这里边的几个参数的含义:先说x,和y,这两个传入的参数就是你想要移动到的位置,这个位置就你要移动到的位置,当然是相对于ScrollView左上角的位置来说。mScrollX和mScrollY就是当前ScrollView的偏移量,也是相对于ScrollView的坐上角来说的,这两项的差值就是要滚动到的位置相对于当前ScrollView显示的左上角的坐标的一个相对位置。下面在放上smoothScrollBy的源码

   

/** 
     * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. 
     * 
     * @param dx the number of pixels to scroll by on the X axis 
     * @param dy the number of pixels to scroll by on the Y axis 
     */  
    public final void smoothScrollBy(int dx, int dy) {  
        if (getChildCount() == 0) {  
            // Nothing to do.  
            return;  
        }  
        long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;  
        if (duration > ANIMATED_SCROLL_GAP) {  
            final int height = getHeight() - mPaddingBottom - mPaddingTop;  
            final int bottom = getChildAt(0).getHeight();  
            final int maxY = Math.max(0, bottom - height);  
            final int scrollY = mScrollY;  
            dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;  
  
            mScroller.startScroll(mScrollX, scrollY, 0, dy);  
            postInvalidateOnAnimation();  
        } else {  
            if (!mScroller.isFinished()) {  
                mScroller.abortAnimation();  
                if (mFlingStrictSpan != null) {  
                    mFlingStrictSpan.finish();  
                    mFlingStrictSpan = null;  
                }  
            }  
            scrollBy(dx, dy);  
        }  
        mLastScroll = AnimationUtils.currentAnimationTimeMillis();  
    }  
  

   看看第8行,很简单,如果ScrollView没有包含任何东西,则什么都处理。(当然了,没有东西滚动毛线!)。然后说一下AnimationUtils.currentAnimationTimeMillis(),这个是获取从开机到现在的毫秒数。maxY计算的是超出ScrollView能够显示的那一部分的长度。dy计算出来的就是要滑动的距离。当然有人会问为什么还有判断if (duration > ANIMATED_SCROLL_GAP),这里是判断当前scrollView是否在滚动中,系统默认的滚动时间是250毫秒。我看网上很多人在问为什么设置的smoothScrollTo没有效果,就是因为计算出来的那个dy是0,这样就不会滚动了。所以解决这个问题还是要看自己设置的那个值为啥不对吧。


   下面是我项目中的使用和报错:

  

 if (TextUtils.isEmpty(etHolderName.getText())) {
//            ToastUtil.show("请填写投保人");
            ToastUtil.showToast(getActivity(),R.layout.my_toast,"请填写投保人");
            etHolderName.requestFocus();
//            scrollView.smoothScrollTo(0, 0);
            return;
        }
        if (TextUtils.isEmpty(etHolderPhone.getText())) {
//            ToastUtil.show("请填写投保人手机号码");
            ToastUtil.showToast(getActivity(),R.layout.my_toast,"请填写投保人手机号码");
            etHolderPhone.requestFocus();
//            scrollView.smoothScrollTo(0, 0);
            return;
        }
        String phoneNum = etHolderPhone.getText().toString().replace(" ", "");
        if (!phoneNum.matches(getString(R.string.photo_reg))) {
//            ToastUtil.show("请输入正确的手机号码");
            ToastUtil.showToast(getActivity(),R.layout.my_toast,"请输入正确的手机号码");
            etHolderPhone.requestFocus();
            return;
        }

    当然,上面的代码里我已经注释了,注释之后就是OK的,下面是报错信息:


java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.smoothScrollTo(int, int)' on a null object reference



因为之前没有用到过这个方法,所以我就直接注释了,虽然是滑动布局,但是我觉的在输入框里的判断里加上这一行没有意思,若是大家有好的建议可以,欢迎赐教与我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值