Android 绘制动态图
最近準備技能大賽,需要將從傳感器中讀出的數據在移動客戶端以圖的形式繪制出來,因為平時很少繪圖,于是各種查資料,算是勉強做出來了。
以下是大賽理論效果圖(左)和實際效果圖(右),真的是理想很豐滿,現實很骨感啊!
?
?制作的整體思路:
?
繪制一個基本表:
(注意:代碼中使用了變量)
1、繪制矩形
Paint paint = new Paint();paint.setColor(Color.BLACK);paint.setStyle(Paint.Style.STROKE);Rect chartRec = new Rect(OFFSET_LEFT, OFFSET_TOP, CHARTW + OFFSET_LEFT,CHARTH + OFFSET_TOP);canvas.drawRect(chartRec, paint);2、繪制左側數值標記
canvas.drawText("100", OFFSET_LEFT - TEXT_OFFSET - 15, OFFSET_TOP + 5,paint);for (int i = 9; i > 0; i--) {canvas.drawText("" + 10 * (10 - i), OFFSET_LEFT - TEXT_OFFSET - 15,OFFSET_TOP + CHARTH / 10 * i, paint);}canvas.drawText("0", OFFSET_LEFT - TEXT_OFFSET - 10, OFFSET_TOP+ CHARTH, paint);3、繪制虛線
DashPathEffect是PathEffect類的一個子類,可以使paint畫出類似虛線的樣子,并且可以任意指定虛實的排列方式。
代碼中的float數組,必須是偶數長度,且>=2,指定了多少長度的實線之后再畫多少長度的空白.
如本代碼中,繪制長度2的實線,再繪制長度2的空白,再繪制長度2的實線,再繪制長度2的空白,依次重復.1是偏移量
PathEffect effects = new DashPathEffect(new float[] { 2, 2, 2, 2 }, 1);這樣一個基本的表格繪制完成。
?
?
動態改變界面的方法:
Handler handler=new Handler(); Runnable runnable=new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stub//要做的事情handler.postDelayed(this, 1000);} };?在這里我們采用消息傳遞機制中Handler的postDelayed(Runnable, long) 方法做定時器,每隔一秒鐘發送一次Runnable對象(該對象最后將會被封裝成Message對象)執行一次子線程中的操作。
?
最后,貼上所有代碼:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><LinearLayoutandroid:id="@+id/root"android:orientation = "vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"></LinearLayout></LinearLayout>MainActivity.class
public class MainActivity extends Activity {private Handler handler;private DrawTest dtest;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();}private void init() {LinearLayout layout = (LinearLayout) findViewById(R.id.root);dtest = new DrawTest(this);dtest.invalidate();layout.addView(dtest);handler = new Handler();handler.post(new Runnable() {@Overridepublic void run() {dtest.invalidate();handler.postDelayed(this, 2000);}});} }DrawTest.class
public class DrawTest extends View {private int CHARTH = 600;//表格的高private int CHARTW = 400;//表格的寬private int OFFSET_LEFT = 70;//距離左邊界距離private int OFFSET_TOP = 80;//距離右邊界距離private int TEXT_OFFSET = 20;//文本距離設置private int X_INTERVAL = 20;//X坐標間隔距離private List<Point> plist;//點集合public DrawTest(Context context) {super(context);plist = new ArrayList<Point>();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawTable(canvas);preparePoint();drawPoint(canvas);}/*** 繪制表* @param canvas*/private void drawTable(Canvas canvas) {Paint paint = new Paint();paint.setColor(Color.BLACK);paint.setStyle(Paint.Style.STROKE);Rect chartRec = new Rect(OFFSET_LEFT, OFFSET_TOP, CHARTW + OFFSET_LEFT,CHARTH + OFFSET_TOP);canvas.drawRect(chartRec, paint);Path textPath = new Path();// 選擇一塊區域,準備寫文字“曲線圖測試” paint.setStyle(Paint.Style.FILL);textPath.moveTo(200, 30);// 區域開始textPath.lineTo(400, 30);// 區域結束paint.setTextSize(20);paint.setAntiAlias(true);// 指定是否使用抗鋸齒功能,會消耗較大資源,繪制圖形速度會變慢。canvas.drawTextOnPath("曲線圖測試", textPath, 0, 0, paint);// 左側數值標記canvas.drawText("100", OFFSET_LEFT - TEXT_OFFSET - 15, OFFSET_TOP + 5,paint);for (int i = 9; i > 0; i--) {canvas.drawText("" + 10 * (10 - i), OFFSET_LEFT - TEXT_OFFSET - 15,OFFSET_TOP + CHARTH / 10 * i, paint);}canvas.drawText("0", OFFSET_LEFT - TEXT_OFFSET - 10, OFFSET_TOP+ CHARTH, paint);// 繪制虛線Path path = new Path();/*** PathEffect是用來控制繪制輪廓(線條)的方式。* DashPathEffect是PathEffect類的一個子類,可以使paint畫出類似虛線的樣子,并且可以任意指定虛實的排列方式.* 代碼中的float數組,必須是偶數長度,且>=2,指定了多少長度的實線之后再畫多少長度的空白.* 如本代碼中,繪制長度2的實線,再繪制長度2的空白,再繪制長度2的實線,再繪制長度2的空白,依次重復.1是偏移量,*/PathEffect effects = new DashPathEffect(new float[] { 2, 2, 2, 2 }, 1);paint.setStyle(Paint.Style.STROKE);paint.setAntiAlias(false);paint.setPathEffect(effects);// 用于設置繪制路徑時的路徑效果,如點劃線。for (int i = 1; i < 10; i++) {path.moveTo(OFFSET_LEFT, OFFSET_TOP + CHARTH / 10 * i);path.lineTo(OFFSET_LEFT + CHARTW, OFFSET_TOP + CHARTH / 10 * i);canvas.drawPath(path, paint);}}/*** 準備繪制點*/private void preparePoint() {//設置點的Y坐標為30-40int py = (CHARTH/10)*6+OFFSET_TOP + (int) Math.rint((Math.random() * (CHARTH/10)));Point p = new Point(OFFSET_LEFT + CHARTW, py);if (plist.size() > 21) {plist.remove(0);//控制點的個數//改變每一個點的X坐標for (int i = 0; i < 20; i++) {if (i == 0)plist.get(i).x -= (X_INTERVAL - 2);elseplist.get(i).x -= X_INTERVAL;}plist.add(p);} else {for (int i = 0; i < plist.size() - 1; i++) {plist.get(i).x -= X_INTERVAL;}plist.add(p);}}/*** 繪制點* * @param canvas*/private void drawPoint(Canvas canvas) {Paint paint = new Paint();paint.setColor(Color.BLACK);paint.setStrokeWidth(3);// 設置筆觸的寬度if (plist.size() >= 2) {for (int i = 0; i < plist.size() - 1; i++) {canvas.drawPoint(plist.get(i).x, plist.get(i).y, paint);}}} }?【注:invalidate ()和postInvalidate()方法的選擇:文檔中已經寫的很清楚了,如果要使用invalidate()必須要在UI主線程當中,如果不在UI主線程中,就要去調用postInValidate()】
如果大家有什么更好的方法或該文中有什么不足,希望大家指點。
Demo下載http://download.csdn.net/detail/af74776/7440807
轉載于:https://www.cnblogs.com/scetopcsa/p/3765719.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Android 绘制动态图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 位,字,字节之间关系及关联知识普及
- 下一篇: $(document).ready()