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

Android自定義控件(實(shí)現(xiàn)狀態(tài)提示圖表)

 更新時(shí)間:2016年11月03日 11:16:35   作者:工匠若水  
本篇文章主要介紹了android實(shí)現(xiàn)狀態(tài)提示圖表的功能,實(shí)現(xiàn)了動(dòng)態(tài)圖表的顯示,有需要的朋友可以了解一下。

前面分析那么多系統(tǒng)源碼了,也該暫停下來休息一下,趁昨晚閑著看見一個(gè)有意思的需求就操練一下分析源碼后的實(shí)例演練—-自定義控件。

這個(gè)實(shí)例很適合新手入門自定義控件。先看下效果圖:

橫屏模式如下:
豎屏模式如下:

看見沒有,這個(gè)控件完全自定義的,連文字等都是自定義的,沒有任何圖片等資源,就僅僅是一個(gè)小的Java文件,這個(gè)界面只有一個(gè)控件。如下咱們看下實(shí)現(xiàn)代碼。

實(shí)例代碼

如下就是整個(gè)工程的源碼了。

自定義上面展示的控件AreaChartsView源碼:

/**
 * Author    : yanbo
 * Date     : 2015-06-03
 * Time     : 09:22
 * Description : 自定義區(qū)域描述圖表View
 */
public class AreaChartsView extends View {
  private Paint mPaint;

  private int[] mZeroPos = new int[2];
  private int[] mMaxYPos = new int[2];
  private int[] mMaxXPos = new int[2];

  private int mWidth, mHight;
  private int mRealWidth, mRealHight;
  private String mTitleY, mTitleX;

  private ArrayList<Integer> mXLevel = new ArrayList<>();
  private ArrayList<Integer> mYLevel = new ArrayList<>();
  private ArrayList<String> mGridLevelText = new ArrayList<>();
  private ArrayList<Integer> mGridColorLevel = new ArrayList<>();
  private ArrayList<Integer> mGridTxtColorLevel = new ArrayList<>();

  private int mGridLevel = mXLevel.size() - 1;

  //title字符大小
  private int mXYTitleTextSize = 40;

  private int mMeasureXpos, mMeasureYpos;

  public AreaChartsView(Context context, AttributeSet attrs) {
    super(context, attrs);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setAntiAlias(true);
    mPaint.setFilterBitmap(true);
  }

  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    mWidth = getWidth();
    mHight = getHeight();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    initPosition();
    drawXYTitle(canvas);
    drawXYLine(canvas);
    drawContent(canvas);
  }

  private void initPosition() {
    //初始化坐標(biāo)圖的xy交點(diǎn)原點(diǎn)坐標(biāo)
    mZeroPos[0] = mXYTitleTextSize * 2;
    mZeroPos[1] = mHight - mXYTitleTextSize * 4;
    //初始化坐標(biāo)圖的X軸最大值坐標(biāo)
    mMaxXPos[0] = mWidth;
    mMaxXPos[1] = mHight - mXYTitleTextSize * 4;
    //初始化坐標(biāo)圖的Y軸最大值坐標(biāo)
    mMaxYPos[0] = mXYTitleTextSize * 2;
    mMaxYPos[1] = mXYTitleTextSize * 2;
  }

  private void drawXYTitle(Canvas canvas) {
    mPaint.setColor(Color.parseColor("#1FB0E7"));
    mPaint.setTextSize(mXYTitleTextSize);
    mPaint.setTextAlign(Paint.Align.LEFT);
    //畫Y軸頂?shù)膖itle
    canvas.drawText(mTitleY, mMaxYPos[0] - mXYTitleTextSize * 2, mMaxYPos[1] - mXYTitleTextSize, mPaint);
    mPaint.setTextAlign(Paint.Align.RIGHT);
    //畫X軸頂?shù)膖itle
    canvas.drawText(mTitleX, mMaxXPos[0], mMaxXPos[1] + mXYTitleTextSize * 2, mPaint);
  }

  private void drawXYLine(Canvas canvas) {
    mPaint.setColor(Color.DKGRAY);
    mPaint.setTextAlign(Paint.Align.RIGHT);
    //畫XY軸
    canvas.drawLine(mMaxYPos[0], mMaxYPos[1], mZeroPos[0], mZeroPos[1], mPaint);
    canvas.drawLine(mZeroPos[0], mZeroPos[1], mMaxXPos[0], mMaxXPos[1], mPaint);
  }

  private void drawContent(Canvas canvas) {
    mGridLevel = mXLevel.size() - 1;
    //計(jì)算出偏移title等顯示尺標(biāo)后的真實(shí)XY軸長(zhǎng)度,便于接下來等分
    mRealWidth = (mWidth - mXYTitleTextSize * 2);
    mRealHight = (mHight - mXYTitleTextSize * 4);
    //算出等分間距
    int offsetX = mRealWidth/(mGridLevel);
    int offsetY = mRealHight/(mGridLevel+1);
    //循環(huán)繪制content
    for (int index=0; index<mGridLevel+1; index++) {
      mPaint.setColor(Color.DKGRAY);
      mPaint.setTextAlign(Paint.Align.RIGHT);
      mPaint.setTextSize(mXYTitleTextSize-5);
      //繪制X軸的那些坐標(biāo)區(qū)間點(diǎn),包含0點(diǎn)坐標(biāo)
      canvas.drawText(String.valueOf(mXLevel.get(index)), mZeroPos[0]+(index*offsetX), mZeroPos[1] + mXYTitleTextSize, mPaint);

      if (index != 0) {
        //繪制Y軸坐標(biāo)區(qū)間點(diǎn),不包含0點(diǎn)坐標(biāo),X軸已經(jīng)畫過了
        canvas.drawText(String.valueOf(mYLevel.get(index)), mZeroPos[0], mZeroPos[1]-(index*offsetY), mPaint);
      }

      if (index == mGridLevel) {
        //坐標(biāo)區(qū)間 = 真實(shí)區(qū)間 + 1
        break;
      }

      mPaint.setColor(mGridColorLevel.get(mGridLevel - 1 - index));
      mPaint.setStyle(Paint.Style.FILL);
      //繪制區(qū)間疊加圖譜方塊,從遠(yuǎn)到0坐標(biāo),因?yàn)樾〉膱D會(huì)覆蓋大的圖
      canvas.drawRect(mMaxYPos[0], mMaxYPos[1] + index*offsetY, mMaxXPos[0]-index*offsetX, mMaxXPos[1], mPaint);

      mPaint.setColor(mGridTxtColorLevel.get(index));
      mPaint.setTextAlign(Paint.Align.RIGHT);
      mPaint.setTextSize(mXYTitleTextSize);
      //繪制每個(gè)方塊狀態(tài)區(qū)間的提示文字
      canvas.drawText(mGridLevelText.get(index), mMaxXPos[0] - index * offsetX - mXYTitleTextSize,
          mMaxYPos[1] + index * offsetY + mXYTitleTextSize, mPaint);
    }
    //繪制當(dāng)前坐標(biāo)
    drawNotice(canvas, offsetX, offsetY);
  }

  private void drawNotice(Canvas canvas, int offsetX, int offsetY) {
    int realPosX = 0;
    int realPosY = 0;
    //計(jì)算傳入的x值與真實(shí)屏幕坐標(biāo)的像素值的百分比差值轉(zhuǎn)換
    for (int index=0; index<mGridLevel; index++) {
      if (mMeasureXpos >= mXLevel.get(index) && mMeasureXpos < mXLevel.get(index+1)) {
        int subValue = mMeasureXpos - mXLevel.get(index);
        int offset = mXLevel.get(index+1) - mXLevel.get(index);
        realPosX = mZeroPos[0] + index*offsetX + (subValue / offset);
        break;
      }
    }
    //計(jì)算傳入的y值與真實(shí)屏幕坐標(biāo)的像素值的百分比差值轉(zhuǎn)換
    for (int index=0; index<mGridLevel; index++) {
      if (mMeasureYpos >= mYLevel.get(index) && mMeasureYpos < mYLevel.get(index+1)) {
        int subValue = mMeasureYpos - mYLevel.get(index);
        int offset = mYLevel.get(index+1) - mYLevel.get(index);
        realPosY = mZeroPos[1] - index*offsetY - (offsetY - (subValue / offset));
        break;
      }
    }
    //畫我們傳入的坐標(biāo)點(diǎn)的標(biāo)記小紅點(diǎn)
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(realPosX, realPosY, 8, mPaint);

    int[] centerPos = {mZeroPos[0] + mRealWidth/2, mZeroPos[1] - mRealHight/2};

    mPaint.setColor(Color.WHITE);
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    RectF rectF = null;
    Path path = new Path();
    //畫紅點(diǎn)旁邊的提示框和文字,有四個(gè)區(qū)域,然后提示框的小三角指標(biāo)方位不同
    if (realPosX <= centerPos[0] && realPosY >= centerPos[1]) {
      //left-bottom
      //畫三角形
      path.moveTo(realPosX+5, realPosY+5);
      path.lineTo(realPosX+15, realPosY+15);
      path.lineTo(realPosX+15, realPosY-15);
      //畫矩形背景
      rectF = new RectF(realPosX+15, realPosY-40, realPosX+200, realPosY + 30);
      canvas.drawRoundRect(rectF, 15, 15, mPaint);
      //畫提示框的文字
      mPaint.reset();
      mPaint.setColor(Color.RED);
      mPaint.setTextSize(mXYTitleTextSize - 5);
      canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX+30, realPosY, mPaint);
    }
    else if (realPosX <= centerPos[0] && realPosY < centerPos[1]) {
      //left-top
      path.moveTo(realPosX+5, realPosY+5);
      path.lineTo(realPosX+15, realPosY+15);
      path.lineTo(realPosX + 15, realPosY - 15);

      rectF = new RectF(realPosX+15, realPosY - 20, realPosX+200, realPosY + 50);
      canvas.drawRoundRect(rectF, 15, 15, mPaint);

      mPaint.reset();
      mPaint.setColor(Color.RED);
      mPaint.setTextSize(mXYTitleTextSize - 5);
      canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX+30, realPosY+20, mPaint);
    }
    else if (realPosX > centerPos[0] && realPosY >= centerPos[1]) {
      //right-bottom
      path.moveTo(realPosX-5, realPosY+5);
      path.lineTo(realPosX-15, realPosY+15);
      path.lineTo(realPosX - 15, realPosY - 15);

      rectF = new RectF(realPosX-200, realPosY-40, realPosX-15, realPosY + 30);
      canvas.drawRoundRect(rectF, 15, 15, mPaint);

      mPaint.reset();
      mPaint.setColor(Color.RED);
      mPaint.setTextSize(mXYTitleTextSize - 5);
      canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX-180, realPosY, mPaint);
    }
    else if (realPosX > centerPos[0] && realPosY < centerPos[1]) {
      //right-top
      path.moveTo(realPosX-5, realPosY+5);
      path.lineTo(realPosX-15, realPosY+15);
      path.lineTo(realPosX - 15, realPosY - 15);

      rectF = new RectF(realPosX-200, realPosY - 20, realPosX-15, realPosY + 50);
      canvas.drawRoundRect(rectF, 15, 15, mPaint);

      mPaint.reset();
      mPaint.setColor(Color.RED);
      mPaint.setTextSize(mXYTitleTextSize - 5);
      canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX-180, realPosY+30, mPaint);
    }

    path.close();
    mPaint.setColor(Color.WHITE);
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    canvas.drawPath(path, mPaint);
  }

  //設(shè)置當(dāng)前比值
  public void updateValues(int x, int y) {
    mMeasureXpos = x;
    mMeasureYpos = y;

    postInvalidate();
  }

  //設(shè)置XY軸頂角的title字體大小
  public void setTitleTextSize(int size) {
    mXYTitleTextSize = size;
  }

  //初始化X軸的坐標(biāo)區(qū)間點(diǎn)值,可以不均等分
  public void initXLevelOffset(ArrayList<Integer> list) {
    mXLevel.clear();
    mXLevel.addAll(list);
  }

  //初始化Y軸的坐標(biāo)區(qū)間點(diǎn)值,可以不均等分
  public void initYLevelOffset(ArrayList<Integer> list) {
    mYLevel.clear();
    mYLevel.addAll(list);
  }

  //初始化每個(gè)區(qū)間的提示文字,如果不想顯示可以設(shè)置""
  public void initGridLevelText(ArrayList<String> list) {
    mGridLevelText.clear();
    mGridLevelText.addAll(list);
  }

  //初始化每個(gè)區(qū)間的顏色
  public void initGridColorLevel(ArrayList<Integer> list) {
    mGridColorLevel.clear();
    mGridColorLevel.addAll(list);
  }

  //初始化每個(gè)區(qū)間的提示文字顏色
  public void initGridTxtColorLevel(ArrayList<Integer> list) {
    mGridTxtColorLevel.clear();
    mGridTxtColorLevel.addAll(list);
  }

  //初始化XY軸title
  public void initTitleXY(String x, String y) {
    mTitleX = x;
    mTitleY = y;
  }
}

再來看下布局文件:

<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">

  <com.yanbober.customerviewdemo.areachartsview.AreaChartsView
    android:id="@+id/area_charts_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"/>

</RelativeLayout>

再看看主界面:

public class MainActivity extends AppCompatActivity {
  private AreaChartsView mAreaChartsView;
  private Timer timer;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mAreaChartsView = (AreaChartsView) this.findViewById(R.id.area_charts_view);

    //初始化自定義圖表的規(guī)格和屬性
    ArrayList<Integer> mXLevel = new ArrayList<>();
    ArrayList<Integer> mYLevel = new ArrayList<>();
    ArrayList<String> mGridLevelText = new ArrayList<>();
    ArrayList<Integer> mGridColorLevel = new ArrayList<>();
    ArrayList<Integer> mGridTxtColorLevel = new ArrayList<>();
    //初始化x軸坐標(biāo)區(qū)間
    mXLevel.add(0);
    mXLevel.add(60);
    mXLevel.add(90);
    mXLevel.add(100);
    mXLevel.add(110);
    mXLevel.add(120);
    //初始化y軸坐標(biāo)區(qū)間
    mYLevel.add(0);
    mYLevel.add(90);
    mYLevel.add(140);
    mYLevel.add(160);
    mYLevel.add(180);
    mYLevel.add(200);
    //初始化區(qū)間顏色
    mGridColorLevel.add(Color.parseColor("#1FB0E7"));
    mGridColorLevel.add(Color.parseColor("#4FC7F4"));
    mGridColorLevel.add(Color.parseColor("#4FDDF2"));
    mGridColorLevel.add(Color.parseColor("#90E9F4"));
    mGridColorLevel.add(Color.parseColor("#B2F6F1"));
    //初始化區(qū)間文字提示顏色
    mGridTxtColorLevel.add(Color.parseColor("#EA8868"));
    mGridTxtColorLevel.add(Color.parseColor("#EA8868"));
    mGridTxtColorLevel.add(Color.parseColor("#EA8868"));
    mGridTxtColorLevel.add(Color.WHITE);
    mGridTxtColorLevel.add(Color.BLACK);
    //初始化區(qū)間文字
    mGridLevelText.add("異常");
    mGridLevelText.add("過高");
    mGridLevelText.add("偏高");
    mGridLevelText.add("正常");
    mGridLevelText.add("偏低");

    mAreaChartsView.initGridColorLevel(mGridColorLevel);
    mAreaChartsView.initGridLevelText(mGridLevelText);
    mAreaChartsView.initGridTxtColorLevel(mGridTxtColorLevel);
    mAreaChartsView.initXLevelOffset(mXLevel);
    mAreaChartsView.initYLevelOffset(mYLevel);
    mAreaChartsView.initTitleXY("投入量(H)", "產(chǎn)出量(H)");
  }

  @Override
  protected void onStart() {
    super.onStart();
    timer = new Timer();
    timer.schedule(new TimerTask() {
      @Override
      public void run() {
        Random random = new Random();
        int x = random.nextInt(120) % (120 + 1) + 0;
        Random randomy = new Random();
        int y = randomy.nextInt(200) % (200 + 1) + 0;
        //隨機(jī)模擬賦值
        mAreaChartsView.updateValues(x, y);
      }
    }, 0, 1000);
  }

  @Override
  protected void onPause() {
    super.onPause();
    timer.cancel();
  }
}

總結(jié)

上面代碼很簡(jiǎn)單,核心的都已經(jīng)注釋了,不需要過多解釋。核心思路就是一些坐標(biāo)點(diǎn)的計(jì)算。該控件支持設(shè)置mergin及width與hight等屬性,支持自定義所有顏色及顯示及坐標(biāo)區(qū)分等,唯一缺陷就是沒來得及寫attr屬性xml設(shè)置這些值,有興趣的自己實(shí)現(xiàn)吧,我是沒時(shí)間了。

可以發(fā)現(xiàn),自定義View無非就是重寫前面文章分析的那三個(gè)方法而已。

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

相關(guān)文章

最新評(píng)論