欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)折線走勢圖

 更新時間:2019年11月20日 11:14:31   作者:姜絲兒jlq  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)折線走勢圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android折線走勢圖的具體代碼,供大家參考,具體內(nèi)容如下

先來看看效果圖

可以根據(jù)球的數(shù)量動態(tài)的改變自己的球半徑,以及線寬

代碼實(shí)現(xiàn)也是超級簡單

//獲取自定義屬性
private void obtainStyledAttrs(AttributeSet attrs) {
  TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.High_LowChartView);
  mTextSize = (int)typedArray.getDimension(R.styleable.High_LowChartView_hl_chart_textsize,mTextSize);
  mTextColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_textcolor,mTextColor);
  if (typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text)!=null){
   mHighText = typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text);
  }
  if(typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text)!=null){
   mLowText = typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text);
  }
  mHighPointColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_high_pointcolor,mHighPointColor);
  mLowPointColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_low_pointcolor,mLowPointColor);
  mMainLineColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_mianlinecolor,mMainLineColor);
  mChartLineColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_chartlinecolor,mChartLineColor);
  mChartDistance = (int) typedArray.getDimension(R.styleable.High_LowChartView_hl_chart_distance,mChartDistance);

  init();
  typedArray.recycle();
 }

//重寫onMeasure
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int width = MeasureSpec.getSize(widthMeasureSpec);
  int height = measureHeight(heightMeasureSpec);
  setMeasuredDimension(width,height);

 }
//計(jì)算view需要的高度
 private int measureHeight(int heightMeasureSpec) {
  int result = 0;
  int mode = MeasureSpec.getMode(heightMeasureSpec);
  int size = MeasureSpec.getSize(heightMeasureSpec);
  if(mode == MeasureSpec.EXACTLY){//如果給了具體值則直接用
   result=size;
  }else {
  //否則高度等于字高與球直徑的最大值
   textHeight = (mPaint.descent()-mPaint.ascent());
   float halfHeight = Math.max(textHeight, mPointMaxHeight) / 2;
   result = (int) (halfHeight+mChartDistance);
   //如果模式為AT_MOST即:測量高度不能超過父類給定的高度則取測量結(jié)果與size的最小值
   if(mode==MeasureSpec.AT_MOST){
    result = Math.min(result,size);
   }
  }
  return result;
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if(!initMeasure()) return;
  canvas.save();
  //1先畫兩條主線
  mPaint.setColor(mMainLineColor);
  mPaint.setStrokeWidth(mainLineHeight);

  //high Line
  canvas.drawLine(textWidth+DEFAULT_OFFSETTING,mainLinePosition,w,mainLinePosition,mPaint);
  //low Line
  canvas.drawLine(textWidth+DEFAULT_OFFSETTING,mainLinePosition+mChartDistance,w,mainLinePosition+mChartDistance,mPaint);

  //2再畫文字
  mPaint.setColor(mTextColor);
  mPaint.setTextAlign(Paint.Align.LEFT);
  Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
  RectF rt1=new RectF(0,mainLinePosition-textHeight/2,w,mainLinePosition+textHeight/2);
  int baseline = (int) ((rt1.bottom + rt1.top - fontMetrics.bottom - fontMetrics.top) / 2);
  canvas.drawText(mHighText,0,baseline,mPaint);
  canvas.drawText(mLowText,0,baseline+mChartDistance,mPaint);

  //3初始化小球圓心
  canvas.translate(textWidth+DEFAULT_OFFSETTING,0);

  for (int i=0;i<mPointNum;i++){
   //high point
   if (mList.get(i).isHighPoint){
//    mPaint.setColor(mHighPointColor);
//    canvas.drawCircle((pointHeight/2+offsetX)+i*(pointHeight+offsetX), mainLinePosition, pointHeight/2, mPaint);
    //存入小球的圓心坐標(biāo)
    mList.get(i).setXY((pointHeight/2+offsetX)+i*(pointHeight+offsetX),mainLinePosition);
   }else {
    //low point
//    mPaint.setColor(mLowPointColor);
//    canvas.drawCircle((pointHeight/2+offsetX)+i*(pointHeight+offsetX), mainLinePosition+mChartDistance, pointHeight/2, mPaint);
    mList.get(i).setXY((pointHeight/2+offsetX)+i*(pointHeight+offsetX),mainLinePosition+mChartDistance);
   }
  }
  //4連接小球
  if(mList.size()>=2){
   mPaint.setColor(mChartLineColor);
   mPaint.setStrokeWidth(chartLineWidth);
   for (int i=0;i<mPointNum-1;i++){
    canvas.drawLine(mList.get(i).cx,mList.get(i).cy,mList.get(i+1).cx,mList.get(i+1).cy,mPaint);
   }
  }
  //5繪制小球(為了不讓線遮蓋小球)
  for (int i=0;i<mPointNum;i++){
   //high point
   if (mList.get(i).isHighPoint){
    mPaint.setColor(mHighPointColor);
    //low point
   }else {
    mPaint.setColor(mLowPointColor);
   }
   canvas.drawCircle(mList.get(i).cx, mList.get(i).cy, pointHeight/2, mPaint);
  }
  canvas.restore();
 }

 /**
  * 根據(jù)小球數(shù)量去動態(tài)測量一些屬性
  * @return
  */
 private boolean initMeasure() {
  //根據(jù)傳進(jìn)來的point數(shù)量計(jì)算小點(diǎn)的大小,MainLine的線寬,折線的線寬
   /* 如果小球數(shù)量在1-10個,主線高度為3dip
   * 如果小球數(shù)量在10-20個,主線高度設(shè)置為2dip
   * 如果小球數(shù)量超過20個,主線高度設(shè)置為1dp
   */
  mPointNum=mList.size();
//  if(mPointNum==0) return false;
  if(10>mPointNum){
   mainLineHeight=dp2px(3);
  }else if(10<=mPointNum&&20>mPointNum){
   mainLineHeight = dp2px(2);
  }else {
   mainLineHeight = dp2px(1);
  }

  //主線長度等于總寬度-(文字寬度+30px)
  textWidth=Math.max(mPaint.measureText(mHighText),mPaint.measureText(mLowText));
  mainLineWidth = (int) (w-(textWidth+DEFAULT_OFFSETTING));

  /*小球直徑應(yīng)該由主線長度與小球數(shù)量決定*/
  //理想直徑
  float ideaDia = mainLineWidth / (mPointNum + (mPointNum + 1));
  //小球直徑不能大于最大直徑
  if(ideaDia>mPointMaxHeight){
//   Log.i("TTT","ideaDia>mPointMaxHeight");
   pointHeight = mPointMaxHeight;
   offsetX=(mainLineWidth-mPointNum*pointHeight)/(mPointNum+1);
   //(極端情況)如果小球直徑小于線高,為小球直徑+2px
  }else if(ideaDia<=mainLineHeight){
//   Log.i("TTT","ideaDia<=mPointMaxHeight");
   pointHeight = mainLineHeight+2;
   offsetX=(mainLineWidth-mPointNum*pointHeight)/(mPointNum+1);
  }else {
//   Log.i("TTT"," pointHeight=offsetX=ideaDia");
   pointHeight=offsetX=ideaDia;
  }
  //主線位置
  mainLinePosition = (h-mChartDistance)/2;
  //折線寬度
  chartLineWidth = mainLineHeight/2;
  return true;
 }

//刷新小球集合
 public void setPointList(List<AiyingPoint> list){
  if (list==null&&list.size()==0) return;
  mList.clear();
  if (list.size()>150) {
   mList.addAll(list.subList(0,150));
  } else {
   mList.addAll(list);
  }
  invalidate();
 }

使用示例

<com.android.view.High_LowChartView
   android:id="@+id/hl_chart"
   android:layout_below="@+id/tv_state"
   android:layout_marginLeft="15dp"
   android:layout_marginRight="15dp"
   android:layout_width="match_parent"
   android:layout_height="70dp"
   app:hl_chart_mianlinecolor="#CDCDCD"
   app:hl_chart_distance="55dp"
   app:hl_chart_low_pointcolor="#999999"
   app:hl_chart_high_pointcolor="#F70919"
   app:hl_chart_textsize="13sp"
   app:hl_chart_textcolor="#2f2f2f"
   app:hl_chart_chartlinecolor="#999999"
 />

好了這樣折線圖就繪制完成了,是不是很簡單呢?

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Flutter實(shí)戰(zhàn)之自定義日志打印組件詳解

    Flutter實(shí)戰(zhàn)之自定義日志打印組件詳解

    這篇文章主要介紹了Flutter實(shí)戰(zhàn)之自定義日志打印組件詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • Android持久化技術(shù)之文件的讀取與寫入實(shí)例詳解

    Android持久化技術(shù)之文件的讀取與寫入實(shí)例詳解

    這篇文章主要介紹了Android持久化技術(shù)之文件的讀取與寫入操作,結(jié)合實(shí)例形式較為詳細(xì)的分析講述了Android持久化操作的相關(guān)技巧與具體實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-01-01
  • Android 動態(tài)菜單實(shí)現(xiàn)實(shí)例代碼

    Android 動態(tài)菜單實(shí)現(xiàn)實(shí)例代碼

    這篇文章主要介紹了Android 動態(tài)菜單實(shí)現(xiàn)實(shí)例代碼的相關(guān)資料,這里附有實(shí)例代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下
    2017-01-01
  • Android實(shí)現(xiàn)透明動畫

    Android實(shí)現(xiàn)透明動畫

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)透明動畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Android 實(shí)現(xiàn)云知聲版離線語音合成

    Android 實(shí)現(xiàn)云知聲版離線語音合成

    這篇文章主要介紹了Android 實(shí)現(xiàn)云知聲版離線語音合成,目前云知聲提供免費(fèi)的離線TTS,功能也比較簡單,合成的語音也比較生硬,如果對合成的語音要求不高的話可以考慮接入。具體合成需要的小伙伴可以參考下面文章內(nèi)容
    2022-06-06
  • Flutter Widget移動UI框架使用Material和密匙Key實(shí)戰(zhàn)

    Flutter Widget移動UI框架使用Material和密匙Key實(shí)戰(zhàn)

    這篇文章主要為大家介紹了Flutter Widget移動UI框架使用Material和密匙Key實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 揭秘雙十一手機(jī)淘寶圖標(biāo)如何被動態(tài)更換

    揭秘雙十一手機(jī)淘寶圖標(biāo)如何被動態(tài)更換

    這篇文章主要介紹了每到雙十一十二的時候Android手機(jī)動態(tài)更換手機(jī)圖標(biāo)的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • Android Canvas和Bitmap結(jié)合繪圖詳解流程

    Android Canvas和Bitmap結(jié)合繪圖詳解流程

    在 Android Canvas 上繪圖非常難,在繪圖時需要理解許多不同的類和概念。這篇文章中,將介紹 Android 框架中可用的一些類,它們可以讓畫布使用時更輕松
    2021-11-11
  • Android仿新版微信浮窗效果

    Android仿新版微信浮窗效果

    在新版微信中,可以把瀏覽的文章縮小為浮窗.點(diǎn)擊浮窗繼續(xù)閱讀.這篇文章主要介紹了Android仿新版微信浮窗效果,需要的朋友可以參考下
    2018-06-06
  • Android 中Handler引起的內(nèi)存泄露

    Android 中Handler引起的內(nèi)存泄露

    本文主要介紹Android中Handler引起的內(nèi)存泄露,在實(shí)際開發(fā)中經(jīng)常會遇到使用Handler來寫異步操作的功能,如果引起內(nèi)存泄漏,看看怎么解決
    2016-08-08

最新評論