日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > 綜合技術(shù) > Android翻頁效果原理實(shí)現(xiàn)之曲線的實(shí)現(xiàn)

Android翻頁效果原理實(shí)現(xiàn)之曲線的實(shí)現(xiàn)

來源:程序員人生   發(fā)布時(shí)間:2015-01-21 08:29:31 閱讀次數(shù):7203次

尊重原創(chuàng)轉(zhuǎn)載請注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵權(quán)必究!

炮兵鎮(zhèn)樓

上1節(jié)我們通過引入折線實(shí)現(xiàn)了頁面的折疊翻轉(zhuǎn)效果,有了前面兩節(jié)的基礎(chǔ)呢其實(shí)曲線的實(shí)現(xiàn)可以變得非常簡單,為何這么說呢?由于曲線不過就是在折線的基礎(chǔ)上對Path加入了曲線的實(shí)現(xiàn),進(jìn)而只是影響了我們的Region區(qū)域,而其他的甚么事件啊、滑動(dòng)計(jì)算啊之類的幾近都是不變的對吧,說白了就是對現(xiàn)有的折線View進(jìn)行update改造,雖然是改造,但是我們該如何下手呢?首先我們來看看現(xiàn)實(shí)中翻頁的效果應(yīng)當(dāng)是怎樣的呢?如果大家身旁有書或本子乃至1張紙也行,嘗試以不同的方式去翻動(dòng)它,你會(huì)發(fā)現(xiàn)除我們前面兩節(jié)曾提到過的1些限制外,還有1些special的現(xiàn)象:

1、翻起來的區(qū)域從側(cè)面來看是1個(gè)有弧度的區(qū)域,如圖所示側(cè)面圖:


而我們將依照第1節(jié)中的約定疏忽這部份弧度的表現(xiàn),由于從正俯視的角度我們壓根看不到弧度的效果,So~我們強(qiáng)迫讓其與頁面平行:


2、根據(jù)拖拽點(diǎn)距離頁面高度的不同,我們可以得到不同的卷曲度:


而其在我們正俯視點(diǎn)的表現(xiàn)則是曲線的弧度不同:


一樣的,我們依照第1節(jié)的約定,為了簡化問題,我們將拖拽點(diǎn)距離頁面的高度視為1個(gè)定值使在我們正俯視點(diǎn)表現(xiàn)的曲線出發(fā)點(diǎn)從距離控件交點(diǎn)1/4處開始:


3、如上1節(jié)末所說,在曲折的區(qū)域圖象也會(huì)有相似的扭曲效果

OK,大致的1個(gè)分析就是這樣,我們根據(jù)分析結(jié)果可以得出下面的1個(gè)分析圖:


由上圖配合我們上面的分析我們可知:DB = 1/4OB,F(xiàn)A = 1/4OA,而點(diǎn)F和點(diǎn)D分別為兩條曲線(如無特殊聲明,我們所說的曲線均為貝賽爾曲線,下同)的出發(fā)點(diǎn)(固然你也能夠說是終點(diǎn)無所謂),這時(shí)候,我們以點(diǎn)A、B為曲線的控制點(diǎn)并以其為端點(diǎn)分別沿著x軸和y軸方向作線段AG、BC,另AG = AF、BC = BD,并令點(diǎn)G、C分別為曲線的終點(diǎn),這樣,我們的這兩條2階貝塞爾曲線就非常非常的特殊,例如上圖中的曲線DC,它是由起始點(diǎn)D、C和控制點(diǎn)B構(gòu)成,而BD = BC,也就是說3角形BDC是的等腰3角形,進(jìn)1步地說就是曲線DC的兩條控制桿力臂相等,進(jìn)1步地我們可以推斷出曲線DC的頂點(diǎn)J一定在直線DC的中垂線上,更進(jìn)1步地我們可以根據(jù)《自定義控件其實(shí)很簡單5/12》所說的2階貝塞爾曲線公式得出當(dāng)且僅當(dāng)t = 0.5時(shí)曲線的端點(diǎn)恰好會(huì)在頂點(diǎn)J上,由此我們可以非常非常簡單地得到曲線的頂點(diǎn)坐標(biāo)。好了,YY歸YY我們還是要回歸到具體的操作中來,首先,我們要計(jì)算出點(diǎn)G、F、D、C的坐標(biāo)值,這4點(diǎn)坐標(biāo)也相當(dāng)easy,就拿F點(diǎn)坐標(biāo)來講,我們過點(diǎn)F分別作OM、AM的垂線:


由于FA = 1/4OA,那末我們可以得到F點(diǎn)的x坐標(biāo)Fx = a + 3/4MA,y坐標(biāo)Fy = b + 3/4OM,而G點(diǎn)的x坐標(biāo)Gx = a + MA - 1/4x;其他兩點(diǎn)D、C就不多扯了,那末在代碼中如何體現(xiàn)呢?首先,為了便于視察效果,我們先注釋掉圖片的繪制:

/* * 如果坐標(biāo)點(diǎn)在原點(diǎn)(即還沒產(chǎn)生觸碰時(shí))則繪制第1頁 */ if (mPointX == 0 && mPointY == 0) { // canvas.drawBitmap(mBitmaps.get(mBitmaps.size() - 1), 0, 0, null); return; } // 省略大量代碼 //drawBitmaps(canvas);
并繪制線條:

canvas.drawPath(mPath, mPaint);
在上1節(jié)中我們在生成Path時(shí)將情況分為了兩種:

if (sizeLong > mViewHeight) { //………………………… } else { //………………………… }
一樣,我們也分開處理兩種情況,那末針對sizeLong > mViewHeight的時(shí)候此時(shí)控件頂部的曲線效果已是看不到了,我們只需斟酌底部的曲線效果:

// 計(jì)算曲線出發(fā)點(diǎn) float startXBtm = btmX2 - CURVATURE * sizeShort; float startYBtm = mViewHeight; // 計(jì)算曲線終點(diǎn) float endXBtm = mPointX + (1 - CURVATURE) * (tempAM); float endYBtm = mPointY + (1 - CURVATURE) * mL; // 計(jì)算曲線控制點(diǎn) float controlXBtm = btmX2; float controlYBtm = mViewHeight; // 計(jì)算曲線頂點(diǎn) float bezierPeakXBtm = 0.25F * startXBtm + 0.5F * controlXBtm + 0.25F * endXBtm; float bezierPeakYBtm = 0.25F * startYBtm + 0.5F * controlYBtm + 0.25F * endYBtm; /* * 生成帶曲線的4邊形路徑 */ mPath.moveTo(startXBtm, startYBtm); mPath.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPath.lineTo(mPointX, mPointY); mPath.lineTo(topX1, 0); mPath.lineTo(topX2, 0); mPath.lineTo(bezierPeakXBtm, bezierPeakYBtm);
該部份的實(shí)際效果以下:


PS:為了便于大家對參數(shù)的理解,我對每個(gè)點(diǎn)的坐標(biāo)都重新給予了1個(gè)援用其命名也淺顯易懂,實(shí)際進(jìn)程可以省略這1步簡化代碼

而當(dāng)sizeLong <= mViewHeight時(shí)這時(shí)候候不但底部有曲線效果,右邊也有:

/* * 計(jì)算參數(shù) */ float leftY = mViewHeight - sizeLong; float btmX = mViewWidth - sizeShort; // 計(jì)算曲線出發(fā)點(diǎn) float startXBtm = btmX - CURVATURE * sizeShort; float startYBtm = mViewHeight; float startXLeft = mViewWidth; float startYLeft = leftY - CURVATURE * sizeLong; /* * 限制左邊曲線出發(fā)點(diǎn) */ if (startYLeft <= 0) { startYLeft = 0; } /* * 限制右邊曲線出發(fā)點(diǎn) */ if (startXBtm <= 0) { startXBtm = 0; } // 計(jì)算曲線終點(diǎn) float endXBtm = mPointX + (1 - CURVATURE) * (tempAM); float endYBtm = mPointY + (1 - CURVATURE) * mL; float endXLeft = mPointX + (1 - CURVATURE) * mK; float endYLeft = mPointY - (1 - CURVATURE) * (sizeLong - mL); // 計(jì)算曲線控制點(diǎn) float controlXBtm = btmX; float controlYBtm = mViewHeight; float controlXLeft = mViewWidth; float controlYLeft = leftY; // 計(jì)算曲線頂點(diǎn) float bezierPeakXBtm = 0.25F * startXBtm + 0.5F * controlXBtm + 0.25F * endXBtm; float bezierPeakYBtm = 0.25F * startYBtm + 0.5F * controlYBtm + 0.25F * endYBtm; float bezierPeakXLeft = 0.25F * startXLeft + 0.5F * controlXLeft + 0.25F * endXLeft; float bezierPeakYLeft = 0.25F * startYLeft + 0.5F * controlYLeft + 0.25F * endYLeft; /* * 生成帶曲線的3角形路徑 */ mPath.moveTo(startXBtm, startYBtm); mPath.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPath.lineTo(mPointX, mPointY); mPath.lineTo(endXLeft, endYLeft); mPath.quadTo(controlXLeft, controlYLeft, startXLeft, startYLeft);
效果以下:


Path有了,我們就該斟酌如何將其轉(zhuǎn)換為Region,在這個(gè)進(jìn)程中呢又1個(gè)問題,曲線路徑不像上1節(jié)的直線路徑我們可以輕易取得其范圍區(qū)域,由于我們的折疊區(qū)域其實(shí)應(yīng)當(dāng)是這樣的:


如圖所示紅色路徑區(qū)域,這部份區(qū)域則是我們折疊的區(qū)域,而事實(shí)上我們?yōu)榱擞?jì)算方便將整條2階貝賽爾曲線都繪制了出來,也就是說我們的Path除紅色線條部份還包括了藍(lán)色線條部份對吧,那末問題來了,如何將這兩部份“做掉”呢?其實(shí)方法很多,我們可以在計(jì)算的時(shí)候就只生成半條曲線,這是方法1我們利用純計(jì)算的方式,記得我在該系列文章開頭曾說過翻頁效果的實(shí)現(xiàn)可以有兩種方式,1種是純計(jì)算而另外一種則是利用圖形的組合思想,如何組合呢?這里對區(qū)域的計(jì)算我們就不用純計(jì)算的方式了,我們嘗試用圖形組合來試試。首先我們將Path轉(zhuǎn)為Region看看是甚么樣的:

Region region = computeRegion(mPath); canvas.clipRegion(region); canvas.drawColor(Color.RED); // canvas.drawPath(mPath, mPaint);
效果以下:


可以看到我們沒有封閉的Path構(gòu)成的Region效果,事實(shí)呢跟我們需要的區(qū)域差距有點(diǎn)大,首先上下兩個(gè)月半圓是過剩的,其次目測少了1塊對吧:


如上圖藍(lán)色的那塊,那末我們該如何把這塊“補(bǔ)”回來呢?利用圖形組合的思想,我們想法為該Region補(bǔ)1塊矩形:


然后差集掉兩個(gè)月半圓不就成了?這部份代碼改動(dòng)較大,我先貼代碼再說吧:

if (sizeLong > mViewHeight) { // 計(jì)算……額……按圖來AN邊~ float an = sizeLong - mViewHeight; // 3角形AMN的MN邊 float largerTrianShortSize = an / (sizeLong - (mViewHeight - mPointY)) * (mViewWidth - mPointX); // 3角形AQN的QN邊 float smallTrianShortSize = an / sizeLong * sizeShort; /* * 計(jì)算參數(shù) */ float topX1 = mViewWidth - largerTrianShortSize; float topX2 = mViewWidth - smallTrianShortSize; float btmX2 = mViewWidth - sizeShort; // 計(jì)算曲線出發(fā)點(diǎn) float startXBtm = btmX2 - CURVATURE * sizeShort; float startYBtm = mViewHeight; // 計(jì)算曲線終點(diǎn) float endXBtm = mPointX + (1 - CURVATURE) * (tempAM); float endYBtm = mPointY + (1 - CURVATURE) * mL; // 計(jì)算曲線控制點(diǎn) float controlXBtm = btmX2; float controlYBtm = mViewHeight; // 計(jì)算曲線頂點(diǎn) float bezierPeakXBtm = 0.25F * startXBtm + 0.5F * controlXBtm + 0.25F * endXBtm; float bezierPeakYBtm = 0.25F * startYBtm + 0.5F * controlYBtm + 0.25F * endYBtm; /* * 生成帶曲線的4邊形路徑 */ mPath.moveTo(startXBtm, startYBtm); mPath.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPath.lineTo(mPointX, mPointY); mPath.lineTo(topX1, 0); mPath.lineTo(topX2, 0); /* * 替補(bǔ)區(qū)域Path */ mPathTrap.moveTo(startXBtm, startYBtm); mPathTrap.lineTo(topX2, 0); mPathTrap.lineTo(bezierPeakXBtm, bezierPeakYBtm); mPathTrap.close(); /* * 底部月半圓Path */ mPathSemicircleBtm.moveTo(startXBtm, startYBtm); mPathSemicircleBtm.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPathSemicircleBtm.close(); /* * 生成包括折疊和下1頁的路徑 */ //暫時(shí)沒用省略掉 // 計(jì)算月半圓區(qū)域 mRegionSemicircle = computeRegion(mPathSemicircleBtm); } else { /* * 計(jì)算參數(shù) */ float leftY = mViewHeight - sizeLong; float btmX = mViewWidth - sizeShort; // 計(jì)算曲線出發(fā)點(diǎn) float startXBtm = btmX - CURVATURE * sizeShort; float startYBtm = mViewHeight; float startXLeft = mViewWidth; float startYLeft = leftY - CURVATURE * sizeLong; // 計(jì)算曲線終點(diǎn) float endXBtm = mPointX + (1 - CURVATURE) * (tempAM); float endYBtm = mPointY + (1 - CURVATURE) * mL; float endXLeft = mPointX + (1 - CURVATURE) * mK; float endYLeft = mPointY - (1 - CURVATURE) * (sizeLong - mL); // 計(jì)算曲線控制點(diǎn) float controlXBtm = btmX; float controlYBtm = mViewHeight; float controlXLeft = mViewWidth; float controlYLeft = leftY; // 計(jì)算曲線頂點(diǎn) float bezierPeakXBtm = 0.25F * startXBtm + 0.5F * controlXBtm + 0.25F * endXBtm; float bezierPeakYBtm = 0.25F * startYBtm + 0.5F * controlYBtm + 0.25F * endYBtm; float bezierPeakXLeft = 0.25F * startXLeft + 0.5F * controlXLeft + 0.25F * endXLeft; float bezierPeakYLeft = 0.25F * startYLeft + 0.5F * controlYLeft + 0.25F * endYLeft; /* * 限制右邊曲線出發(fā)點(diǎn) */ if (startYLeft <= 0) { startYLeft = 0; } /* * 限制底部左邊曲線出發(fā)點(diǎn) */ if (startXBtm <= 0) { startXBtm = 0; } /* * 根據(jù)底部左邊限制點(diǎn)重新計(jì)算貝塞爾曲線頂點(diǎn)坐標(biāo) */ float partOfShortLength = CURVATURE * sizeShort; if (btmX >= -mValueAdded && btmX <= partOfShortLength - mValueAdded) { float f = btmX / partOfShortLength; float t = 0.5F * f; float bezierPeakTemp = 1 - t; float bezierPeakTemp1 = bezierPeakTemp * bezierPeakTemp; float bezierPeakTemp2 = 2 * t * bezierPeakTemp; float bezierPeakTemp3 = t * t; bezierPeakXBtm = bezierPeakTemp1 * startXBtm + bezierPeakTemp2 * controlXBtm + bezierPeakTemp3 * endXBtm; bezierPeakYBtm = bezierPeakTemp1 * startYBtm + bezierPeakTemp2 * controlYBtm + bezierPeakTemp3 * endYBtm; } /* * 根據(jù)右邊限制點(diǎn)重新計(jì)算貝塞爾曲線頂點(diǎn)坐標(biāo) */ float partOfLongLength = CURVATURE * sizeLong; if (leftY >= -mValueAdded && leftY <= partOfLongLength - mValueAdded) { float f = leftY / partOfLongLength; float t = 0.5F * f; float bezierPeakTemp = 1 - t; float bezierPeakTemp1 = bezierPeakTemp * bezierPeakTemp; float bezierPeakTemp2 = 2 * t * bezierPeakTemp; float bezierPeakTemp3 = t * t; bezierPeakXLeft = bezierPeakTemp1 * startXLeft + bezierPeakTemp2 * controlXLeft + bezierPeakTemp3 * endXLeft; bezierPeakYLeft = bezierPeakTemp1 * startYLeft + bezierPeakTemp2 * controlYLeft + bezierPeakTemp3 * endYLeft; } /* * 替補(bǔ)區(qū)域Path */ mPathTrap.moveTo(startXBtm, startYBtm); mPathTrap.lineTo(startXLeft, startYLeft); mPathTrap.lineTo(bezierPeakXLeft, bezierPeakYLeft); mPathTrap.lineTo(bezierPeakXBtm, bezierPeakYBtm); mPathTrap.close(); /* * 生成帶曲線的3角形路徑 */ mPath.moveTo(startXBtm, startYBtm); mPath.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPath.lineTo(mPointX, mPointY); mPath.lineTo(endXLeft, endYLeft); mPath.quadTo(controlXLeft, controlYLeft, startXLeft, startYLeft); /* * 生成底部月半圓的Path */ mPathSemicircleBtm.moveTo(startXBtm, startYBtm); mPathSemicircleBtm.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPathSemicircleBtm.close(); /* * 生成右邊月半圓的Path */ mPathSemicircleLeft.moveTo(endXLeft, endYLeft); mPathSemicircleLeft.quadTo(controlXLeft, controlYLeft, startXLeft, startYLeft); mPathSemicircleLeft.close(); /* * 生成包括折疊和下1頁的路徑 */ //暫時(shí)沒用省略掉 /* * 計(jì)算底部和右邊兩月半圓區(qū)域 */ Region regionSemicircleBtm = computeRegion(mPathSemicircleBtm); Region regionSemicircleLeft = computeRegion(mPathSemicircleLeft); // 合并兩月半圓區(qū)域 mRegionSemicircle.op(regionSemicircleBtm, regionSemicircleLeft, Region.Op.UNION); } // 根據(jù)Path生成的折疊區(qū)域 Region regioFlod = computeRegion(mPath); // 替補(bǔ)區(qū)域 Region regionTrap = computeRegion(mPathTrap); // 令折疊區(qū)域與替補(bǔ)區(qū)域相加 regioFlod.op(regionTrap, Region.Op.UNION); // 從相加后的區(qū)域中剔除掉月半圓的區(qū)域取得終究折疊區(qū)域 regioFlod.op(mRegionSemicircle, Region.Op.DIFFERENCE); /* * 根據(jù)裁剪區(qū)域填充畫布 */ canvas.clipRegion(regioFlod); canvas.drawColor(Color.RED);
200行的代碼我們就做了1件事就是正確計(jì)算Path,一樣我們還是依照之前的分了兩種情況來計(jì)算,第1種情況sizeLong > mViewHeight時(shí),我們先計(jì)算替補(bǔ)的這塊區(qū)域:


如上代碼46⑷9行

/* * 替補(bǔ)區(qū)域Path */ mPathTrap.moveTo(startXBtm, startYBtm); mPathTrap.lineTo(topX2, 0); mPathTrap.lineTo(bezierPeakXBtm, bezierPeakYBtm); mPathTrap.close();
然后計(jì)算底部的月半圓Path:


對應(yīng)代碼54⑸6行

/* * 底部月半圓Path */ mPathSemicircleBtm.moveTo(startXBtm, startYBtm); mPathSemicircleBtm.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPathSemicircleBtm.close();
將當(dāng)前折疊區(qū)域和替補(bǔ)區(qū)域相加再減去月半圓Path區(qū)域我們就能夠得到正確的折疊區(qū)域,對應(yīng)代碼64行和192⑵01行:

// 計(jì)算月半圓區(qū)域 mRegionSemicircle = computeRegion(mPathSemicircleBtm); // ………………中間省略巨量代碼……………… // 根據(jù)Path生成的折疊區(qū)域 Region regioFlod = computeRegion(mPath); // 替補(bǔ)區(qū)域 Region regionTrap = computeRegion(mPathTrap); // 令折疊區(qū)域與替補(bǔ)區(qū)域相加 regioFlod.op(regionTrap, Region.Op.UNION); // 從相加后的區(qū)域中剔除掉月半圓的區(qū)域取得終究折疊區(qū)域 regioFlod.op(mRegionSemicircle, Region.Op.DIFFERENCE);
該情況下我們的折疊區(qū)域是醬紫的:


兩1種情況則略微復(fù)雜些,除要計(jì)算底部,我們還要計(jì)算右邊的月半圓Path區(qū)域,代碼165⑴74:

/* * 生成底部月半圓的Path */ mPathSemicircleBtm.moveTo(startXBtm, startYBtm); mPathSemicircleBtm.quadTo(controlXBtm, controlYBtm, endXBtm, endYBtm); mPathSemicircleBtm.close(); /* * 生成右邊月半圓的Path */ mPathSemicircleLeft.moveTo(endXLeft, endYLeft); mPathSemicircleLeft.quadTo(controlXLeft, controlYLeft, startXLeft, startYLeft); mPathSemicircleLeft.close(); 替補(bǔ)區(qū)域的計(jì)算,147⑴51: /* * 替補(bǔ)區(qū)域Path */ mPathTrap.moveTo(startXBtm, startYBtm); mPathTrap.lineTo(startXLeft, startYLeft); mPathTrap.lineTo(bezierPeakXLeft, bezierPeakYLeft); mPathTrap.lineTo(bezierPeakXBtm, bezierPeakYBtm); mPathTrap.close(); 區(qū)域的轉(zhuǎn)換,184⑴88: /* * 計(jì)算底部和右邊兩月半圓區(qū)域 */ Region regionSemicircleBtm = computeRegion(mPathSemicircleBtm); Region regionSemicircleLeft = computeRegion(mPathSemicircleLeft); // 合并兩月半圓區(qū)域 mRegionSemicircle.op(regionSemicircleBtm, regionSemicircleLeft, Region.Op.UNION);
終究的計(jì)算跟上面第1種情況1樣,效果以下:


結(jié)合兩種情況,我們可以得到下面的效果:


然后,我們需要計(jì)算“下1頁”的區(qū)域,一樣,根據(jù)上1節(jié)我們的講授,我們先獲得折疊區(qū)域和下1頁區(qū)域之和再減去折疊區(qū)域就能夠得到下1頁的區(qū)域:

mRegionNext = computeRegion(mPathFoldAndNext); mRegionNext.op(mRegionFold, Region.Op.DIFFERENCE);
繪制效果以下:


最后,我們結(jié)合上兩節(jié),注入數(shù)據(jù):

/** * 繪制位圖數(shù)據(jù) * * @param canvas * 畫布對象 */ private void drawBitmaps(Canvas canvas) { // 繪制位圖前重置isLastPage為false isLastPage = false; // 限制pageIndex的值范圍 mPageIndex = mPageIndex < 0 ? 0 : mPageIndex; mPageIndex = mPageIndex > mBitmaps.size() ? mBitmaps.size() : mPageIndex; // 計(jì)算數(shù)據(jù)起始位置 int start = mBitmaps.size() - 2 - mPageIndex; int end = mBitmaps.size() - mPageIndex; /* * 如果數(shù)據(jù)出發(fā)點(diǎn)位置小于0則表示當(dāng)前已到了最后1張圖片 */ if (start < 0) { // 此時(shí)設(shè)置isLastPage為true isLastPage = true; // 并顯示提示信息 showToast("This is fucking lastest page"); // 強(qiáng)迫重置起始位置 start = 0; end = 1; } /* * 計(jì)算當(dāng)前頁的區(qū)域 */ canvas.save(); canvas.clipRegion(mRegionCurrent); canvas.drawBitmap(mBitmaps.get(end - 1), 0, 0, null); canvas.restore(); /* * 計(jì)算折疊頁的區(qū)域 */ canvas.save(); canvas.clipRegion(mRegionFold); canvas.translate(mPointX, mPointY); /* * 根據(jù)長短邊標(biāo)識(shí)計(jì)算折疊區(qū)域圖象 */ if (mRatio == Ratio.SHORT) { canvas.rotate(90 - mDegrees); canvas.translate(0, -mViewHeight); canvas.scale(⑴, 1); canvas.translate(-mViewWidth, 0); } else { canvas.rotate(-(90 - mDegrees)); canvas.translate(-mViewWidth, 0); canvas.scale(1, ⑴); canvas.translate(0, -mViewHeight); } canvas.drawBitmap(mBitmaps.get(end - 1), 0, 0, null); canvas.restore(); /* * 計(jì)算下1頁的區(qū)域 */ canvas.save(); canvas.clipRegion(mRegionNext); canvas.drawBitmap(mBitmaps.get(start), 0, 0, null); canvas.restore(); }
終究效果以下:


該部份的代碼就不貼出了,大部份跟上1節(jié)相同,由于過兩天要去旅游時(shí)間略緊這節(jié)略講得粗糙,不過也沒甚么太大的改動(dòng),如果大家有不懂的地方可以留言或群里@哥,下1節(jié)我們將嘗試實(shí)現(xiàn)翻頁時(shí)圖象扭曲的效果。

源碼地址:傳送門

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 97视频免费播放 | 精品视频免费观看 | 91啦在线观看 | 免费嗨片网 | 日本精品视频一区二区 | 精品国产一| www.99re| 欧美亚洲另类视频 | 成人性生交大片免费网站 | 久热国产精品视频一区二区三区 | 九九av | 久久国产在线观看 | 二区视频在线 | 色嗨嗨av一区二区三区 | 成人在线国产 | 丁香午夜 | 亚洲色图19p| 成人免费视 | 在线免费观看av网站 | 五月婷婷综合色 | 免费人成网ww44kk44 | 又黄又湿的网站 | 黄视频在线免费看 | 欧美一区二区国产 | 国产激情美女久久久久久吹潮 | 美女久久 | 懂色av一区二区 | 国产九九精品 | 国产精品久久久久久久va果冻 | 成人av观看 | 久久av网站 | 日韩视频在线观看免费 | 国产视频一二区 | 91在线精品秘密一区二区 | 丁香激情视频 | 俺去俺来也www色官网cms | 久久久久久一区二区三区四区别墅 | 国产一区二区毛片 | 操操网 | 久草小视频| 一区二区成人在线 |