知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
android自定義控件系列
發(fā)表時(shí)間:2020-10-19
發(fā)布人:葵宇科技
瀏覽次數(shù):29
說袈溱前面的話:
為什么要來說Scroller這個(gè)類呢?這個(gè)類到底是拿來干什么的呢?如不雅你看了ListView這類控件那么你肯定會(huì)發(fā)明瑯綾擎有一個(gè)Sroller類,其實(shí)它的感化就是幫助記錄和計(jì)算我們滑動(dòng)的距離和速度這些。大年夜而讓我們?cè)谧远x控件的時(shí)刻可以便利的做一些滑動(dòng)和回彈的動(dòng)畫,為什么呢?因?yàn)镾roller類都給你計(jì)算好了嘛。
類分析
public class Scroller { private int mMode; private int mStartX; private int mStartY; private int mFinalX; private int mFinalY; private int mMinX; private int mMaxX; private int mMinY; private int mMaxY; ...... /** * Call this when you want to know the new location. If it returns true, * the animation is not yet finished. */ public boolean computeScrollOffset() { if (mFinished) { return false; } int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); if (timePassed < mDuration) { switch (mMode) { case SCROLL_MODE: float x = timePassed * mDurationReciprocal; if (mInterpolator == null) x = viscousFluid(x); else x = mInterpolator.getInterpolation(x); mCurrX = mStartX + Math.round(x * mDeltaX); mCurrY = mStartY + Math.round(x * mDeltaY); break; case FLING_MODE: final float t = (float) timePassed / mDuration; final int index = (int) (NB_SAMPLES * t); float distanceCoef = 1.f; float velocityCoef = 0.f; if (index < NB_SAMPLES) { final float t_inf = (float) index / NB_SAMPLES; final float t_sup = (float) (index + 1) / NB_SAMPLES; final float d_inf = SPLINE_POSITION[index]; final float d_sup = SPLINE_POSITION[index + 1]; velocityCoef = (d_sup - d_inf) / (t_sup - t_inf); distanceCoef = d_inf + (t - t_inf) * velocityCoef; } mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f; mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); // Pin to mMinX <= mCurrX <= mMaxX mCurrX = Math.min(mCurrX, mMaxX); mCurrX = Math.max(mCurrX, mMinX); mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY)); // Pin to mMinY <= mCurrY <= mMaxY mCurrY = Math.min(mCurrY, mMaxY); mCurrY = Math.max(mCurrY, mMinY); if (mCurrX == mFinalX && mCurrY == mFinalY) { mFinished = true; } break; } } else { mCurrX = mFinalX; mCurrY = mFinalY; mFinished = true; } return true; } 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; } /** * Start scrolling based on a fling gesture. The distance travelled will * depend on the initial velocity of the fling. * * @param startX Starting point of the scroll (X) * @param startY Starting point of the scroll (Y) * @param velocityX Initial velocity of the fling (X) measured in pixels per * second. * @param velocityY Initial velocity of the fling (Y) measured in pixels per * second * @param minX Minimum X value. The scroller will not scroll past this * point. * @param maxX Maximum X value. The scroller will not scroll past this * point. * @param minY Minimum Y value. The scroller will not scroll past this * point. * @param maxY Maximum Y value. The scroller will not scroll past this * point. */ public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { // Continue a scroll or fling in progress if (mFlywheel && !mFinished) { float oldVel = getCurrVelocity(); float dx = (float) (mFinalX - mStartX); float dy = (float) (mFinalY - mStartY); float hyp = FloatMath.sqrt(dx * dx + dy * dy); float ndx = dx / hyp; float ndy = dy / hyp; float oldVelocityX = ndx * oldVel; float oldVelocityY = ndy * oldVel; if (Math.signum(velocityX) == Math.signum(oldVelocityX) && Math.signum(velocityY) == Math.signum(oldVelocityY)) { velocityX += oldVelocityX; velocityY += oldVelocityY; } } mMode = FLING_MODE; mFinished = false; float velocity = FloatMath.sqrt(velocityX * velocityX + velocityY * velocityY); mVelocity = velocity; mDuration = getSplineFlingDuration(velocity); mStartTime = AnimationUtils.currentAnimationTimeMillis(); mStartX = startX; mStartY = startY; float coeffX = velocity == 0 ? 1.0f : velocityX / velocity; float coeffY = velocity == 0 ? 1.0f : velocityY / velocity; double totalDistance = getSplineFlingDistance(velocity); mDistance = (int) (totalDistance * Math.signum(velocity)); mMinX = minX; mMaxX = maxX; mMinY = minY; mMaxY = maxY; mFinalX = startX + (int) Math.round(totalDistance * coeffX); // Pin to mMinX <= mFinalX <= mMaxX mFinalX = Math.min(mFinalX, mMaxX); mFinalX = Math.max(mFinalX, mMinX); mFinalY = startY + (int) Math.round(totalDistance * coeffY); // Pin to mMinY <= mFinalY <= mMaxY mFinalY = Math.min(mFinalY, mMaxY); mFinalY = Math.max(mFinalY, mMinY); } /** * Stops the animation. Contrary to {@link #forceFinished(boolean)}, * aborting the animating cause the scroller to move to the final x and y * position * * @see #forceFinished(boolean) */ public void abortAnimation() { mCurrX = mFinalX; mCurrY = mFinalY; mFinished = true; } ....膳綾擎我貼出來的類辦法都是常用的幾個(gè)辦法,這里我來分別解釋每個(gè)辦法的感化和用法,起首我們照樣來看computeScrollOffset()這個(gè)辦法吧,我們看到它的注釋 /**
* Call this when you want to know the new location. If it returns true,當(dāng)你想獲得一個(gè)新的地位的時(shí)刻call這個(gè)辦法。其實(shí)袈溱這個(gè)類瑯綾擎已經(jīng)給了我們一個(gè)很好的例子我這里也貼出來看看到底是怎么樣的?
* <p>To track the changing positions of the x/y coordinates, use * {@link #computeScrollOffset}. The method returns a boolean to indicate * whether the scroller is finished. If it isn't, it means that a fling or * programmatic pan operation is still in progress. You can use this method to * find the current offsets of the x and y coordinates, for example:</p> * * <pre>if (mScroller.computeScrollOffset()) { * // Get current x and y positions * int currX = mScroller.getCurrX(); * int currY = mScroller.getCurrY(); * ... * }</pre>google官方的注釋照樣挺給力的,我就不多說什么了,接著來看下一辦法。startScroll()這個(gè)辦法又該什么時(shí)刻用呢?又該在哪個(gè)處所用呢?其實(shí)我們須要做一個(gè)滑動(dòng)效不雅,我們就須要調(diào)用這個(gè)辦法贊助我們不時(shí)的計(jì)算我們當(dāng)前的地位。如許我們就不消本身去計(jì)算當(dāng)前的速度是若干當(dāng)前該走到哪里了。這里官方也給出了一個(gè)例子我們照樣來看看到底是怎么竽暌姑的?
<pre> private Scroller mScroller = new Scroller(context); * ... * public void zoomIn() { * // Revert any animation currently in progress * mScroller.forceFinished(true); * // Start scrolling by providing a starting point and * // the distance to travel * mScroller.startScroll(0, 0, 100, 0); * // Invalidate to request a redraw * invalidate(); * }</pre>
可以看到膳綾擎的代碼,注釋都很nice對(duì)紕謬?須要留意的是最后一行invalidate這個(gè)時(shí)刻須要我們手動(dòng)的去提議一次刷新請(qǐng)求,不然結(jié)不雅會(huì)跟你想得不一樣的。接下來就是fling()這個(gè)辦法,我們大年夜它的注釋可以讀出來是什么意思 /** * Start scrolling based on a fling gesture. The distance travelled will * depend on the initial velocity of the fling.根據(jù)你的手勢(shì)來滑動(dòng)一段距離取決于你的初速度,那么這個(gè)函數(shù)應(yīng)當(dāng)什么時(shí)刻調(diào)用呢?那么我來告訴你,listview是不是快速滑動(dòng)的時(shí)刻你會(huì)看到listview的視圖快速網(wǎng)上滑動(dòng)一些條目過后才會(huì)停止下來,就是在我們快速滑動(dòng)屏幕的時(shí)刻就調(diào)用這個(gè)函數(shù)。大年夜下一篇開端就要開端講拭魅戰(zhàn)了。
相關(guān)案例查看更多
相關(guān)閱讀
- typescript
- 百度快速排名
- 云南網(wǎng)站制作哪家好
- 百度自然排名
- 小程序分銷商城
- 云南網(wǎng)站建設(shè)
- 云南小程序開發(fā)哪家好
- 小程序技術(shù)
- 云南網(wǎng)站建設(shè)百度官方
- 網(wǎng)站建設(shè)列表網(wǎng)
- 全國(guó)前十名小程序開發(fā)公司
- 花農(nóng)小程序
- 百度小程序公司
- 小程序密鑰
- 昆明網(wǎng)站設(shè)計(jì)
- web開發(fā)
- 買小程序被騙
- 手機(jī)網(wǎng)站建設(shè)
- 小程序開發(fā)排名前十名
- 云南做網(wǎng)站
- 網(wǎng)站建設(shè)靠譜公司
- 報(bào)廢車回收管理系統(tǒng)
- 昆明軟件定制
- 大理小程序開發(fā)
- 汽車回收管理系統(tǒng)
- 網(wǎng)站優(yōu)化公司
- 云南網(wǎng)站建設(shè)電話
- 前端開發(fā)
- 網(wǎng)站優(yōu)化哪家好
- 霸屏推廣