因为项目中有遇到进度的一个需求,目前类似的在实现网络进度加载和流量用量上比较多,所有今天就把代码贴出来,希望有需要的朋友能够有用到。

1.首先是主页面

package com.zhanglu.percentageball;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;/** *  * 项目名称:PercentageBall 类名称:MainActivity 类描述: 主页面 创建人:zhanglu 创建时间:2016-6-1 上午9:04:46 修改人:zhanglu 修改时间:2016-6-1 上午9:04:46 修改备注: *  * @version *  */public class MainActivity extends Activity implements OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button1).setOnClickListener(this);findViewById(R.id.button2).setOnClickListener(this);findViewById(R.id.button3).setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1:startActivity(new Intent(this, PercentageBallActivty.class));break;case R.id.button2:startActivity(new Intent(this, PercentageBallListviewActivty.class));break;case R.id.button3:startActivity(new Intent(this, PercentageBallWaveActivty.class));break;default:break;}}}



2.下面是静止页面的代码

package com.zhanglu.percentageball;import com.zhanglu.percentageball.view.PercentageBallView;import android.app.Activity;import android.os.Bundle;/**     *      * 项目名称:PercentageBall     * 类名称:PercentageBallActivty     * 类描述:    动态波浪球 * 创建人:zhanglu    * 创建时间:2016-6-1 上午9:30:53     * 修改人:zhanglu    * 修改时间:2016-6-1 上午9:30:53     * 修改备注:     * @version      *      */public class PercentageBallActivty extends Activity {private PercentageBallView pv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.percentage_ball_activty);pv = (PercentageBallView) findViewById(R.id.ball);pv.setmWaterLevel(0.5f, "10/5");pv.startWave();// 开始执行}}
 

下面是实现波浪球的效果代码

package com.zhanglu.percentageball.view;import android.annotation.TargetApi;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.RectF;import android.os.Build;import android.os.Handler;import android.os.Parcel;import android.os.Parcelable;import android.util.AttributeSet;import android.view.View;import android.widget.ProgressBar;import com.zhanglu.percentageball.R;/**     *      * 项目名称:PercentageBall     * 类名称:PercentageBallView     * 类描述:    实现效果类 * 创建人:zhanglu    * 创建时间:2016-6-1 上午11:20:17     * 修改人:zhanglu    * 修改时间:2016-6-1 上午11:20:17     * 修改备注:     * @version      *      */@TargetApi(Build.VERSION_CODES.HONEYCOMB)public class PercentageBallView extends View {private Context mContext;private int mScreenWidth;private int mScreenHeight;private Paint mRingPaint;private Paint mCirclePaint;private Paint mWavePaint;private Paint flowPaint;private int mRingSTROKEWidth = 8;private int mCircleSTROKEWidth = 8;private int mLineSTROKEWidth = 1;private Handler mHandler;private long c = 0L;private boolean mStarted = false;private final float f = 0.033F;private int mAlpha = 50;// 透明度private float mAmplitude = 0.0F; // 振幅private float mWaterLevel = 0.0F;// 水高(0~1)private Path mPath;// 绘制文字显示在圆形中间,只是我没有设置,我觉得写在布局上也挺好的private String flowNum = "";// 2/10/** * @param context */public PercentageBallView(Context context) {super(context);// TODO Auto-generated constructor stubmContext = context;init(mContext);}/** * @param context * @param attrs */public PercentageBallView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubmContext = context;init(mContext);}/** * @param context * @param attrs * @param defStyleAttr */public PercentageBallView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;init(mContext);}public void setmWaterLevel(float mWaterLevel, String str) {this.mWaterLevel = mWaterLevel;this.flowNum = str;}public void setmWaterWave(float mWaterLevel, String str, float mWater) {this.mWaterLevel = mWaterLevel;this.flowNum = str;this.mAmplitude = mWater;}private void init(Context context) {// 外圈mRingPaint = new Paint();mRingPaint.setColor(Color.rgb(75, 210, 243));mRingPaint.setStyle(Paint.Style.STROKE);mRingPaint.setAntiAlias(true);mRingPaint.setStrokeWidth(mRingSTROKEWidth);// 内圈mCirclePaint = new Paint();mCirclePaint.setColor(Color.WHITE);mCirclePaint.setStyle(Paint.Style.STROKE);mCirclePaint.setAntiAlias(true);mCirclePaint.setStrokeWidth(mCircleSTROKEWidth);// 文字flowPaint = new Paint();flowPaint.setColor(Color.BLACK);flowPaint.setStyle(Paint.Style.FILL);flowPaint.setAntiAlias(true);flowPaint.setTextSize(24);// 内填充mWavePaint = new Paint();mWavePaint.setStrokeWidth(1.0F);mWavePaint.setColor(Color.rgb(75, 210, 243));// mWavePaint.setAlpha(mAlpha);mPath = new Path();mHandler = new Handler() {@Overridepublic void handleMessage(android.os.Message msg) {if (msg.what == 0) {invalidate();if (mStarted) {// 不断发消息给自己,使自己不断被重绘mHandler.sendEmptyMessageDelayed(0, 60L);}}}};}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = measure(widthMeasureSpec, true);int height = measure(heightMeasureSpec, false);if (width < height) {setMeasuredDimension(width, width);} else {setMeasuredDimension(height, height);}}/** * @category 测量 * @param measureSpec * @param isWidth * @return */private int measure(int measureSpec, boolean isWidth) {int result;int mode = MeasureSpec.getMode(measureSpec);int size = MeasureSpec.getSize(measureSpec);int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();if (mode == MeasureSpec.EXACTLY) {result = size;} else {result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight();result += padding;if (mode == MeasureSpec.AT_MOST) {if (isWidth) {result = Math.max(result, size);} else {result = Math.min(result, size);}}}return result;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {// TODO Auto-generated method stubsuper.onSizeChanged(w, h, oldw, oldh);mScreenWidth = w;mScreenHeight = h;}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);// 得到控件的宽高int width = getWidth();int height = getHeight();setBackgroundColor(Color.WHITE);// 可以自定义色值// 计算当前油量线和水平中线的距离float centerOffset = Math.abs(mScreenWidth / 2 * mWaterLevel - mScreenWidth / 4);// 计算油量线和与水平中线的角度float horiAngle = (float) (Math.asin(centerOffset / (mScreenWidth / 4)) * 180 / Math.PI);// 扇形的起始角度和扫过角度float startAngle, sweepAngle;if (mWaterLevel > 0.5F) {startAngle = 360F - horiAngle;sweepAngle = 180F + 2 * horiAngle;} else {startAngle = horiAngle;sweepAngle = 180F - 2 * horiAngle;}float num = flowPaint.measureText(flowNum);// 如果未开始(未调用startWave方法),绘制一个扇形if ((!mStarted) || (mScreenWidth == 0) || (mScreenHeight == 0)) {// 绘制,即水面静止时的高度RectF oval = new RectF(mScreenWidth / 4, mScreenHeight / 4, mScreenWidth * 3 / 4, mScreenHeight * 3 / 4);canvas.drawArc(oval, startAngle, sweepAngle, false, mWavePaint);return;}// 绘制,即水面静止时的高度// 绘制,即水面静止时的高度RectF oval = new RectF(mScreenWidth / 4, mScreenHeight / 4, mScreenWidth * 3 / 4, mScreenHeight * 3 / 4);canvas.drawArc(oval, startAngle, sweepAngle, false, mWavePaint);if (this.c >= 8388607L) {this.c = 0L;}// 每次onDraw时c都会自增c = (1L + c);float f1 = mScreenHeight * (1.0F - (0.25F + mWaterLevel / 2)) - mAmplitude;// 当前油量线的长度float waveWidth = (float) Math.sqrt(mScreenWidth * mScreenWidth / 16 - centerOffset * centerOffset);// 与圆半径的偏移量float offsetWidth = mScreenWidth / 4 - waveWidth;int top = (int) (f1 + mAmplitude);mPath.reset();// 起始振动X坐标,结束振动X坐标int startX, endX;if (mWaterLevel > 0.50F) {startX = (int) (mScreenWidth / 4 + offsetWidth);endX = (int) (mScreenWidth / 2 + mScreenWidth / 4 - offsetWidth);} else {startX = (int) (mScreenWidth / 4 + offsetWidth - mAmplitude);endX = (int) (mScreenWidth / 2 + mScreenWidth / 4 - offsetWidth + mAmplitude);}// 波浪效果while (startX < endX) {int startY = (int) (f1 - mAmplitude * Math.sin(Math.PI * (2.0F * (startX + this.c * width * this.f)) / width));canvas.drawLine(startX, startY, startX, top, mWavePaint);startX++;}canvas.drawCircle(mScreenWidth / 2, mScreenHeight / 2, mScreenWidth / 4 + mRingSTROKEWidth / 2, mRingPaint);canvas.drawCircle(mScreenWidth / 2, mScreenHeight / 2, mScreenWidth / 4, mCirclePaint);// 放到这里绘制文字,不然会因为前面的绘图遮挡住文字canvas.drawText(flowNum, mScreenWidth * 4 / 8 - num / 2, mScreenHeight * 4 / 8, flowPaint);canvas.restore();}@Overridepublic Parcelable onSaveInstanceState() {Parcelable superState = super.onSaveInstanceState();SavedState ss = new SavedState(superState);ss.progress = (int) c;return ss;}@Overridepublic void onRestoreInstanceState(Parcelable state) {SavedState ss = (SavedState) state;super.onRestoreInstanceState(ss.getSuperState());c = ss.progress;}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();// 关闭硬件加速,防止异常unsupported operation exceptionthis.setLayerType(View.LAYER_TYPE_SOFTWARE, null);}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();}/** * 开始波动 */public void startWave() {if (!mStarted) {this.c = 0L;mStarted = true;this.mHandler.sendEmptyMessage(0);}}/** * @category 停止波动 */public void stopWave() {if (mStarted) {this.c = 0L;mStarted = false;this.mHandler.removeMessages(0);}}/** * @category 保存状态 */static class SavedState extends BaseSavedState {int progress;/** * Constructor called from {@link ProgressBar#onSaveInstanceState()} */SavedState(Parcelable superState) {super(superState);}/** * Constructor called from {@link #CREATOR} */private SavedState(Parcel in) {super(in);progress = in.readInt();}@Overridepublic void writeToParcel(Parcel out, int flags) {super.writeToParcel(out, flags);out.writeInt(progress);}public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {public SavedState createFromParcel(Parcel in) {return new SavedState(in);}public SavedState[] newArray(int size) {return new SavedState[size];}};}}


运行后效果如下:



好,我们实现了静态的图后,再来实现动态波动的


因为项目需要,是要在listview中实现,所有现在把效果加到listview中,下面是实现代码:

package com.zhanglu.percentageball;import java.util.ArrayList;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import com.zhanglu.percentageball.view.PercentageBallView;/**     *      * 项目名称:PercentageBall     * 类名称:PercentageBallListviewActivty     * 类描述:    实现在listview中波动效果 * 创建人:zhanglu    * 创建时间:2016-6-1 上午11:25:15     * 修改人:zhanglu    * 修改时间:2016-6-1 上午11:25:15     * 修改备注:     * @version      *      */public class PercentageBallListviewActivty extends Activity {private Context mContext;private ListView listview;private ArrayList mlist = new ArrayList();private MyAdapter mMyAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.percentage_ball__listview_activty);mContext = getApplicationContext();listview = (ListView) findViewById(R.id.listView1);mMyAdapter = new MyAdapter(mlist);listview.setAdapter(mMyAdapter);}@Overrideprotected void onResume() {super.onResume();for (int i = 0; i < 30; i++) {pvinfo pv = new pvinfo();pv.setStr((i + 1) + "/" + 30);mlist.add(pv);}mMyAdapter.notifyDataSetChanged();}public class MyAdapter extends BaseAdapter {private ArrayList mlist = null;public MyAdapter(ArrayList mlist2) {this.mlist = mlist2;}public int getCount() {return mlist.size();}public Object getItem(int pos) {return mlist.get(pos);}public long getItemId(int pos) {return pos;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {final ViewHolder viewHolder;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.percentage_ball__listview_item, null);viewHolder = new ViewHolder();viewHolder.pv = (PercentageBallView) convertView.findViewById(R.id.ball);viewHolder.textView1 = (TextView) convertView.findViewById(R.id.textView1);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.textView1.setText("这是第" + (position+1) + " item ");float n = (float) position / 30;viewHolder.pv.setmWaterWave(n, mlist.get(position).getStr(),8f);viewHolder.pv.startWave();return convertView;}public class ViewHolder {public PercentageBallView pv;public TextView textView1;}}public class pvinfo {private float valve;private String str;public float getValve() {return valve;}public void setValve(float valve) {this.valve = valve;}public String getStr() {return str;}public void setStr(String str) {this.str = str;}public pvinfo(float valve, String str) {super();this.valve = valve;this.str = str;}public pvinfo() {super();}}}

来张效果图:


代码下载地址:http://download.csdn.net/detail/meburningg/9537522

更多相关文章

  1. 让Android设备永不休眠
  2. Android(安卓)如何关闭Navigation Bar M
  3. android 启动自动调用自己创建的脚本(应用程序)
  4. Android(安卓)游戏开发必备的基础知识
  5. Android(安卓)新建一个lunch项(全志方案)
  6. Android(安卓)使用RecycleView实现吸附小标题的Demo(附源码)
  7. android 绘制图片的一部分
  8. Android(安卓)4.2 设置手机的 Airplane mode
  9. Android(安卓)Studio 串口jni开发

随机推荐

  1. Android官方架构组件介绍之LifeCycle
  2. Android串口(SerialPort)开发常遇神坑
  3. android TextView属性的详细介绍 分享
  4. Android(安卓)推送通知指南
  5. Android(安卓)OTA 升级之三:生成recovery.
  6. Android(安卓)总结:进阶之路(资源与方法)
  7. Android简明开发教程九:创建应用程序框架
  8. Android面试复习(Android篇一)
  9. 修改 Android(安卓)系统默认语言版本
  10. 使用shape来定义控件的一些显示属性