您的位置:首页 > 移动开发 > Android开发

android 画笔和画布的使用,实现类似360清除内存的画面

2016-07-11 11:23 525 查看
代码上已经写好了注释, 因时间关系只写了关键部分的注释,如有不理解的可以给我留言, 我会帮你解读的。

//UI类

package com.example.atest_rectui.widget;

import java.util.List;

import com.example.atest_rectui.R;

import com.example.atest_rectui.util.Utils;

import android.app.ActivityManager;

import android.app.ActivityManager.RunningAppProcessInfo;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RectF;

import android.graphics.Typeface;

import android.os.Handler.Callback;

import android.os.Handler;

import android.os.Message;

import android.util.AttributeSet;

import android.util.Log;

import android.widget.TextView;

import android.widget.Toast;

/**

 * @author snake

 * UI类, 直接在xml文件配置 即可使用

 *

 */

public class ClearMemoryView extends TextView implements Callback {

 private static final String TAG = ClearMemoryView.class.getSimpleName();

 

 private static final int REFRESHING  = 0x01;

 private static final int REFRESH_UI = 0x02;

 private static final int REFRESH_END = 0x03;

 private Context mContext = null;

 private Handler mHandler = null;

 /** 画圆的画笔 */

 private Paint mCircularPaint;

 /** 写字体的画笔 */

 private Paint mTxtPaint;

 private RectF mRectF;

 private RectF mRectFrame;

 /** View的宽度 */

 private int mViewWidth = 0;

 /** View的高度 */

 private int mViewHeight = 0;

 /** 圆的宽度 */

 private int mCircularWidth = 0;

 /** 当前的进度 */

 private int mCurrentProgress = 100;

 private int mMax = 100;

 private long mMaxValue = 0;

 private float mSweepAngle;

 private float mTxtSize = 0.0f;

 /** ClearAppsIcon的进度 */

 private int mProgress = 0;

 /** 允许清除apps的标志 */

 private boolean mAllowClear = true;

 /** 之前的内存 */

 private long mBeforeMem = 0l;

 private float mIconPadding = 20;

 

 

 private float paintwidth = 12;

 private Paint mCenterPaint;

 private Paint mPerentPaint;

 

 public ClearMemoryView(Context context) {

  this(context, null);

 }

 public ClearMemoryView(Context context, AttributeSet attrs) {

  this(context, attrs, 0);

 }

 public ClearMemoryView(Context context, AttributeSet attrs, int defStyle) {

  super(context, attrs, defStyle);

  mContext = context;

  mHandler = new Handler(this);

  mViewWidth = (int)mContext.getResources().getDimension(R.dimen.dimen_bottom_item_layout);

  mViewHeight = (int)mContext.getResources().getDimension(R.dimen.dimen_bottom_item_layout);

  initData();

  

 }

 private void initData() {

  

  mCircularWidth = (int)(mViewWidth * 0.78f);

  Log.d(TAG, "Clear View Circular==" + mCircularWidth + "::CellWidth==" + mViewWi
f46b
dth + ":::getScrollX() = " + getScrollX());

  mRectF = new RectF();

  mRectFrame = new RectF();

  // 初始化画圆形的画笔

  mCircularPaint = new Paint();

  

  //设置画布填充模式 , Paint.Style.STROKE表示中间区域是 镂空的

  mCircularPaint.setStyle(Paint.Style.STROKE);

  

  //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式   Cap.ROUND,或方形样式Cap.SQUARE  

  mCircularPaint.setStrokeCap(Paint.Cap.ROUND);

  

  //设置绘制时各图形的结合方式,如平滑效果等

  mCircularPaint.setStrokeJoin(Paint.Join.ROUND);

  

  //设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰 

  mCircularPaint.setDither(true);

  

  //设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。  

  mCircularPaint.setAntiAlias(true);

  

  //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度 

  mCircularPaint.setStrokeWidth(paintwidth);

  

  mCenterPaint = new Paint();

  mCenterPaint.setStyle(Paint.Style.FILL);

  mCenterPaint.setDither(true);

  mCenterPaint.setAntiAlias(true);

  mCenterPaint.setColor(Color.parseColor("#eeeeee"));

  // 设置渐变的颜色组,也就是按红、绿、蓝的方式渐变

//  int[] colors = new int[]{Color.parseColor("#00EC00"), Color.parseColor("#00BB00"), Color.parseColor("#009100")};

//  Shader shader = new SweepGradient(getWidth() / 2, 0, colors, null);

//  mCircularPaint.setShader(shader);

  // 初始化写文字的画笔

  mTxtPaint = new Paint();

  mTxtSize = 33;

  

  mTxtPaint.setTextSize(mTxtSize);

  mTxtPaint.setAntiAlias(true);

//  Typeface typeface = Typeface.createFromAsset(mContext.getAssets(), "fonts/segoemcl.ttf");

//  mTxtPaint.setTypeface(typeface);

  mTxtPaint.setColor(Color.BLACK);

  

  mPerentPaint = new Paint();

  mPerentPaint.setTextSize(22);

  mPerentPaint.setAntiAlias(true);

//  mPerentPaint.setTypeface(typeface);

  mPerentPaint.setColor(Color.BLACK);

  // 初始化值

  setMaxValue(Utils.getTotalMemory(mContext));

  setProgressValue(Utils.getUsedMemory(mContext));

 }

 

 @Override

 protected void onDraw(Canvas canvas) {

  // TODO Auto-generated method stub

  super.onDraw(canvas);

  // 圆环

  float fLeft = mViewWidth - mCircularWidth;

//  float fTop = (mViewHeight - mCircularWidth) / 2 + mIconPadding;

  float fTop = (mViewHeight - mCircularWidth);

  mRectFrame.set(getScrollX() + fLeft-8, fTop-8, getScrollX() + mCircularWidth+8 , mCircularWidth+8);

  mCircularPaint.setStrokeWidth(8);

  mCircularPaint.setColor(Color.parseColor("#32f9f9f9"));

//  mCircularPaint.setColor(Color.parseColor("#00ff00"));

  canvas.drawArc(mRectFrame, 275, 360, false, mCircularPaint);

  

  

  mRectF.set(getScrollX() + fLeft, fTop, getScrollX() + mCircularWidth, mCircularWidth);

  

  

  mCircularPaint.setStrokeWidth(paintwidth);

  mCircularPaint.setColor(Color.parseColor("#757575"));

  canvas.drawArc(mRectF, 275, 360, false, mCircularPaint);

  mSweepAngle = ((float)mCurrentProgress / mMax )*360;

  if(mSweepAngle >= 324) {

   // 90% 324

//   mCircularPaint.setColor(Color.RED);

   mCircularPaint.setColor(Color.parseColor("#91c7c1"));

   

  } else if(mSweepAngle >= 216) {

   // 60% 216

//   mCircularPaint.setColor(Color.parseColor("#ed610a"));

   mCircularPaint.setColor(Color.parseColor("#91c7c1"));

   

  } else {

//   mCircularPaint.setColor(Color.GREEN);

   mCircularPaint.setColor(Color.parseColor("#91c7c1"));

  }

  canvas.drawArc(mRectF, 275, mSweepAngle, false, mCircularPaint);

  

  

  mRectF.set(getScrollX() + fLeft+6, fTop+5, getScrollX() + mCircularWidth -5, mCircularWidth-5);

  canvas.drawArc(mRectF, 275, 360, false, mCenterPaint);

  

  

  // 文字内容

  long nPercentage = mCurrentProgress * 100 / mMax;

//  String strPercentage = String.format("%d%%", nPercentage);

  String strPercentage = String.valueOf(nPercentage);

  String percentage = "%";

  // 文字的长度

  float fTxtLeght = mTxtPaint.measureText(strPercentage);

  float fPercentLenght = mPerentPaint.measureText("%");

  float fTxtHeight = mTxtPaint.measureText("+");

  float nLeft = (mViewWidth - fTxtLeght) / 2;

  

  float nTop = (mCircularWidth + fTxtHeight) / 2 + mIconPadding;

//  float nTop = (mViewWidth - fTxtHeight) / 2;

  

  mTxtPaint.setTextSize(33);

  canvas.drawText(strPercentage, getScrollX() + nLeft - fPercentLenght/2, nTop, mTxtPaint);

  canvas.drawText(percentage, getScrollX() + nLeft + fTxtLeght*3/4 , nTop, mPerentPaint);

 }

 

 @Override

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  // TODO Auto-generated method stub

  super.onMeasure(widthMeasureSpec, heightMeasureSpec);

  setMeasuredDimension(mViewWidth, mViewHeight);

 }

 

 /**

  * 获取比例值

  * @return

  */

 public int getProgress() {

  return mCurrentProgress;

 }

 

 /**

  * 当前的比例

  * @param progress

  */

 public void setProgressValue(long progress) {

  if(progress < 0) {

   progress = 0;

  }

  if(progress > mMaxValue) {

   progress = mMaxValue;

  }

  mCurrentProgress = (int)(progress * 100 / mMaxValue);

  invalidate();

 }

 

 public void setProgress(int progress) {

  if(progress < 0) {

   progress = 0;

  }

  if(progress > mMax) {

   progress = mMax;

  }

  mCurrentProgress = progress;

  invalidate();

 }

 /**

  * 定义的最大值

  * @param max

  */

 public void setMax(int max) {

  mMax = max;

 }

 

 public int getMax() {

  return mMax;

 }

 

 /**

  *

  */

 public void setMaxValue(long maxValue) {

  mMaxValue = maxValue;

 }

 

 /**

  * 清除Apps,释放内存

  */

 private void clearApps() {

  

  ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);

        List<RunningAppProcessInfo> infoList = am.getRunningAppProcesses();

//        List<ActivityManager.RunningServiceInfo> serviceInfos = am.getRunningServices(100);

        mBeforeMem = Utils.getAvailMemory(mContext);

        if (infoList != null) {

            for (int i = 0; i < infoList.size(); ++i) {

                RunningAppProcessInfo appProcessInfo = infoList.get(i);

//                Log.d(TAG, "process name : " + appProcessInfo.processName);

                //importance 该进程的重要程度  分为几个级别,数值越低就越重要。

                Log.d(TAG, "importance : " + appProcessInfo.importance);

                // 一般数值大于RunningAppProcessInfo.IMPORTANCE_SERVICE的进程都长时间没用或者空进程了

                // 一般数值大于RunningAppProcessInfo.IMPORTANCE_VISIBLE的进程都是非可见进程,也就是在后台运行着

                if (appProcessInfo.importance > RunningAppProcessInfo.IMPORTANCE_VISIBLE) {

                    String[] pkgList = appProcessInfo.pkgList;

                    for (int j = 0; j < pkgList.length; ++j) {//pkgList 得到该进程下运行的包名

                        if("com.sen5.launcher".equals(pkgList[j]) || "com.amlogic.DVBPlayer".equals(pkgList[j])) {

                         continue;

                        }

                        try {

                         am.killBackgroundProcesses(pkgList[j]);

                        } catch(SecurityException e) {

                         Log.e(TAG, "killBackgroundProcesses error==" + e.toString());

                        }

                    }

                }

            }

        }

 }

 

 /**

  * 更新界面的动画

  */

 private void refeshUI() {

  

  new Thread(new Runnable() {

   

   @Override

   public void run() {

    

    for(; mProgress > -1; mProgress--) {

     

     mHandler.sendEmptyMessage(REFRESH_UI);

     try {

      Thread.sleep(20);

     } catch (InterruptedException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

     }

    }

    int nUsedMemory = (int)(Utils.getUsedMemory(mContext) * getMax()

      / Utils.getTotalMemory(mContext));

    for(; mProgress <= nUsedMemory; mProgress++) {

     

     mHandler.sendEmptyMessage(REFRESH_UI);

     try {

      Thread.sleep(20);

     } catch (InterruptedException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

     }

     nUsedMemory = (int)(Utils.getUsedMemory(mContext) * getMax()

       / Utils.getTotalMemory(mContext));

    }

    mHandler.sendEmptyMessage(REFRESH_END);

   }

  }).start();

  

 }

 

 /**

  * 开始清除内存

  */

 public void startClearApps() {

  

  if(!mAllowClear) {

   return;

  }

  mProgress = getProgress();

  new Thread(new Runnable() {

   

   @Override

   public void run() {

    // TODO Auto-generated method stub

    mAllowClear = false;

    mHandler.sendEmptyMessage(REFRESHING);

    clearApps();

   }

  }).start();

  

 }

 

 /**

  * 刷新内存的现实,一般在应用打开时就得调用

  */

 public void refreshIconValue() {

  

  setProgressValue(Utils.getUsedMemory(mContext));

 }

 

 @Override

 public boolean handleMessage(Message msg) {

  // TODO Auto-generated method stub

  switch(msg.what) {

  case REFRESHING:

   refeshUI();

   break;

   

  case REFRESH_UI:

   setProgress(mProgress);

   break;

   

  case REFRESH_END:

   mAllowClear = true;

   // 清除内存的结果显示

   long currentMem = Utils.getAvailMemory(mContext);

   Log.d(TAG, "AvailMem===" + currentMem + ":::BeforeMem===" + mBeforeMem);

   String strHint = "";

   if(currentMem > mBeforeMem) {

    String strReleaseMem = mContext.getString(R.string.release_memory);

    String strCurrentMem = mContext.getString(R.string.currunt_memory);

    strHint = String.format("%s %dM,\n%s %dM", strReleaseMem, (currentMem - mBeforeMem)

      , strCurrentMem, currentMem);

   } else {

    strHint = mContext.getString(R.string.best_memory_status);

   }

   

   Toast.makeText(mContext, strHint, Toast.LENGTH_SHORT).show();

   

   break;

   

  default:

   break;

  }

  

  return false;

 }

}

//以下是Main调用类

package com.example.atest_rectui;

import com.example.atest_rectui.widget.ClearMemoryView;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

/**

 * @author snake

 * 调用类

 */

public class MainActivity extends Activity implements OnClickListener{

 private ClearMemoryView mClearMemoryView;

 @Override

 protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_main);

  initView();

 }

 private void initView() {

  mClearMemoryView = (ClearMemoryView)findViewById(R.id.tv_myclearmemory);

  mClearMemoryView.setOnClickListener(this);

  mClearMemoryView.refreshIconValue();

 }

 @Override

 public void onClick(View v) {

  // TODO Auto-generated method stub

  switch (v.getId()) {

  case R.id.tv_myclearmemory:

   mClearMemoryView.startClearApps();

   break;

  default:

   break;

  }

 }

}

//以下是工具类

package com.example.atest_rectui.util;

import android.app.ActivityManager;

import android.app.ActivityManager.MemoryInfo;

import android.content.Context;

/**

 * @author snake

 * 工具类

 */

public class Utils {

 

 /**

  * 获取可用内存大小

  * @param context

  * @return

  */

    public static long getAvailMemory(Context context) {

       

        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        MemoryInfo mi = new MemoryInfo();

        am.getMemoryInfo(mi);

        //return Formatter.formatFileSize(context, mi.availMem);// 将获取的内存大小规格化

        return mi.availMem / (1024 * 1024);

    }

   

    /**

  * 获取已用内存大小

  * @param context

  * @return

  */

    public static long getUsedMemory(Context context) {

       

        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        MemoryInfo mi = new MemoryInfo();

        am.getMemoryInfo(mi);

        //return Formatter.formatFileSize(context, mi.availMem);// 将获取的内存大小规格化

        return (mi.totalMem - mi.availMem) / (1024 * 1024);

    }

   

    /**

  * 获取总的内存大小

  * @param context

  * @return

  */

    public static long getTotalMemory(Context context) {

       

        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        MemoryInfo mi = new MemoryInfo();

        am.getMemoryInfo(mi);

        return mi.totalMem / (1024 * 1024);

    }

}

//资源文件

activity_main.xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context="com.example.atest_rectui.MainActivity" >

    <com.example.atest_rectui.widget.ClearMemoryView

        android:id="@+id/tv_myclearmemory"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"

        android:focusable="true"

         />

</RelativeLayout>

dimens.xml 文件

<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->

    <dimen name="activity_horizontal_margin">16dp</dimen>

    <dimen name="activity_vertical_margin">16dp</dimen>

 <dimen name="dimen_bottom_item_layout">110dp</dimen>

</resources>

strings.xml文件

<?xml version="1.0" encoding="utf-8"?>

<resources>

    <string name="app_name">atest_rectui</string>

    <string name="hello_world">Hello world!</string>

    <string name="action_settings">Settings</string>

    <string name="release_memory">Release memory for</string>

    <string name="currunt_memory">Current memory available is</string>

    <string name="best_memory_status">Has been cleaned up to the best</string>

</resources>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: