赞
踩
最近项目中遇到,需要绘制温度实时显示的曲线,纵坐标有三个区间,刻度分别不一致。中间的区域为温度适宜区,显示高度不变,但是刻度会根据实际情况改变。并且要绘制圆滑的曲线,这里使用的是赛贝尔曲线。同时需要在绘制过程中能够左右滑动曲线。下面直接上效果:
赛贝尔曲线使用的是path的方法
path.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY, currentPointX, currentPointY);
这里需要使用现有的数据点求出控制点的坐标再绘制
- // 求出控制点坐标
- final float firstDiffX = (currentPointX - prePreviousPointX);
- final float firstDiffY = (currentPointY - prePreviousPointY);
- final float secondDiffX = (nextPointX - previousPointX);
- final float secondDiffY = (nextPointY - previousPointY);
- final float firstControlPointX = previousPointX + (mLineSmoothness * firstDiffX);
- final float firstControlPointY = previousPointY + (mLineSmoothness * firstDiffY);
- final float secondControlPointX = currentPointX - (mLineSmoothness * secondDiffX);
- final float secondControlPointY = currentPointY - (mLineSmoothness * secondDiffY);
自动左右滑动引入了一个第一个点的X坐标变量firstPointX来控制,在添加数据addValue方法的最后判断点是否超过了屏幕宽度,这个时候需要重新计算第一个点的横坐标,重绘时来让曲线看上去在自动往后移动,intervalX变量是每个数据点固定移动的横坐标宽度
- firstMinX = CHARTW - originX - (m_plist.size() - 1) * intervalX - leftRightExtra;
- if (nx > CHARTW - OFFSET_RIGHT) {
- firstPointX = firstPointX - intervalX;
- }
手动滑动,重写onTouchEvent方法,postDelayed方法是手抬起后,过几秒会自动回到最后的点,继续自动滑动0
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_UP) {
- Log.d("jokey", "onTouchEvent-->ACTION_UP");
- myHander.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (m_plist != null && m_plist.size() > 0 && m_plist.get(m_plist.size() - 1).x > CHARTW - OFFSET_RIGHT) {
- firstPointX = originX - (intervalX * m_plist.size() - (CHARTW - OFFSET_RIGHT));
- }
- }
- }, 2000);
- } else if (event.getAction() == MotionEvent.ACTION_DOWN) {
- Log.d("jokey", "onTouchEvent-->ACTION_DOWN");
- myHander.removeCallbacksAndMessages(null);
- }
- if (m_plist != null && m_plist.size() > 0 && m_plist.get(m_plist.size() - 1).x < CHARTW - OFFSET_RIGHT) {
- return false;
- }
- gestureDetector.onTouchEvent(event);
- return true;
- }
手势事件的控制
- /**
- * 手势事件
- */
- class MyOnGestureListener implements GestureDetector.OnGestureListener {
- @Override
- public boolean onDown(MotionEvent e) { // 按下事件
- return false;
- }
-
- // 按下停留时间超过瞬时,并且按下时没有松开或拖动,就会执行此方法
- @Override
- public void onShowPress(MotionEvent motionEvent) {
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent motionEvent) { // 单击抬起
- return false;
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- if (e1.getX() > originX && e1.getX() < CHARTW - OFFSET_RIGHT &&
- e1.getY() > OFFSET_TOP && e1.getY() < CHARTH - OFFSET_BOTTOM) {
- //注意:这里的distanceX是e1.getX()-e2.getX()
- distanceX = -distanceX;
- if (firstPointX + distanceX > firstMaxX) {
- firstPointX = firstMaxX;
- } else if (firstPointX + distanceX < firstMinX) {
- firstPointX = firstMinX;
- } else {
- firstPointX = (int) (firstPointX + distanceX);
- }
- Log.d("jokey", "onScroll-->firstPointX: " + firstPointX);
- Log.d("jokey", "onScroll-->firstMaxX: " + firstMaxX);
- Log.d("jokey", "onScroll-->firstMinX: " + firstMinX);
- invalidate();
- }
- return false;
- }
-
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- } // 长按事件
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- return false;
- }
- }
最后来段完整的代码
- public class WarmAreDrawChart extends View {
- public int CHARTH = 0;
- public int CHARTW = 0;
- private int originX; // 原点x坐标
- private int originY; // 原点y坐标
- private int firstPointX;//第一个点x坐标
-
- private int firstMinX; // 移动时第一个点的最小x值
- private int firstMaxX; //移动时第一个点的最大x值
- private int leftRightExtra = 0;//x轴左右向外延伸的长度
-
- private int OFFSET_LEFT = 0;
- private int OFFSET_TOP = 10;
- private int OFFSET_RIGHT = 0;
- private int OFFSET_BOTTOM = 10;
- private int TEXT_OFFSET = 5;
- private int intervalX = 25; // x坐标刻度的间隔
-
- private int areWarmMin = 38;//温度适宜区低值
- private int areWarmMax = 48;//温度适宜区高值
- public int m_nCurrMovePos = 0; //当前点的个数
- private int Y_MAX = 50;//Y轴最大值
- private int Y_MIN = 35; //Y轴最小值
- public List<Point> m_plist, m_plist2, m_plist3;
- private Paint paint1, paintBack;
- private SimpleDateFormat format = new SimpleDateFormat("mm:ss", Locale.getDefault());
- private boolean isFreshTable;
- // private int addCount = 0;
- private Bitmap bitmap;
- public int warmMin, warmMax;
- private GestureDetector gestureDetector;
- private Handler myHander = new Handler();
- // private boolean isGolden;
- //曲线切率
- private float mLineSmoothness = 0.18f;
- private int intervalTimeMs = 100;//数据时间间隔,多少毫秒上传一个数据
-
- public WarmAreDrawChart(Activity activity, int warmMin, int warmMax, int intervalTimeMs) {
- super(activity);
- this.warmMin = warmMin;
- this.warmMax = warmMax;
- this.intervalTimeMs = intervalTimeMs;
- // this.isGolden = isGolden;
- m_plist = new ArrayList<>();
- m_plist2 = new ArrayList<>();
- m_plist3 = new ArrayList<>();
- //画左边的文字
- paint1 = new Paint();
- paint1.setStyle(Paint.Style.FILL);
- paint1.setColor(getResources().getColor(R.color.text_color_666));
- paint1.setAntiAlias(true);
- paint1.setTextSize(10);
- paintBack = new Paint(Paint.ANTI_ALIAS_FLAG);
- paintBack.setColor(Color.parseColor("#ffffff"));
- paintBack.setStyle(Paint.Style.FILL);
- isFreshTable = true;
- gestureDetector = new GestureDetector(activity, new MyOnGestureListener());
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- if (changed) {
- CHARTW = getWidth();
- CHARTH = getHeight();
- Log.d("jokey", "onLayout-->CHARTW: " + CHARTW);
- Log.d("jokey", "onLayout-->CHARTH: " + CHARTH);
- originX = OFFSET_LEFT;
- originY = CHARTH - OFFSET_BOTTOM;
-
- firstPointX = originX;
- Log.d("jokey", "onLayout-->firstPointX: " + firstPointX);
- firstMinX = CHARTW - originX - (m_plist.size() - 1) * intervalX - leftRightExtra;
- // 滑动时,第一个点x值最大为paddingLeft,在大于这个值就不能滑动了
- firstMaxX = firstPointX;
- Log.d("jokey", "onLayout-->firstMaxX: " + firstMaxX);
- Log.d("jokey", "onLayout-->firstMinX: " + firstMinX);
- setBackgroundColor(Color.parseColor("#ffffff"));
- }
- super.onLayout(changed, left, top, right, bottom);
- }
-
- @SuppressLint("DrawAllocation")
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- init();
- if (bitmap == null) {
- return;
- }
- canvas.drawBitmap(bitmap, 0, 0, null);
-
- drawCurve(canvas);
- drawLeftText(canvas);
- }
-
- private void init() {
- if (isFreshTable) {
- if (bitmap != null) {
- bitmap.recycle();
- bitmap = null;
- }
- bitmap = Bitmap.createBitmap(CHARTW + OFFSET_LEFT * 2, CHARTH + OFFSET_TOP * 2, Bitmap.Config.ARGB_8888);
- Canvas bufferCanvas = new Canvas(bitmap);
- drawTable(bufferCanvas);
- drawWarmAre(bufferCanvas);
-
- //画模板曲线
- isFreshTable = false;
- invalidate();
- }
- }
-
- /**
- * 温度适宜区域
- *
- * @param bufferCanvas
- */
- private void drawWarmAre(Canvas bufferCanvas) {
- //定义画笔
- Paint paint = new Paint();
- //设置颜色
- paint.setColor(0x1A0CACDD);
- //设置画笔类型
- paint.setStyle(Paint.Style.FILL);
- int gapMin = (areWarmMin - Y_MIN);
- int gapMax = (areWarmMax - Y_MIN);
- //使用画笔在画布上画矩形
- bufferCanvas.drawRect(OFFSET_LEFT,
- originY - (originY - OFFSET_TOP) * gapMax / 15 + 5,
- CHARTW,
- originY - (originY - OFFSET_TOP) * gapMin / 15 + 5, paint);
-
- //画温度适宜区文字
- Paint paintAreText = new Paint();
- paintAreText.setStyle(Paint.Style.FILL);
- paintAreText.setColor(getResources().getColor(R.color.color_warm));
- paintAreText.setAntiAlias(true);
- paintAreText.setTextSize(40);
- bufferCanvas.drawText("温 度 适 宜 区 域", (CHARTW - OFFSET_LEFT) / 3, originY - (originY - OFFSET_TOP) * 7 / 15 + 10, paintAreText);
- }
-
- private void drawTable(Canvas canvas) {
- // paint1.setStyle(Paint.Style.STROKE);
- // paint1.setStrokeWidth(2);
- // paint1.setColor(getResources().getColor(R.color.red));
- // Path path = new Path();
- // path.moveTo(originX, OFFSET_TOP);
- // path.lineTo(OFFSET_LEFT + CHARTW, OFFSET_TOP);
- // for (int i = 1; i < 15; i++) {
- // path.moveTo(originX, originY - (originY - OFFSET_TOP) * i / 15);
- // path.lineTo(OFFSET_LEFT + CHARTW, originY - (originY - OFFSET_TOP) * i / 15);
- // }
- // path.moveTo(originX, originY);
- // path.lineTo(OFFSET_LEFT + CHARTW, originY);
- // canvas.drawPath(path, paint1);
- }
-
- private void drawLeftText(Canvas canvas) {
- //画左侧数字
- canvas.drawText(Y_MAX + "", TEXT_OFFSET, OFFSET_TOP + 5, paint1);
- int gapMin = (areWarmMin - Y_MIN);
- int gapMax = (areWarmMax - Y_MIN);
- canvas.drawText(String.valueOf(warmMin), TEXT_OFFSET, originY - (originY - OFFSET_TOP) * gapMin / 15 + 5, paint1);
- canvas.drawText(String.valueOf(warmMax), TEXT_OFFSET, originY - (originY - OFFSET_TOP) * gapMax / 15 + 5, paint1);
-
- canvas.drawText(Y_MIN + "", TEXT_OFFSET, CHARTH - OFFSET_BOTTOM + 7, paint1);
- canvas.drawText("℃/min", OFFSET_LEFT + 18, CHARTH, paint1);
- }
-
- private void drawCurve(Canvas canvas) {
-
- Paint paintBlue = new Paint(Paint.ANTI_ALIAS_FLAG);
- paintBlue.setColor(getResources().getColor(R.color.colorAccent));
- paintBlue.setStrokeWidth(2f);
- paintBlue.setStyle(Paint.Style.STROKE);
-
- Paint paintGreen = new Paint(Paint.ANTI_ALIAS_FLAG);
- paintGreen.setColor(getResources().getColor(R.color.color_19D9CB));
- paintGreen.setStrokeWidth(2f);
- paintGreen.setStyle(Paint.Style.STROKE);
-
- Paint paintRed = new Paint(Paint.ANTI_ALIAS_FLAG);
- paintRed.setColor(getResources().getColor(R.color.color_FE6085));
- paintRed.setStrokeWidth(2f);
- paintRed.setStyle(Paint.Style.STROKE);
-
- int size = m_plist.size();
- //画线
- // if (size > 0) {
- // for (int i = 0; i < size - 2; i++) {
- // canvas.drawLine(firstPointX + i * intervalX, m_plist.get(i).y, firstPointX + (i + 1) * intervalX, m_plist.get(i + 1).y, paintBlue);
- // if (m_plist2.size() > 0) {
- // canvas.drawLine(firstPointX + i * intervalX, m_plist2.get(i).y, firstPointX + (i + 1) * intervalX, m_plist2.get(i + 1).y, paintGreen);
- // }
- // if (m_plist3.size() > 0) {
- // canvas.drawLine(firstPointX + i * intervalX, m_plist3.get(i).y, firstPointX + (i + 1) * intervalX, m_plist3.get(i + 1).y, paintRed);
- // }
- // }
- // }
-
- Path path = new Path();
- // Path path2 = new Path();
- // Path path3 = new Path();
- float prePreviousPointX = Float.NaN;
- float prePreviousPointY = Float.NaN;
- float previousPointX = Float.NaN;
- float previousPointY = Float.NaN;
- float currentPointX = Float.NaN;
- float currentPointY = Float.NaN;
- float nextPointX;
- float nextPointY;
-
- int lineSize = m_plist.size();
- for (int i = 0; i < lineSize; i++) {
- if (firstPointX + i * intervalX < 0) {
- continue;
- }
- if (firstPointX + i * intervalX > CHARTW) {
- break;
- }
- if (Float.isNaN(currentPointX)) {
- currentPointX = firstPointX + i * intervalX;
- currentPointY = m_plist.get(i).y;
- }
- if (Float.isNaN(previousPointX)) {
- //是第一个点?
- if (i > 0) {
- previousPointX = firstPointX + (i - 1) * intervalX;
- previousPointY = m_plist.get(i - 1).y;
- } else {
- //用当前点表示上一个点
- previousPointX = currentPointX;
- previousPointY = currentPointY;
- }
- }
- if (Float.isNaN(prePreviousPointX)) {
- //是前两个点?
- if (i > 1) {
- prePreviousPointX = firstPointX + (i - 2) * intervalX;
- prePreviousPointY = m_plist.get(i - 2).y;
- } else {
- //当前点表示上上个点
- prePreviousPointX = previousPointX;
- prePreviousPointY = previousPointY;
- }
- }
- // 判断是不是最后一个点了
- if (i < lineSize - 1) {
- nextPointX = firstPointX + (i + 1) * intervalX;
- nextPointY = m_plist.get(i + 1).y;
- } else {
- //用当前点表示下一个点
- nextPointX = currentPointX;
- nextPointY = currentPointY;
- }
- if (i == 0) {
- // 将Path移动到开始点
- path.moveTo(currentPointX, currentPointY);
- } else {
- // 求出控制点坐标
- final float firstDiffX = (currentPointX - prePreviousPointX);
- final float firstDiffY = (currentPointY - prePreviousPointY);
- final float secondDiffX = (nextPointX - previousPointX);
- final float secondDiffY = (nextPointY - previousPointY);
- final float firstControlPointX = previousPointX + (mLineSmoothness * firstDiffX);
- final float firstControlPointY = previousPointY + (mLineSmoothness * firstDiffY);
- final float secondControlPointX = currentPointX - (mLineSmoothness * secondDiffX);
- final float secondControlPointY = currentPointY - (mLineSmoothness * secondDiffY);
- //画出曲线
- path.cubicTo(firstControlPointX, firstControlPointY, secondControlPointX, secondControlPointY,
- currentPointX, currentPointY);
- }
-
- // 更新
- prePreviousPointX = previousPointX;
- prePreviousPointY = previousPointY;
- previousPointX = currentPointX;
- previousPointY = currentPointY;
- currentPointX = nextPointX;
- currentPointY = nextPointY;
- //显示时间
-
- if (i != 0 && i % (60 * (1000 / intervalTimeMs)) == 0) {
- canvas.drawText((i / (60 * (1000 / intervalTimeMs))) + "min", firstPointX + i * intervalX, CHARTH - 5, paint1);
- }
- }
-
- canvas.drawPath(path, paintBlue);
- // for (int i = 0; i < size; i++) {
- // if (i == 0) {
- // path.moveTo(firstPointX, m_plist.get(i).y);
- // if (m_plist2 != null && m_plist2.size() > 0) {
- // path2.moveTo(firstPointX, m_plist2.get(i).y);
- // }
- // if (m_plist3 != null && m_plist3.size() > 0) {
- // path3.moveTo(firstPointX, m_plist3.get(i).y);
- // }
- // } else {
- // path.lineTo(firstPointX + i * intervalX, m_plist.get(i).y);
- // if (m_plist2 != null && m_plist2.size() > 0) {
- // path2.lineTo(firstPointX + i * intervalX, m_plist2.get(i).y);
- // }
- // if (m_plist3 != null && m_plist3.size() > 0) {
- // path3.lineTo(firstPointX + i * intervalX, m_plist3.get(i).y);
- // }
- // }
- // }
- // canvas.drawPath(path, paintBlue);
- // if (m_plist2 != null && m_plist2.size() > 0) {
- // paintBlue.setColor(getResources().getColor(R.color.color_19D9CB));
- // canvas.drawPath(path2, paintBlue);
- // }
- // if (m_plist3 != null && m_plist3.size() > 0) {
- // paintBlue.setColor(getResources().getColor(R.color.color_FE6085));
- // canvas.drawPath(path3, paintBlue);
- // }
-
-
- // 截取折线超出部分(右边)
- paintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
- RectF rectF = new RectF(CHARTW - OFFSET_RIGHT, 0, CHARTW, CHARTH);
- canvas.drawRect(rectF, paintBack);
- canvas.save();
- canvas.restore();
- //将折线超出x轴坐标的部分截取掉(左边)
- paintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
- rectF = new RectF(0, 0, originX, CHARTH);
- canvas.drawRect(rectF, paintBack);
- canvas.save();
- canvas.restore();
- }
-
- public void addValue(ArrayList<List<Integer>> arrayList) {
- if (arrayList != null && arrayList.size() > 0) {
- if (arrayList.get(0) != null) {
- for (int i = 0; i < arrayList.get(0).size(); i++) {
- if (arrayList.size() > 1 && arrayList.get(1) != null && arrayList.get(1).size() > 0) {
- if (arrayList.size() > 2 && arrayList.get(2) != null && arrayList.get(2).size() > 0) {
- addValue(arrayList.get(0).get(i) / 10, arrayList.get(1).get(i) / 10, arrayList.get(2).get(i) / 10);
- } else {
- addValue(arrayList.get(0).get(i) / 10, arrayList.get(1).get(i) / 10);
- }
- } else {
- addValue(arrayList.get(0).get(i) / 10);
- }
- }
- }
- }
- }
-
- private int getScreenPosY(double y) {
- int gapMin = (areWarmMin - Y_MIN);
- int gapMax = (areWarmMax - Y_MIN);
- if (y <= warmMin) {
- //底部的区域
- double ratio = (y - Y_MIN) / (warmMin - Y_MIN);
- int height = originY - (originY - OFFSET_TOP) * gapMin / 15 + 5;
- int bottom = originY;
- return bottom - (int) Math.ceil((bottom - height) * ratio);
- } else if (y <= warmMax) {
- //中间适宜区
- double ratio = (y - warmMin) / (warmMax - warmMin);
- int height = originY - (originY - OFFSET_TOP) * gapMax / 15 + 5;
- int bottom = originY - (originY - OFFSET_TOP) * gapMin / 15 + 5;
- return bottom - (int) Math.ceil((bottom - height) * ratio);
- } else {
- //顶端区域
- double ratio = (y - warmMax) / (Y_MAX - warmMax);
- int height = OFFSET_TOP + 5;
- int bottom = originY - (originY - OFFSET_TOP) * gapMax / 15 + 5;
- return bottom - (int) Math.ceil((bottom - height) * ratio);
- }
- }
-
- public void addValue(double nValue) {
- if (nValue > Y_MAX) {
- nValue = Y_MAX;
- }
- if (nValue > 0 && nValue < Y_MIN) {
- nValue = Y_MIN;
- }
- int ny = getScreenPosY(nValue);
- //X坐标一样就不绘制
- int nx = OFFSET_LEFT + m_nCurrMovePos * intervalX;
- m_nCurrMovePos++;
- if (m_plist.size() == 0) {
- Point p = new Point(nx, ny);
- m_plist.add(p);
- } else {
- Point p = new Point(nx, ny);
- m_plist.add(p);
- }
- firstMinX = CHARTW - originX - (m_plist.size() - 1) * intervalX - leftRightExtra;
- if (nx > CHARTW - OFFSET_RIGHT) {
- firstPointX = firstPointX - intervalX;
- }
- // Log.d("jokey", "addValue-->firstPointX: " + firstPointX);
- invalidate();
- }
-
- public void addValue(double nValueA, double nValueB) {
- if (nValueA >= Y_MAX) {
- nValueA = Y_MAX;
- }
- if (nValueA > 0 && nValueA <= Y_MIN) {
- nValueA = Y_MIN;
- }
- int ny = getScreenPosY(nValueA);
-
- if (nValueB >= Y_MAX) {
- nValueB = Y_MAX;
- }
- if (nValueB > 0 && nValueB <= Y_MIN) {
- nValueB = Y_MIN;
- }
- int ny2 = getScreenPosY(nValueB);
- //X坐标一样就不绘制
- int nx = OFFSET_LEFT + m_nCurrMovePos * intervalX;
- m_nCurrMovePos++;
- if (m_plist.size() == 0) {
- Point p = new Point(nx, ny);
- Point p2 = new Point(nx, ny2);
- m_plist.add(p);
- m_plist2.add(p2);
- } else if ((nx - m_plist.get(m_plist.size() - 1).x) >= 5) {
- Point p = new Point(nx, ny);
- Point p2 = new Point(nx, ny2);
- m_plist.add(p);
- m_plist2.add(p2);
- }
- firstMinX = CHARTW - originX - (m_plist.size() - 1) * intervalX - leftRightExtra;
- if (nx > CHARTW - OFFSET_RIGHT) {
- firstPointX = firstPointX - intervalX;
- }
- invalidate();
- }
-
- public void addValue(double nValueA, double nValueB, double nValueC) {
- Log.d("jokey", "nValueA: " + nValueA + ",nValueB: " + nValueB + ",nValueC: " + nValueC);
- if (nValueA >= Y_MAX) {
- nValueA = Y_MAX;
- }
- if (nValueA > 0 && nValueA <= Y_MIN) {
- nValueA = Y_MIN;
- }
- int ny = getScreenPosY(nValueA);
-
- if (nValueB >= Y_MAX) {
- nValueB = Y_MAX;
- }
- if (nValueB > 0 && nValueB <= Y_MIN) {
- nValueB = Y_MIN;
- }
- int ny2 = getScreenPosY(nValueB);
-
- if (nValueC >= Y_MAX) {
- Log.d("jokey", "nValueC1: " + nValueC);
- nValueC = Y_MAX;
- }
- if (nValueC > 0 && nValueC <= Y_MIN) {
- Log.d("jokey", "nValueC2: " + nValueC);
- nValueC = Y_MIN;
- }
- int ny3 = getScreenPosY(nValueC);
- Log.d("jokey", "ny3: " + ny3);
- //X坐标一样就不绘制
- int nx = OFFSET_LEFT + m_nCurrMovePos * intervalX;
- m_nCurrMovePos++;
- if (m_plist.size() == 0) {
- Point p = new Point(nx, ny);
- Point p2 = new Point(nx, ny2);
- Point p3 = new Point(nx, ny3);
- m_plist.add(p);
- m_plist2.add(p2);
- m_plist3.add(p3);
- } else if ((nx - m_plist.get(m_plist.size() - 1).x) >= 5) {
- Point p = new Point(nx, ny);
- Point p2 = new Point(nx, ny2);
- Point p3 = new Point(nx, ny3);
- m_plist.add(p);
- m_plist2.add(p2);
- m_plist3.add(p3);
- }
- firstMinX = CHARTW - originX - (m_plist.size() - 1) * intervalX - leftRightExtra;
- if (nx > CHARTW - OFFSET_RIGHT) {
- firstPointX = firstPointX - intervalX;
- }
- invalidate();
- }
-
- /**
- * 手势事件
- */
- class MyOnGestureListener implements GestureDetector.OnGestureListener {
- @Override
- public boolean onDown(MotionEvent e) { // 按下事件
- return false;
- }
-
- // 按下停留时间超过瞬时,并且按下时没有松开或拖动,就会执行此方法
- @Override
- public void onShowPress(MotionEvent motionEvent) {
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent motionEvent) { // 单击抬起
- return false;
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- if (e1.getX() > originX && e1.getX() < CHARTW - OFFSET_RIGHT &&
- e1.getY() > OFFSET_TOP && e1.getY() < CHARTH - OFFSET_BOTTOM) {
- //注意:这里的distanceX是e1.getX()-e2.getX()
- distanceX = -distanceX;
- if (firstPointX + distanceX > firstMaxX) {
- firstPointX = firstMaxX;
- } else if (firstPointX + distanceX < firstMinX) {
- firstPointX = firstMinX;
- } else {
- firstPointX = (int) (firstPointX + distanceX);
- }
- Log.d("jokey", "onScroll-->firstPointX: " + firstPointX);
- Log.d("jokey", "onScroll-->firstMaxX: " + firstMaxX);
- Log.d("jokey", "onScroll-->firstMinX: " + firstMinX);
- invalidate();
- }
- return false;
- }
-
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- } // 长按事件
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- return false;
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_UP) {
- Log.d("jokey", "onTouchEvent-->ACTION_UP");
- myHander.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (m_plist != null && m_plist.size() > 0 && m_plist.get(m_plist.size() - 1).x > CHARTW - OFFSET_RIGHT) {
- firstPointX = originX - (intervalX * m_plist.size() - (CHARTW - OFFSET_RIGHT));
- }
- }
- }, 2000);
- } else if (event.getAction() == MotionEvent.ACTION_DOWN) {
- Log.d("jokey", "onTouchEvent-->ACTION_DOWN");
- myHander.removeCallbacksAndMessages(null);
- }
- if (m_plist != null && m_plist.size() > 0 && m_plist.get(m_plist.size() - 1).x < CHARTW - OFFSET_RIGHT) {
- return false;
- }
- gestureDetector.onTouchEvent(event);
- return true;
- }
- }
MainActivity调用
- public class MainActivity extends AppCompatActivity {
- private MyThread myThread;
- private LinearLayout llChart;
- private WarmAreDrawChart warmAreDrawChart;
- private int intervalTimeMs = 100;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- llChart = findViewById(R.id.ll_chart);
- initChart();
- initListener();
- }
-
-
- private void initListener() {
- findViewById(R.id.btn_open).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- open();
-
- });
- findViewById(R.id.btn_close).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- close();
-
- }
- });
- findViewById(R.id.btn_jie_mian2).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(MainActivity.this, ListActivity.class));
- }
- });
- }
-
- private void initChart() {
- warmAreDrawChart = new WarmAreDrawChart(this, 38, 42, intervalTimeMs);
- llChart.removeAllViews();
- llChart.addView(warmAreDrawChart);
- }
-
- private void open() {
- if (myThread == null) {
- myThread = new MyThread();
- myThread.setContinue(true);
- myThread.start();
- }
- }
-
- private void close() {
- if (myThread != null) {
- myThread.setContinue(false);
- myThread = null;
- }
- }
-
-
- private class MyThread extends Thread {
- private boolean isContinue;
-
- public void setContinue(boolean aContinue) {
- isContinue = aContinue;
- }
-
- @Override
- public void run() {
- while (isContinue) {
- int value = new Random().nextInt(16) + 35;
-
- warmAreDrawChart.addValue(value);
- SystemClock.sleep(intervalTimeMs);
- }
- }
- }
- }
xml布局
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
-
- <LinearLayout
- android:id="@+id/ll_chart"
- android:layout_width="match_parent"
- android:layout_height="200dp"
- android:orientation="horizontal">
-
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:orientation="horizontal">
- <Button
- android:id="@+id/btn_open"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="开启"/>
- <Button
- android:id="@+id/btn_close"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="关闭"/>
- <Button
- android:id="@+id/btn_jie_mian2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="界面2"/>
- </LinearLayout>
- </RelativeLayout>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。