http://blog.csdn.net/wangjinyu501/article/details/39527021

http://blog.csdn.net/wangjinyu501/article/details/39527021

http://blog.csdn.net/wangjinyu501/article/details/39527021

http://blog.csdn.net/wangjinyu501/article/details/39527021

http://blog.csdn.net/wangjinyu501/article/details/39527021

http://blog.csdn.net/wangjinyu501/article/details/39527021









Android 分享一个流量显示界面

分类:Android 1204人阅读 评论(7) 收藏 举报 版本:1.0 日期:2014.8.9 2014.9.24 版权:© 2014 kince 转载注明出处
波形效果有几种不同的呈现形式,比如从中间向四周散开的波形,也就是熟知的水涟漪;还有上下波动的曲线,像五线谱等。英文中可以称作Wave或者Ripple,所以暂且叫它们WaveView、WaveLayout、RippleView、RippleLayout,接下来开始实现这些效果。 首先看一下Solo 火爆足球动态壁纸, Android 分享一个流量显示界面_第1张图片
下面中间的按钮就是一个波形按钮,它会不断地向四周辐射,由于是静态图,如果想体验真实效果可以另行下载。这种效果的实现思路是不断绘制圆形,当然半径也要不断变化,透明度也是一样。代码如下: [html] view plain copy
  1. /**
  2. *
  3. */
  4. packagecom.kince.rippleview;
  5. importandroid.content.Context;
  6. importandroid.graphics.Bitmap;
  7. importandroid.graphics.BitmapFactory;
  8. importandroid.graphics.Canvas;
  9. importandroid.graphics.Color;
  10. importandroid.graphics.Paint;
  11. importandroid.graphics.RectF;
  12. importandroid.os.Handler;
  13. importandroid.os.Message;
  14. importandroid.util.AttributeSet;
  15. importandroid.view.View;
  16. /**
  17. *@authorkince
  18. *@category波纹
  19. *@since2014.8.9
  20. *@versionv1.0.0
  21. *
  22. */
  23. publicclassRippleViewextendsView{
  24. privateintmScreenWidth;
  25. privateintmScreenHeight;
  26. privateBitmapmRippleBitmap;
  27. privatePaintmRipplePaint=newPaint();
  28. privateintmBitmapWidth;
  29. privateintmBitmapHeight;
  30. privatebooleanisStartRipple;
  31. privateintheightPaddingTop;
  32. privateintheightPaddingBottom;
  33. privateintwidthPaddingLeft;
  34. privateintwidthPaddingRight;
  35. privateRectFmRect=newRectF();
  36. privateintrippleFirstRadius=0;
  37. privateintrippleSecendRadius=-33;
  38. privateintrippleThirdRadius=-66;
  39. privatePainttextPaint=newPaint();
  40. privateStringmText="点击我吧";
  41. privateHandlerhandler=newHandler(){
  42. @Override
  43. publicvoidhandleMessage(Messagemsg){
  44. //TODOAuto-generatedmethodstub
  45. super.handleMessage(msg);
  46. invalidate();
  47. if(isStartRipple){
  48. rippleFirstRadius++;
  49. if(rippleFirstRadius>100){
  50. rippleFirstRadius=0;
  51. }
  52. rippleSecendRadius++;
  53. if(rippleSecendRadius>100){
  54. rippleSecendRadius=0;
  55. }
  56. rippleThirdRadius++;
  57. if(rippleThirdRadius>100){
  58. rippleThirdRadius=0;
  59. }
  60. sendEmptyMessageDelayed(0,20);
  61. }
  62. }
  63. };
  64. /**
  65. *@paramcontext
  66. */
  67. publicRippleView(Contextcontext){
  68. super(context);
  69. //TODOAuto-generatedconstructorstub
  70. init();
  71. }
  72. /**
  73. *@paramcontext
  74. *@paramattrs
  75. */
  76. publicRippleView(Contextcontext,AttributeSetattrs){
  77. super(context,attrs);
  78. //TODOAuto-generatedconstructorstub
  79. init();
  80. }
  81. /**
  82. *@paramcontext
  83. *@paramattrs
  84. *@paramdefStyleAttr
  85. */
  86. publicRippleView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
  87. super(context,attrs,defStyleAttr);
  88. //TODOAuto-generatedconstructorstub
  89. init();
  90. }
  91. privatevoidinit(){
  92. mRipplePaint.setColor(4961729);
  93. mRipplePaint.setAntiAlias(true);
  94. mRipplePaint.setStyle(Paint.Style.FILL);
  95. textPaint.setTextSize(26);
  96. textPaint.setAntiAlias(true);
  97. textPaint.setStyle(Paint.Style.FILL);
  98. textPaint.setColor(Color.WHITE);
  99. mRippleBitmap=BitmapFactory.decodeStream(getResources()
  100. .openRawResource(R.drawable.easy3d_ic_apply));
  101. mBitmapWidth=mRippleBitmap.getWidth();
  102. mBitmapHeight=mRippleBitmap.getHeight();
  103. }
  104. @Override
  105. protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
  106. //TODOAuto-generatedmethodstub
  107. super.onMeasure(widthMeasureSpec,heightMeasureSpec);
  108. intmh=getMeasuredHeight()-getPaddingTop()-getPaddingBottom();
  109. intmw=getMeasuredWidth()-getPaddingLeft()-getPaddingRight();
  110. if(mBitmapWidth<2*mBitmapHeight){
  111. mBitmapWidth=(2*mBitmapHeight);
  112. }
  113. setMeasuredDimension(mBitmapWidth,mBitmapHeight);
  114. }
  115. @Override
  116. protectedvoidonDraw(Canvascanvas){
  117. //TODOAuto-generatedmethodstub
  118. super.onDraw(canvas);
  119. if(isStartRipple){
  120. floatf1=3*mBitmapHeight/10;
  121. mRipplePaint.setAlpha(255);
  122. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,
  123. 7*mBitmapHeight/10,mRipplePaint);
  124. inti1=(int)(220.0F-(220.0F-0.0F)/100.0F
  125. *rippleFirstRadius);
  126. mRipplePaint.setAlpha(i1);
  127. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,7
  128. *mBitmapHeight/10+f1*rippleFirstRadius/100.0F,
  129. mRipplePaint);
  130. if(rippleSecendRadius>=0){
  131. inti3=(int)(220.0F-(220.0F-0.0F)/100.0F
  132. *rippleSecendRadius);
  133. mRipplePaint.setAlpha(i3);
  134. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,
  135. 7*mBitmapHeight/10+f1*rippleSecendRadius
  136. /100.0F,mRipplePaint);
  137. }
  138. if(rippleThirdRadius>=0){
  139. inti2=(int)(220.0F-(220.0F-0.0F)/100.0F
  140. *rippleThirdRadius);
  141. mRipplePaint.setAlpha(i2);
  142. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,7
  143. *mBitmapHeight/10+f1*rippleThirdRadius/100.0F,
  144. mRipplePaint);
  145. }
  146. }
  147. mRipplePaint.setAlpha(30);
  148. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,mBitmapHeight,
  149. mRipplePaint);
  150. mRipplePaint.setAlpha(120);
  151. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,
  152. 9*mBitmapHeight/10,mRipplePaint);
  153. mRipplePaint.setAlpha(180);
  154. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,
  155. 8*mBitmapHeight/10,mRipplePaint);
  156. mRipplePaint.setAlpha(255);
  157. canvas.drawCircle(mBitmapWidth/2,mBitmapHeight,
  158. 7*mBitmapHeight/10,mRipplePaint);
  159. floatlength=textPaint.measureText(mText);
  160. canvas.drawText(mText,(mBitmapWidth-length)/2,
  161. mBitmapHeight*3/4,textPaint);
  162. }
  163. @Override
  164. protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
  165. //TODOAuto-generatedmethodstub
  166. super.onSizeChanged(w,h,oldw,oldh);
  167. mScreenWidth=w;
  168. mScreenHeight=h;
  169. confirmSize();
  170. invalidate();
  171. }
  172. privatevoidconfirmSize(){
  173. intminScreenSize=Math.min(mScreenWidth,mScreenHeight);
  174. intwidthOverSize=mScreenWidth-minScreenSize;
  175. intheightOverSize=mScreenHeight-minScreenSize;
  176. heightPaddingTop=(getPaddingTop()+heightOverSize/2);
  177. heightPaddingBottom=(getPaddingBottom()+heightOverSize/2);
  178. widthPaddingLeft=(getPaddingLeft()+widthOverSize/2);
  179. widthPaddingRight=(getPaddingRight()+widthOverSize/2);
  180. intwidth=getWidth();
  181. intheight=getHeight();
  182. mRect=newRectF(widthPaddingLeft,heightPaddingTop,width
  183. -widthPaddingRight,height*2-heightPaddingBottom);
  184. }
  185. publicvoidstratRipple(){
  186. isStartRipple=true;
  187. handler.sendEmptyMessage(0);
  188. }
  189. }
下图是某个应用的流量显示界面,使用的是上面说的第二种形式。 Android 分享一个流量显示界面_第2张图片 实现上面效果的思路是使用正弦或者余弦曲线,代码如下: [html] view plain copy
  1. /**
  2. *
  3. */
  4. packagecom.kince.waveview;
  5. importandroid.content.Context;
  6. importandroid.graphics.Canvas;
  7. importandroid.graphics.Color;
  8. importandroid.graphics.Paint;
  9. importandroid.graphics.Path;
  10. importandroid.graphics.RectF;
  11. importandroid.os.Handler;
  12. importandroid.os.Parcel;
  13. importandroid.os.Parcelable;
  14. importandroid.util.AttributeSet;
  15. importandroid.view.View;
  16. importandroid.widget.ProgressBar;
  17. /**
  18. *@authorkince
  19. *@categoryView必须是正方形
  20. *
  21. */
  22. publicclassWaterWaveViewextendsView{
  23. privateContextmContext;
  24. privateintmScreenWidth;
  25. privateintmScreenHeight;
  26. privatePaintmRingPaint;
  27. privatePaintmCirclePaint;
  28. privatePaintmWavePaint;
  29. privatePaintlinePaint;
  30. privatePaintflowPaint;
  31. privatePaintleftPaint;
  32. privateintmRingSTROKEWidth=15;
  33. privateintmCircleSTROKEWidth=2;
  34. privateintmLineSTROKEWidth=1;
  35. privateintmCircleColor=Color.WHITE;
  36. privateintmRingColor=Color.WHITE;
  37. privateintmWaveColor=Color.WHITE;
  38. privateHandlermHandler;
  39. privatelongc=0L;
  40. privatebooleanmStarted=false;
  41. privatefinalfloatf=0.033F;
  42. privateintmAlpha=50;//透明度
  43. privatefloatmAmplitude=10.0F;//振幅
  44. privatefloatmWateLevel=0.5F;//水高(0~1)
  45. privatePathmPath;
  46. privateStringflowNum="1024M";
  47. privateStringflowLeft="还剩余";
  48. /**
  49. *@paramcontext
  50. */
  51. publicWaterWaveView(Contextcontext){
  52. super(context);
  53. //TODOAuto-generatedconstructorstub
  54. mContext=context;
  55. init(mContext);
  56. }
  57. /**
  58. *@paramcontext
  59. *@paramattrs
  60. */
  61. publicWaterWaveView(Contextcontext,AttributeSetattrs){
  62. super(context,attrs);
  63. //TODOAuto-generatedconstructorstub
  64. mContext=context;
  65. init(mContext);
  66. }
  67. /**
  68. *@paramcontext
  69. *@paramattrs
  70. *@paramdefStyleAttr
  71. */
  72. publicWaterWaveView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
  73. super(context,attrs,defStyleAttr);
  74. //TODOAuto-generatedconstructorstub
  75. mContext=context;
  76. init(mContext);
  77. }
  78. privatevoidinit(Contextcontext){
  79. mRingPaint=newPaint();
  80. mRingPaint.setColor(mRingColor);
  81. mRingPaint.setAlpha(50);
  82. mRingPaint.setStyle(Paint.Style.STROKE);
  83. mRingPaint.setAntiAlias(true);
  84. mRingPaint.setStrokeWidth(mRingSTROKEWidth);
  85. mCirclePaint=newPaint();
  86. mCirclePaint.setColor(mCircleColor);
  87. mCirclePaint.setStyle(Paint.Style.STROKE);
  88. mCirclePaint.setAntiAlias(true);
  89. mCirclePaint.setStrokeWidth(mCircleSTROKEWidth);
  90. linePaint=newPaint();
  91. linePaint.setColor(mCircleColor);
  92. linePaint.setStyle(Paint.Style.STROKE);
  93. linePaint.setAntiAlias(true);
  94. linePaint.setStrokeWidth(mLineSTROKEWidth);
  95. flowPaint=newPaint();
  96. flowPaint.setColor(mCircleColor);
  97. flowPaint.setStyle(Paint.Style.FILL);
  98. flowPaint.setAntiAlias(true);
  99. flowPaint.setTextSize(36);
  100. leftPaint=newPaint();
  101. leftPaint.setColor(mCircleColor);
  102. leftPaint.setStyle(Paint.Style.FILL);
  103. leftPaint.setAntiAlias(true);
  104. leftPaint.setTextSize(18);
  105. mWavePaint=newPaint();
  106. mWavePaint.setStrokeWidth(1.0F);
  107. mWavePaint.setColor(mWaveColor);
  108. mWavePaint.setAlpha(mAlpha);
  109. mPath=newPath();
  110. mHandler=newHandler(){
  111. @Override
  112. publicvoidhandleMessage(android.os.Messagemsg){
  113. if(msg.what==0){
  114. invalidate();
  115. if(mStarted){
  116. //不断发消息给自己,使自己不断被重绘
  117. mHandler.sendEmptyMessageDelayed(0,60L);
  118. }
  119. }
  120. }
  121. };
  122. }
  123. @Override
  124. protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
  125. intwidth=measure(widthMeasureSpec,true);
  126. intheight=measure(heightMeasureSpec,false);
  127. if(width<height){
  128. setMeasuredDimension(width,width);
  129. }else{
  130. setMeasuredDimension(height,height);
  131. }
  132. }
  133. /**
  134. *@category测量
  135. *@parammeasureSpec
  136. *@paramisWidth
  137. *@return
  138. */
  139. privateintmeasure(intmeasureSpec,booleanisWidth){
  140. intresult;
  141. intmode=MeasureSpec.getMode(measureSpec);
  142. intsize=MeasureSpec.getSize(measureSpec);
  143. intpadding=isWidth?getPaddingLeft()+getPaddingRight()
  144. :getPaddingTop()+getPaddingBottom();
  145. if(mode==MeasureSpec.EXACTLY){
  146. result=size;
  147. }else{
  148. result=isWidth?getSuggestedMinimumWidth()
  149. :getSuggestedMinimumHeight();
  150. result+=padding;
  151. if(mode==MeasureSpec.AT_MOST){
  152. if(isWidth){
  153. result=Math.max(result,size);
  154. }else{
  155. result=Math.min(result,size);
  156. }
  157. }
  158. }
  159. returnresult;
  160. }
  161. @Override
  162. protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
  163. //TODOAuto-generatedmethodstub
  164. super.onSizeChanged(w,h,oldw,oldh);
  165. mScreenWidth=w;
  166. mScreenHeight=h;
  167. }
  168. @Override
  169. protectedvoidonDraw(Canvascanvas){
  170. //TODOAuto-generatedmethodstub
  171. super.onDraw(canvas);
  172. //得到控件的宽高
  173. intwidth=getWidth();
  174. intheight=getHeight();
  175. setBackgroundColor(mContext.getResources().getColor(
  176. R.color.holo_purple2));
  177. canvas.drawCircle(mScreenWidth/2,mScreenHeight/2,
  178. mScreenWidth/4,mRingPaint);
  179. canvas.drawCircle(mScreenWidth/2,mScreenHeight/2,mScreenWidth/4
  180. -mRingSTROKEWidth/2,mCirclePaint);
  181. canvas.drawLine(mScreenWidth*3/8,mScreenHeight*5/8,
  182. mScreenWidth*5/8,mScreenHeight*5/8,linePaint);
  183. floatnum=flowPaint.measureText(flowNum);
  184. canvas.drawText(flowNum,mScreenWidth*4/8-num/2,
  185. mScreenHeight*4/8,flowPaint);
  186. floatleft=leftPaint.measureText(flowLeft);
  187. canvas.drawText(flowLeft,mScreenWidth*4/8-left/2,
  188. mScreenHeight*3/8,leftPaint);
  189. //如果未开始(未调用startWave方法),绘制一个扇形
  190. if((!mStarted)||(mScreenWidth==0)||(mScreenHeight==0)){
  191. RectFoval=newRectF(mScreenWidth/4+mRingSTROKEWidth/2,
  192. mScreenHeight/4+mRingSTROKEWidth/2,mScreenWidth*3
  193. /4-mRingSTROKEWidth/2,mScreenHeight*3/4
  194. -mRingSTROKEWidth/2);//设置个新的长方形,扫描测量
  195. canvas.drawArc(oval,0,180,true,mWavePaint);
  196. return;
  197. }
  198. //绘制,即水面静止时的高度
  199. RectFoval=newRectF(mScreenWidth/4+mRingSTROKEWidth/2,
  200. mScreenHeight/4+mRingSTROKEWidth/2+mAmplitude*2,
  201. mScreenWidth*3/4-mRingSTROKEWidth/2,mScreenHeight*3
  202. /4-mRingSTROKEWidth/2);//设置个新的长方形,扫描测量
  203. canvas.drawArc(oval,0,180,true,mWavePaint);
  204. if(this.c>=8388607L){
  205. this.c=0L;
  206. }
  207. //每次onDraw时c都会自增
  208. c=(1L+c);
  209. floatf1=mScreenHeight*(1.0F-mWateLevel);
  210. inttop=(int)(f1+mAmplitude);
  211. mPath.reset();
  212. intstartX=mScreenWidth/2-mScreenWidth/4+mRingSTROKEWidth/2;
  213. //波浪效果
  214. while(startX<mScreenWidth/2+mScreenWidth/4-mRingSTROKEWidth
  215. /2){
  216. intstartY=(int)(f1-mAmplitude
  217. *Math.sin(Math.PI
  218. *(2.0F*(startX+this.c*width*this.f))
  219. /width));
  220. canvas.drawLine(startX,startY,startX,top,mWavePaint);
  221. startX++;
  222. }
  223. canvas.restore();
  224. }
  225. @Override
  226. publicParcelableonSaveInstanceState(){
  227. //Forceourancestorclasstosaveitsstate
  228. ParcelablesuperState=super.onSaveInstanceState();
  229. SavedStatess=newSavedState(superState);
  230. ss.progress=(int)c;
  231. returnss;
  232. }
  233. @Override
  234. publicvoidonRestoreInstanceState(Parcelablestate){
  235. SavedStatess=(SavedState)state;
  236. super.onRestoreInstanceState(ss.getSuperState());
  237. c=ss.progress;
  238. }
  239. @Override
  240. protectedvoidonAttachedToWindow(){
  241. super.onAttachedToWindow();
  242. //关闭硬件加速,防止异常unsupportedoperationexception
  243. this.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
  244. }
  245. @Override
  246. protectedvoidonDetachedFromWindow(){
  247. super.onDetachedFromWindow();
  248. }
  249. /**
  250. *@category开始波动
  251. */
  252. publicvoidstartWave(){
  253. if(!mStarted){
  254. this.c=0L;
  255. mStarted=true;
  256. this.mHandler.sendEmptyMessage(0);
  257. }
  258. }
  259. /**
  260. *@category停止波动
  261. */
  262. publicvoidstopWave(){
  263. if(mStarted){
  264. this.c=0L;
  265. mStarted=false;
  266. this.mHandler.removeMessages(0);
  267. }
  268. }
  269. /**
  270. *@category保存状态
  271. */
  272. staticclassSavedStateextendsBaseSavedState{
  273. intprogress;
  274. /**
  275. *Constructorcalledfrom{@linkProgressBar#onSaveInstanceState()}
  276. */
  277. SavedState(ParcelablesuperState){
  278. super(superState);
  279. }
  280. /**
  281. *Constructorcalledfrom{@link#CREATOR}
  282. */
  283. privateSavedState(Parcelin){
  284. super(in);
  285. progress=in.readInt();
  286. }
  287. @Override
  288. publicvoidwriteToParcel(Parcelout,intflags){
  289. super.writeToParcel(out,flags);
  290. out.writeInt(progress);
  291. }
  292. publicstaticfinalParcelable.Creator<SavedState>CREATOR=newParcelable.Creator<SavedState>(){
  293. publicSavedStatecreateFromParcel(Parcelin){
  294. returnnewSavedState(in);
  295. }
  296. publicSavedState[]newArray(intsize){
  297. returnnewSavedState[size];
  298. }
  299. };
  300. }
  301. }

github下载地址: https://github.com/wangjinyu501/RippleView https://github.com/wangjinyu501/WaterWaveView/




更多相关文章

  1. Android 实现图片闪烁效果
  2. Android 震动示例--心跳效果
  3. Android动画效果学习
  4. JavaGG android实现uc 和墨迹天气那样的左右拖动效果
  5. Android切换Activity的动画效果
  6. android 控件 3d 旋转效果
  7. Android中开关按钮IOS效果的实现
  8. android ListView滑动到顶部带弹性效果

随机推荐

  1. 详解Android主流框架不可或缺的基石
  2. android sqlite 数据类型
  3. Android(安卓)adb的使用略解
  4. 在android中创建圆角的文本框的实现
  5. [置顶] 一步一步学android OpenGL ES2.0
  6. android JNI 学习笔记
  7. 1.Android新版开发教程&笔记—Android(安
  8. AVD(android virtual device )路径设置
  9. android bug 问题定位(log+traces)
  10. Android(安卓)App开发总结