最近做一个效果:在手机设置里面“关于手机”里面添加一项来显示当前手机cpu使用率的曲线!其实现效果如下图所示:
上图关于手机的第一项就是我要实现的效果!今天来讲讲这个曲线的view(cpu_speedcurve_view)是如何实现的!
首先要注意以下几点:
(1)由于我设计的cpu_speedcurve_view不仅仅显示动态的曲线,还需要用textview显示一些cpu相关信息!所以,我选择cpu_speedcurve_view继承一个viewgroup,这里我选择的是FrameLayout
(3)曲线的怎么绘制?
这里我是在cpu_speedcurve_view的public void draw(Canvas canvas)里面用Canvas的drawPath来绘制的。具体代码如下:
public void draw(Canvas canvas) { super.draw(canvas); //mPaint.setColor(coordinateColor); //mPaint.setStrokeWidth(mStrokeSize*2); //canvas.drawPath(m_path_coordinate, mPaint); //canvas.clipRect(10, 10, 5, 5); if(flag_start){ if(m_path_0 == null && m_path_1 == null){ //Start_run_CpuTracker_to_show_curve(); }else{ mPaint.setColor(curveColor); mPaint.setStrokeWidth(mStrokeSize); if(m_path_0 != null){ // Log.d("speedcurve", "cpu_speedcurve_view draw (m_path != null) "); if(!m_path_0.isEmpty()){ canvas.drawPath(m_path_0, mPaint); } } if(m_path_1 != null){ // Log.d("speedcurve", "cpu_speedcurve_view draw (m_path != null) "); if(!m_path_1.isEmpty()){ canvas.drawPath(m_path_1, mPaint); } } } } }从上面代码可以看到,这里居然有两个Path,从上面的效果图可以看出只是一条曲线呀!为什么这里有两个Path呢?
private Path m_path_0; private Path m_path_1;
的确我定义了两个Path,那是因为一个Path的曲线长度不是无线的,总是会溢出的!所以我就设计了两个曲线(Path),当m_path_0使用一段时间后,就启动另一个曲线m_path_1,使其重叠显示,直到m_path_1长度超过这个view显示的宽度时候,把m_path_0给清除掉。整个运行的机制就是这样反复。
(2)对于曲线的动态显示,我的办法是定义一个Handler定时的自动发送信息来更新cpu运行的数据,最后用invalidate();来刷新曲线:
private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 000: m_CpuTracker.update(); TotalCpuPercent = m_CpuTracker.getTotalCpuPercent(); int h = view_h - 2; //int CpuPercent_po = (int) (h * TotalCpuPercent); if(flag_num < 400){ if(m_path_0 == null){ m_path_0 = new Path(); m_path_0.moveTo(view_w+4, h - TotalCpuPercent); } if(flag_num > 200){ if(m_path_1 == null){ m_path_1 = new Path(); m_path_1.moveTo(view_w+4, h - TotalCpuPercent); } }else{ m_path_1 = null; } }else if(flag_num < 600){ m_path_0 = null; if(m_path_1 == null){ m_path_1 = new Path(); m_path_1.moveTo(view_w+4, h - TotalCpuPercent); } }else if(flag_num < 800){ if(m_path_0 == null){ m_path_0 = new Path(); m_path_0.moveTo(view_w+4, h - TotalCpuPercent); } }else{ flag_num = 0; } if(m_path_0 != null){ m_path_0.lineTo(view_w+4, h - TotalCpuPercent); matrix.setTranslate(-4,0); m_path_0.transform(matrix); } if(m_path_1 != null){ m_path_1.lineTo(view_w+4, h - TotalCpuPercent); matrix.setTranslate(-4,0); m_path_1.transform(matrix); } // Log.d("speedcurve", "cpu_speedcurve_view handleMessage msg.what=000 flag_num="+flag_num); // Log.d("speedcurve", "cpu_speedcurve_view handleMessage TotalCpuPercent="+TotalCpuPercent+"view_h="+view_h+"getCurCpuFreq()="+Cpu_info_manager.getCurCpuFreq()); if(flag_start){ mHandler.sendEmptyMessageDelayed(000,300); invalidate(); flag_num++; }else{ Stop_run_CpuTracker_to_show_curve(); } break; case 111: break; } } };从上面的代码可以知道:首先获取当前cpu使用的百分率,再通过这个百分率来计算出曲线高度!最后通过path的moveTo来完成曲线的绘制保存。
(3)如何获取cpu的使用率呢?
用android提供的ProcessCpuTracker就可以了。
m_CpuTracker = new ProcessCpuTracker(false);实际上在ProcessCpuTracker里面就是在/proc/stat 去读取cpu的信息(user time /nice time/sys time/idle time/iowait time等)来计算出使用率的百分比的!
(4)最后记得 在这个里面 protected void onDetachedFromWindow()停止运行就可以了!
就这样问题就基本解决了!如果要实现如上的效果图的则需要定义一个PreferenceGroup:
PreferenceGroup mCPUStatusPref = (PreferenceGroup) findPreference("cpu_key"); mCPUStatusPref.setLayoutResource(R.layout.cpu_curve_preference);在layout: cpu_curve_preference就可以布局成上面的效果了!
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="85dip" android:gravity="center_vertical" android:paddingStart="@*android:dimen/preference_item_padding_side" android:paddingEnd="?android:attr/scrollbarSize" android:background="?android:attr/selectableItemBackground" android:paddingTop="6dip" android:paddingBottom="6dip"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:paddingTop="6dip" android:paddingBottom="6dip"> <TextView android:id="@+android:id/title" android:text="@string/XunHu_Setting_Cpu_Info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:textAppearance="?android:attr/textAppearanceMedium" android:ellipsize="marquee" android:fadingEdge="horizontal" /> <TextView android:id="@android:id/summary" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/usage_type_cpu_foreground" android:layout_below="@android:id/title" android:layout_alignStart="@android:id/title" android:visibility="gone" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="?android:attr/textColorSecondary" android:maxLines="4" /> </RelativeLayout> <com.android.settings.widget.cpu_speedcurve_view android:layout_width="wrap_content" android:layout_height="match_parent" android:minWidth="180dip" android:background="@drawable/cpu_curve_bg" android:layout_marginBottom="8dip" android:layout_marginTop="8dip" > <TextView android:id="@+android:id/cpu_speedcurve_view_title" android:text="@string/XunHu_Setting_Cpu_Info_util" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="marquee" android:fadingEdge="horizontal" /> </com.android.settings.widget.cpu_speedcurve_view></LinearLayout>