flipboard的翻页效果的实现

来源:互联网 发布:网络使人疏远二辩问题 编辑:程序博客网 时间:2024/04/27 20:16
401人阅读评论(0)收藏举报

最近看到flipboard的翻页效果很不错,就想着把他给实现,整个效果做的差不多了,还有一些细节要完善,现在放上来。我学android全靠自学的,而且的代码的质量也难保证,还希望各位大神批评指正那。

核心源码放一部分,我顺便到github上那个开源工程去。哈哈。

主要利用的原理还是通过拉伸图片实现类似三维沿着Y轴方向翻转的效果,

我说下我的原理,假如一张图片,如图1,我对他进行宽度拉伸,和高度压缩,图片看起来,就好像是沿坐标轴Y轴翻转了一样,


实现这个效果,在加上适当的光效,就可以很好的模拟了。整个的效果,我主要仿着flipboar我主要是用了

google的apidemos里面的PolyToPoly里面的方法,通过控制四个点的位置,来实现。主要用的方法就

是matrix.setPloyToPloy()。



[html] view plaincopyprint?
  1. package com.iobee.ui;
  2. import java.util.Timer;
  3. import java.util.TimerTask;
  4. import com.iobee.activity.R;
  5. import android.content.Context;
  6. import android.graphics.Bitmap;
  7. import android.graphics.BitmapFactory;
  8. import android.graphics.Canvas;
  9. import android.graphics.Color;
  10. import android.graphics.ColorFilter;
  11. import android.graphics.ColorMatrix;
  12. import android.graphics.ColorMatrixColorFilter;
  13. import android.graphics.Matrix;
  14. import android.graphics.Paint;
  15. import android.graphics.PaintFlagsDrawFilter;
  16. import android.graphics.Path;
  17. import android.graphics.Region;
  18. import android.graphics.drawable.GradientDrawable;
  19. import android.util.Log;
  20. import android.view.MotionEvent;
  21. import android.view.View;
  22. /**
  23. * 采用src更改点的位置,进行拉升类实现3d翻转效果。
  24. * @author iobee
  25. *
  26. */
  27. public class flipboardviewSrc extends View{
  28. private final static String TAG = "flipboardViewSrc";
  29. //当开始翻转时,激发翻转程序,生成翻转效果用的上下两张bitmap
  30. private Bitmap downBitmap;
  31. private Bitmap upBitmap;
  32. private Bitmap currentBitmap;
  33. private Bitmap bitmap;
  34. private Bitmap grayBitmap;
  35. //对翻转时需要进行设置的一些类
  36. private Matrix UpMatrix; //矩阵
  37. private Matrix DownMatrix;
  38. private Paint paint; //绘制bitmap时的一些属性设计
  39. private Paint paintGray;
  40. private Canvas canvas; //画布
  41. private Path path;
  42. //翻转时,需要固定的一些点
  43. private int centerX,centerY;
  44. private int mscreenY,mscreenX; //当前手机屏幕的宽和高
  45. private float deltaX,deltaY;
  46. private float firstX,firstY;
  47. private int testY;
  48. //shadow
  49. private int[] gradientShadow;
  50. private GradientDrawable gradientdrawable;
  51. private ColorMatrix colormatrix;
  52. //private float[] src = {0,480,640,480,60,960,580,960};
  53. //private float[] dst = {0,480,640,480,5,560,640,560};
  54. private float baseY = 0;
  55. private int UpOrDown; //判断是上翻还是下翻
  56. private Timer time;
  57. public flipboardviewSrc(Context context) {
  58. super(context);
  59. // TODO Auto-generated constructor stub
  60. creatBitmap();
  61. initCanvas();
  62. }
  63. /**
  64. * 生成bitmap
  65. */
  66. public void creatBitmap(){
  67. upBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_right);
  68. downBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_960_640);
  69. grayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mask_gray);
  70. currentBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test2);
  71. bitmap = currentBitmap;
  72. }
  73. /**
  74. * 初始化画布绘制的一些数据
  75. */
  76. public void initCanvas(){
  77. mscreenX = 480;
  78. mscreenY = 854;
  79. centerX = mscreenX/2;
  80. centerY = mscreenY/2;
  81. paint = new Paint();
  82. paint.setAntiAlias(true);
  83. paintGray = new Paint();
  84. paintGray.setAntiAlias(true);
  85. paintGray.setAlpha(0);
  86. //src = new Float[]{0,480};
  87. UpMatrix = new Matrix();
  88. DownMatrix = new Matrix();
  89. colormatrix = new ColorMatrix();
  90. colormatrix.set(new float[] {
  91. 1, 0, 0, 0, 0,
  92. 0, 1, 0, 0, 0,
  93. 0, 0, 1, 0, 0,
  94. 0, 0, 0, 1, 0 });
  95. //paint.setColorFilter(new ColorMatrixColorFilter(colormatrix));
  96. gradientShadow = new int[]{0xFF000000,0xFF000000};
  97. gradientdrawable = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, gradientShadow);
  98. gradientdrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
  99. //设置矩形path,分隔图片用
  100. path = new Path();
  101. path.moveTo(0, 0);
  102. path.lineTo(mscreenX, 0);
  103. path.lineTo(mscreenX,centerY);
  104. path.lineTo(0, centerY);
  105. path.close();
  106. }
  107. /**
  108. * 自动翻转
  109. * @param delta
  110. */
  111. public void autoUpdate(){
  112. time = new Timer();
  113. TimerTask task = new TimerTask() {
  114. @Override
  115. public void run() {
  116. // TODO Auto-generated method stub
  117. if(Math.abs(testY) < mscreenY){
  118. if(UpOrDown == 1)
  119. testY += 10;
  120. else if(UpOrDown == 2)
  121. testY -=10;
  122. Log.i(TAG, "testY-->"+testY);
  123. taskManager(testY);
  124. }
  125. else
  126. time.cancel();
  127. }
  128. };
  129. time.schedule(task, 0, 10);
  130. }
  131. /**
  132. * 对用户操作行为进行分析并作出相应行为反馈
  133. */
  134. public void taskManager(float deltaY){
  135. float multiple,currentY = 0,currentX =0,initY;
  136. int currentAlpha = 0;
  137. if(UpOrDown == 0)
  138. if(deltaY >0)
  139. UpOrDown = 1;
  140. else if(deltaY <0)
  141. UpOrDown = 2;
  142. if(UpOrDown == 1){ //如果下翻,计算Y点的坐标和X点坐标
  143. multiple = (mscreenY - baseY)/(firstY - baseY); //获取初始距离的倍数,用来计算Y方向到哪里
  144. currentY = mscreenY - deltaY*multiple;
  145. if(currentY > mscreenY)
  146. currentY = mscreenY;
  147. if(currentY < 0)
  148. currentY = 0;
  149. }
  150. else if(UpOrDown == 2 ){
  151. multiple = (mscreenY - baseY)/(mscreenY-baseY-firstY);
  152. if(deltaY > 0)
  153. deltaY = 0;
  154. currentY = Math.abs(deltaY)*multiple;
  155. if(currentY > mscreenY)
  156. currentY = mscreenY;
  157. Log.i(TAG, "currentY-->"+currentY);
  158. }
  159. //如果Y点在下半个屏幕
  160. if(currentY > centerY){
  161. initY = mscreenY;
  162. if(UpOrDown == 1)
  163. bitmap = currentBitmap;
  164. else if(UpOrDown == 2)
  165. bitmap = upBitmap;
  166. currentX = (currentY - centerY)/7;
  167. currentAlpha = (int) ((mscreenY - currentY)/2);
  168. gradientdrawable.setBounds(0, centerY, mscreenX, mscreenY);
  169. }
  170. else{ //如果Y点在上半个屏幕
  171. initY = 0;
  172. if(UpOrDown == 1)
  173. bitmap = downBitmap;
  174. else if(UpOrDown == 2)
  175. bitmap = currentBitmap;
  176. currentX = (centerY - currentY)/7;
  177. currentAlpha = (int) (currentY/2);
  178. gradientdrawable.setBounds(0, 0, mscreenX, centerY);
  179. }
  180. float[] dst = {0,centerY,mscreenX,centerY,currentX,currentY,mscreenX-currentX,currentY};
  181. float[] src = {0,centerY,mscreenX,centerY,61,initY,mscreenX-61,initY};
  182. UpMatrix.setPolyToPoly(src, 0, dst, 0, src.length>>1);
  183. //设置透明度
  184. //int currentAlpha = (int) ((960 - currentY)/2);
  185. paintGray.setAlpha(currentAlpha);
  186. gradientdrawable.setAlpha(255 - currentAlpha);
  187. postInvalidate();
  188. }
  189. public void updateView(Canvas canvas){
  190. if(UpOrDown == 1 || UpOrDown ==0){
  191. canvas.save();
  192. canvas.clipPath(path,Region.Op.DIFFERENCE);
  193. canvas.drawBitmap(downBitmap, DownMatrix, paint);
  194. if(bitmap == currentBitmap){
  195. gradientdrawable.draw(canvas);
  196. canvas.drawBitmap(bitmap, UpMatrix, paint);
  197. canvas.drawBitmap(grayBitmap, UpMatrix, paintGray);
  198. }
  199. canvas.restore();
  200. canvas.save();
  201. canvas.clipPath(path,Region.Op.INTERSECT);
  202. canvas.drawBitmap(currentBitmap, DownMatrix, paint);
  203. if(bitmap == downBitmap){
  204. gradientdrawable.draw(canvas);
  205. canvas.drawBitmap(bitmap, UpMatrix, paint);
  206. canvas.drawBitmap(grayBitmap, DownMatrix, paintGray);
  207. }
  208. canvas.restore();
  209. }
  210. if(UpOrDown == 2){
  211. canvas.save();
  212. canvas.clipPath(path,Region.Op.DIFFERENCE);
  213. canvas.drawBitmap(currentBitmap, DownMatrix, paint);
  214. if(bitmap == upBitmap){
  215. gradientdrawable.draw(canvas);
  216. canvas.drawBitmap(bitmap, UpMatrix, paint);
  217. canvas.drawBitmap(grayBitmap, UpMatrix, paintGray);
  218. }
  219. canvas.restore();
  220. canvas.save();
  221. canvas.clipPath(path,Region.Op.INTERSECT);
  222. canvas.drawBitmap(upBitmap, DownMatrix, paint);
  223. if(bitmap == currentBitmap){
  224. gradientdrawable.draw(canvas);
  225. canvas.drawBitmap(bitmap, UpMatrix, paint);
  226. canvas.drawBitmap(grayBitmap, UpMatrix, paintGray);
  227. }
  228. canvas.restore();
  229. }
  230. }
  231. @Override
  232. protected void dispatchDraw(Canvas canvas) {
  233. // TODO Auto-generated method stub
  234. super.dispatchDraw(canvas);
  235. canvas.drawColor(Color.YELLOW);
  236. canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
  237. updateView(canvas);
  238. }
  239. @Override
  240. public boolean onTouchEvent(MotionEvent event) {
  241. // TODO Auto-generated method stub
  242. Log.i(TAG, "ontouchevent");
  243. float mLastMotionX = event.getX();
  244. float mLastMotionY = event.getY();
  245. Log.i(TAG, "mLastMotionY-->"+mLastMotionY);
  246. Log.i(TAG, "firstY-->"+firstY);
  247. switch (event.getAction()) {
  248. case MotionEvent.ACTION_DOWN:
  249. Log.i(TAG, "action_down");
  250. firstY = mLastMotionY;
  251. UpOrDown = 0;
  252. break;
  253. case MotionEvent.ACTION_MOVE:
  254. Log.i(TAG, "action_move");
  255. deltaY = firstY - mLastMotionY;
  256. Log.i(TAG, deltaY+"");
  257. taskManager(deltaY);
  258. break;
  259. case MotionEvent.ACTION_UP:
  260. Log.i(TAG, "event.up");
  261. testY = (int) deltaY;
  262. autoUpdate();
  263. //taskManager(0);
  264. break;
  265. default:
  266. break;
  267. }
  268. return true;
  269. }
  270. }


最近看到flipboard的翻页效果很不错,就想着把他给实现,整个效果做的差不多了,还有一些细节要完善,现在放上来。我学android全靠自学的,而且的代码的质量也难保证,还希望各位大神批评指正那。我把工程文件上传到了http://download.csdn.net/detail/iobee/4388778这个csdn了。大家可以去下载哦。
原创粉丝点击