欧美成人午夜免费全部完,亚洲午夜福利精品久久,а√最新版在线天堂,另类亚洲综合区图片小说区,亚洲欧美日韩精品色xxx

扣丁學(xué)堂Android培訓(xùn)之實現(xiàn)繪制動態(tài)折線圖

2019-01-07 10:44:46 1671瀏覽

今天扣丁學(xué)堂Android培訓(xùn)老師為大家詳細(xì)介紹一下關(guān)于Android繪制動態(tài)折線圖的源碼,實現(xiàn)折線圖隨著手指的滑動進(jìn)行動態(tài)繪制效果,首先所謂動態(tài)折線圖,就是折線圖能隨著手指的滑動進(jìn)行動態(tài)繪制,這里很定會產(chǎn)生動畫效果?;谶@個效果,這里使用SurfaceView進(jìn)行制圖。



實現(xiàn)步奏如下:

(1):這里新建一個繪圖ChartView,繼承SurfaceView并實現(xiàn)SurfaceHolder.Callback,Runnable接口,主要繪圖工作在子線程中完成。

(2):現(xiàn)實SurfaceHolder.Callback接口的三個方法,并在surfaceCreated中開啟子線程進(jìn)行繪圖。

(3):重寫onTouchEvent方法,在Move事件中,根據(jù)手指的滑動距離計算偏移量,具體實現(xiàn)請看代碼。

(4):這里的折線圖的坐標(biāo)值是隨意添加的,可以在實際項目中根據(jù)需求自己添加。

(5):此例中有大量從集合中添加和刪除元素,建議使用LinkedList來進(jìn)行保存數(shù)據(jù)。

自定義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;
 
 //曲線上的總點數(shù)
 private Point[] mPoints;
 //縱坐標(biāo)值
 private LinkedList<Double> yRawData;
 //橫坐標(biāo)值
 private LinkedList<String> xRawData;
 //根據(jù)間隔計算出的每個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);
  //鎖定畫圖區(qū)域
  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);
  }
 }
 
 //繪制坐標(biāo)值
 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倉促,如果不妥之處,請大家批評指正,謝謝!

以上就是關(guān)于扣丁學(xué)堂Android培訓(xùn)之實現(xiàn)繪制動態(tài)折線圖的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,想要了解更多關(guān)于Android開發(fā)方面內(nèi)容的小伙伴,請關(guān)注扣丁學(xué)堂官網(wǎng)、微信等平臺,扣丁學(xué)堂IT職業(yè)在線學(xué)習(xí)教育平臺為您提供權(quán)威的Android開發(fā)環(huán)境搭建視頻,扣丁學(xué)堂老師精心推出的Android視頻教程定能讓你快速掌握Android從入門到精通開發(fā)實戰(zhàn)技能。


扣丁學(xué)堂微信公眾號


【關(guān)注微信公眾號獲取更多學(xué)習(xí)資料】


查看更多關(guān)于“Android開發(fā)技術(shù)的相關(guān)資訊>>

標(biāo)簽: Android培訓(xùn) Android學(xué)習(xí)路線 Android視頻教程 Android開發(fā)培訓(xùn) Android培訓(xùn)班

熱門專區(qū)

暫無熱門資訊

課程推薦

微信
微博
15311698296

全國免費咨詢熱線

郵箱:codingke@1000phone.com

官方群:148715490

北京千鋒互聯(lián)科技有限公司版權(quán)所有   北京市海淀區(qū)寶盛北里西區(qū)28號中關(guān)村智誠科創(chuàng)大廈4層
京ICP備2021002079號-2   Copyright ? 2017 - 2022
返回頂部 返回頂部