亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android繪制動態折線圖

2019-10-21 21:30:54
字體:
來源:轉載
供稿:網友

所謂動態折線圖,就是折線圖能隨著手指的滑動進行動態繪制,這里很定會產生動畫效果?;谶@個效果,這里使用SurfaceView進行制圖。

實現步奏如下:

(1): 這里新建一個繪圖ChartView,繼承SurfaceView并實現SurfaceHolder.Callback , Runnable接口,主要繪圖工作在子線程中完成。
(2):現實 SurfaceHolder.Callback接口的三個方法,并在 surfaceCreated中開啟子線程進行繪圖。
(3):重寫onTouchEvent方法,在Move事件中,根據手指的滑動距離計算偏移量,具體實現請看代碼。
(4): 這里的折線圖的坐標值是隨意添加的,可以在實際項目中根據需求自己添加。
(5):此例中有大量從集合中添加和刪除元素,建議使用LinkedList來進行保存數據。

自定義ChartView:

public class ChartView extends SurfaceView implements SurfaceHolder.Callback , Runnable{ private Context mContext; private Paint mPaint; private Resources res; private DisplayMetrics dm; private int canvasHeight; private int canvasWidth; private int bHeight = 0; private int bWidth; private boolean isMeasure = true; private boolean canScrollRight = true; private boolean canScrollLeft = true; //y軸最大值 private int maxValue; //y軸間隔值 private int averageValue; private int marginTop = 20; private int marginBottom = 80; //曲線上的總點數 private Point[] mPoints; //縱坐標值 private LinkedList<Double> yRawData; //橫坐標值 private LinkedList<String> xRawData; //根據間隔計算出的每個X的值 private LinkedList<Integer> xList = new LinkedList<>(); private LinkedList<String> xPreData = new LinkedList<>(); private LinkedList<Double> yPreData = new LinkedList<>(); private LinkedList<String> xLastData = new LinkedList<>(); private LinkedList<Double> yLastData = new LinkedList<>(); private int spacingHeight; private SurfaceHolder holder; private boolean isRunning = true; private int lastX; private int offSet; private Rect mRect; private int xAverageValue = 0; public ChartView(Context context) {  this(context , null); } public ChartView(Context context , AttributeSet attrs) {  super(context, attrs);  this.mContext = context;  initView(); } private void initView() {  this.res = mContext.getResources();  this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  dm = new DisplayMetrics();  WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);  wm.getDefaultDisplay().getMetrics(dm);  xPreData.add("05-18");  xPreData.add("05-17");  xPreData.add("05-16");  xPreData.add("05-15");  xPreData.add("05-14");  xPreData.add("05-13");  yPreData.add(4.53);  yPreData.add(3.45);  yPreData.add(6.78);  yPreData.add(5.21);  yPreData.add(2.34);  yPreData.add(6.32);  xLastData.add("05-26");  xLastData.add("05-27");  xLastData.add("05-28");  xLastData.add("05-29");  xLastData.add("05-30");  xLastData.add("05-31");  yLastData.add(2.35);  yLastData.add(5.43);  yLastData.add(6.23);  yLastData.add(7.33);  yLastData.add(3.45);  yLastData.add(2.45);  holder = this.getHolder();  holder.addCallback(this); } @Override protected void onSizeChanged(int w , int h , int oldW , int oldH) {  if (isMeasure)  {   this.canvasHeight = getHeight();   this.canvasWidth = getWidth();   if (bHeight == 0)   {    bHeight = canvasHeight - marginBottom;   }   bWidth = dip2px(30);   xAverageValue = (canvasWidth - bWidth) / 7;   isMeasure = false;  } } @Override public void run() {  while (isRunning)  {   drawView();   try   {    Thread.sleep(100);   }   catch (InterruptedException e)   {    e.printStackTrace();   }  } } private void drawView() {  Canvas canvas = holder.lockCanvas();  canvas.drawColor(Color.WHITE);  mPaint.setColor(res.getColor(R.color.color_f2f2f2));  drawAllXLine(canvas);  mRect = new Rect(bWidth - 3, marginTop - 5 ,    bWidth + (canvasWidth - bWidth) / yRawData.size() * (yRawData.size() - 1) + 3, bHeight + marginTop + marginBottom);  //鎖定畫圖區域  canvas.clipRect(mRect);  drawAllYLine(canvas);  mPoints = getPoints();  mPaint.setColor(res.getColor(R.color.color_ff4631));  mPaint.setStrokeWidth(dip2px(2.5f));  mPaint.setStyle(Paint.Style.STROKE);  drawLine(canvas);  mPaint.setStyle(Paint.Style.FILL);  for (int i = 0 ; i < mPoints.length ; i++)  {   canvas.drawCircle(mPoints[i].x , mPoints[i].y , 5 , mPaint);  }  holder.unlockCanvasAndPost(canvas); } //繪制折線圖 private void drawLine(Canvas canvas) {  Point startP = null;  Point endP = null;  for (int i = 0 ; i < mPoints.length - 1; i++)  {   startP = mPoints[i];   endP = mPoints[i + 1];   canvas.drawLine(startP.x , startP.y , endP.x , endP.y , mPaint);  } } //繪制所有的縱向分割線 private void drawAllYLine(Canvas canvas) {  for (int i = 0 ; i < yRawData.size() ; i++)  {   if (i == 0)   {    canvas.drawLine(bWidth, marginTop , bWidth, bHeight + marginTop , mPaint);   }   if (i == yRawData.size() - 1)   {    canvas.drawLine(bWidth + xAverageValue * i, marginTop , bWidth + xAverageValue * i , bHeight + marginTop , mPaint);   }   xList.add(bWidth + xAverageValue * i);   canvas.drawLine(bWidth + xAverageValue * i + offSet, marginTop , bWidth + xAverageValue * i + offSet , bHeight + marginTop , mPaint);   drawText(xRawData.get(i) , bWidth + xAverageValue * i - 30 + offSet, bHeight + dip2px(26) , canvas);  } } //繪制所有的橫向分割線 private void drawAllXLine(Canvas canvas) {  for (int i = 0 ; i < spacingHeight + 1 ; i++)  {   canvas.drawLine(bWidth , bHeight - (bHeight / spacingHeight) * i + marginTop ,     bWidth + xAverageValue * (yRawData.size() - 1) , bHeight - (bHeight / spacingHeight) * i + marginTop , mPaint);   drawText(String.valueOf(averageValue * i) , bWidth / 2 , bHeight - (bHeight / spacingHeight) * i + marginTop, canvas);  } } //繪制坐標值 private void drawText(String text , int x , int y , Canvas canvas) {  Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);  p.setTextSize(dip2px(12));  p.setColor(res.getColor(R.color.color_999999));  p.setTextAlign(Paint.Align.LEFT);  canvas.drawText(text , x , y , p); } @Override public void surfaceCreated(SurfaceHolder surfaceHolder) {  new Thread(this).start();  Log.d("OOK" , "Created"); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {  Log.d("OOK" , "Changed"); } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {  isRunning = false;  try  {   Thread.sleep(500);  }  catch (InterruptedException e)  {   e.printStackTrace();  } } @Override public boolean onTouchEvent(MotionEvent event) {  int action = event.getAction();  int rawX = (int) event.getX();  switch (action)  {   case MotionEvent.ACTION_DOWN:    lastX = rawX;    break;   case MotionEvent.ACTION_MOVE:    int offsetX = rawX - lastX;    if (xPreData.size() == 0 && offSet > 0)    {     offSet = 0;     canScrollRight = false;    }    if (xLastData.size() == 0 && offSet < 0)    {     offSet = 0;     canScrollLeft = false;    }    offSet = offSet + offsetX;    if (offSet > xAverageValue && canScrollRight)    {     offSet = offSet % xAverageValue;     xRawData.addFirst(xPreData.pollFirst());     yRawData.addFirst(yPreData.pollFirst());     xLastData.addFirst(xRawData.removeLast());     yLastData.addFirst(yRawData.removeLast());     canScrollLeft = true;    }    if (offSet < -xAverageValue && canScrollLeft)    {     offSet = offSet % xAverageValue;     xRawData.addLast(xLastData.pollFirst());     yRawData.addLast(yLastData.pollFirst());     xPreData.addFirst(xRawData.removeFirst());     yPreData.addFirst(yRawData.removeFirst());     canScrollRight = true;    }    lastX = rawX;    break;   case MotionEvent.ACTION_UP:    break;  }  return true; } private Point[] getPoints() {  Point[] points = new Point[yRawData.size()];  for (int i = 0 ; i < yRawData.size() ; i++)  {   int ph = bHeight - (int)(bHeight * (yRawData.get(i) / maxValue));   points[i] = new Point(xList.get(i) + offSet , ph + marginTop);  }  return points; } public void setData(LinkedList<Double> yRawData , LinkedList<String> xRawData , int maxValue , int averageValue) {  this.maxValue = maxValue;  this.averageValue = averageValue;  this.mPoints = new Point[yRawData.size()];  this.yRawData = yRawData;  this.xRawData = xRawData;  this.spacingHeight = maxValue / averageValue; } private int dip2px(float dpValue) {  return (int) (dpValue * dm.density + 0.5f); }}

MainActivity代碼:

public class MainActivity extends Activity{ LinkedList<Double> yList; LinkedList<String> xRawData; ChartView chartView; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main_activity);  chartView = (ChartView) findViewById(R.id.chartView);  yList = new LinkedList<>();  yList.add(2.203);  yList.add(4.05);  yList.add(6.60);  yList.add(3.08);  yList.add(4.32);  yList.add(2.0);  yList.add(5.0);  xRawData = new LinkedList<>();  xRawData.add("05-19");  xRawData.add("05-20");  xRawData.add("05-21");  xRawData.add("05-22");  xRawData.add("05-23");  xRawData.add("05-24");  xRawData.add("05-25");  chartView.setData(yList , xRawData , 8 , 2); }}

此例頁面布局比較簡單,就是在主頁面布局中添加一個自定義的ChartView即可,這里不再貼出??赡軐懙糜悬c倉促,如果不妥之處,請大家批評指正,謝謝!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人黄色av网站| 国产精品久久久久久av下载红粉| 国产日韩精品在线观看| 97视频人免费观看| 成人午夜在线观看| 日韩国产精品亚洲а∨天堂免| 色午夜这里只有精品| 高清欧美性猛交xxxx黑人猛交| 国产精品爽黄69| 欧美激情日韩图片| 日本在线观看天堂男亚洲| 色综合伊人色综合网站| 日韩精品在线观| 国产久一一精品| 国产精品三级久久久久久电影| 国产精品一区二区久久久久| 68精品国产免费久久久久久婷婷| 中文字幕日韩av| 亚洲人成网7777777国产| 狠狠躁天天躁日日躁欧美| 日韩av综合中文字幕| 亚洲人成网7777777国产| 欧美成人精品影院| 国产日韩在线视频| 亚洲精品一区中文| 在线观看日韩www视频免费| 国产精品久久久久国产a级| 久久综合久久八八| 国产精品免费网站| 日本国产一区二区三区| 午夜精品在线视频| 国产aⅴ夜夜欢一区二区三区| 亚洲成人激情在线观看| 92裸体在线视频网站| 亚洲精品国产综合久久| 国产精品99久久久久久白浆小说| 国产免费亚洲高清| 国内精品久久久久伊人av| 欧美激情2020午夜免费观看| 性色av一区二区三区在线观看| 欧美国产精品va在线观看| 日本精品视频在线播放| 成人性生交大片免费观看嘿嘿视频| 欧美电影在线播放| 久久精品成人欧美大片| 裸体女人亚洲精品一区| 国产美女久久久| 久久视频在线直播| 国产日韩欧美在线观看| 亚洲精品白浆高清久久久久久| 欧美日韩ab片| 91精品国产精品| 欧美国产视频日韩| 98精品国产自产在线观看| 美乳少妇欧美精品| 欧美肥臀大乳一区二区免费视频| 国产精品久久久久久久久久久久久| 国产在线视频一区| 精品久久久av| 久久不射热爱视频精品| 国产精品免费一区| 国产精品日韩精品| 亚洲在线观看视频| 性视频1819p久久| 欧美日韩国产成人在线| 国产精品白丝av嫩草影院| 深夜福利日韩在线看| 久久国产精品电影| 欧美激情久久久久久| 中文字幕亚洲欧美在线| 国产精品久久久久久影视| 国模视频一区二区| 亚洲欧美福利视频| 国产成人免费av| 成人免费视频网| 国产精品美女主播在线观看纯欲| 九九久久久久99精品| 久久视频在线看| 精品国产老师黑色丝袜高跟鞋| 欧美成人午夜剧场免费观看| 日韩av在线一区| 狠狠色香婷婷久久亚洲精品| 国产69精品久久久久久| 亚洲最大的av网站| 色综合久久中文字幕综合网小说| 亚洲精品成a人在线观看| 国产91精品黑色丝袜高跟鞋| 国产欧美日韩免费看aⅴ视频| 一区二区三区动漫| 亚洲国产精品成人一区二区| 欧美在线亚洲在线| 欧美一区二区三区免费视| 91视频国产一区| 伊人久久精品视频| 国产精品久久久久久搜索| 精品国产依人香蕉在线精品| 亚洲欧美第一页| 97国产suv精品一区二区62| 欧美一级淫片aaaaaaa视频| 亚洲a中文字幕| 久久精品久久精品亚洲人| 国产精品美女网站| 欧美中文字幕精品| 国产成人jvid在线播放| 黑人欧美xxxx| 国产91色在线免费| 日韩av电影在线免费播放| 日韩高清电影免费观看完整版| 一区二区欧美激情| 日韩av免费在线播放| 国产精品久久久久久久久久久久| 色偷偷888欧美精品久久久| 亚洲变态欧美另类捆绑| 久久精品91久久香蕉加勒比| 亚洲国产精品大全| 亚洲国产精久久久久久| 久久免费福利视频| 久久精品国产精品亚洲| 欧美福利小视频| 亚洲精品一区av在线播放| 久久久久免费精品国产| 亚洲人成网站色ww在线| www高清在线视频日韩欧美| 国产精品视频大全| 中文字幕在线看视频国产欧美在线看完整| 伦伦影院午夜日韩欧美限制| 亚洲欧美制服综合另类| 欧美自拍大量在线观看| 欧美日韩亚洲成人| 亚洲欧美国产精品久久久久久久| 一区二区三区高清国产| 欧美激情伊人电影| 91精品国产成人www| 日韩av观看网址| 久久久久久亚洲精品不卡| 国内精品中文字幕| 国产精品成人观看视频国产奇米| 亚洲三级黄色在线观看| 欧美午夜激情视频| 欧美日韩国内自拍| 欧美亚洲国产日韩2020| 色香阁99久久精品久久久| 精品国产一区二区三区久久久狼| 青青草精品毛片| 中文字幕亚洲欧美日韩高清| 亚洲精品视频免费在线观看| 亚洲尤物视频网| 国产成人精品av在线| 欧美激情视频网| 九九九热精品免费视频观看网站| 欧美激情一区二区三级高清视频| 亚洲丝袜一区在线| 亚洲电影免费观看高清完整版在线| 原创国产精品91| 国自在线精品视频| 久久精品国产一区二区电影| 国产精品久久久久久久av电影| 久久综合免费视频影院| 日韩精品极品在线观看播放免费视频| 韩国国内大量揄拍精品视频| 91久久久久久久久| 97视频网站入口| 欧美成人精品不卡视频在线观看| 国产精品自产拍高潮在线观看|