demand
Implement a temperature change curve that continuously loads the data as shown in the figure below. Gestures are supported, the graph curve moves with the drag as it continues to the left, and more data needs to be loaded as it drags to the edge.
Steps:
1. Put a surfaceView in the Activity
2. Add listeners to the surfaceView
surfaceHolder = surfaceView1.getHolder();
mMySurfaceCallback = new MySurfaceCallback();
surfaceHolder.addCallback(mMySurfaceCallback);
Copy the code
3. Implement listeners.
class MySurfaceCallback implements android.view.SurfaceHolder.Callback {
MyDraw mMyDraw;
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mMyDraw.onSurfaceChanged();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mMyDraw = new MyDraw();
mMyDraw.draw();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
Copy the code
4. Write the method of drawing graphics
class MyDraw { Paint p; Canvas canvas; int unit_x = 80; Int unit_y = 10; // Int unit_y = 10; // Final int preInit_x = 50; // Start position final int preInit_y = 550; // The largest Y vertex. Point origin; final int MAX_Fliing_X = unit_x * 20; Public MyDraw() {super(); p = new Paint(); // Create pen origin = new Point(preInit_x, preInit_y); } /** * drag range, x > 0 means drag from left to right. * * @param x_changed */ public void onFliing(float x_changed) {float newX = origin. X + x_changed; if (newX > preInit_x) newX = preInit_x; int minNewX = -((result.length) * unit_x - surfaceView1.getWidth()); boolean isToEnd = false; // Whether the last point has been reached. I drag it to the extreme right-hand limit. if (newX < minNewX) { newX = minNewX; isToEnd = true; } int x = (int) newX; if (x == origin.x) return; origin = new Point(x, origin.y); // Change the position of the coordinate origin draw(); If (isToEnd) {// Trigger the method to reach the vertex. raiseScrollToEnd(); } } public void draw() { canvas = surfaceHolder.lockCanvas(); onDdraw(canvas); surfaceHolder.unlockCanvasAndPost(canvas); } public void onDdraw(Canvas c) {log. I ("PDWY", string. format(" new origin :(%s, %s)", origine.x, origine.y)); Rect r; int height = c.getHeight(); int width = c.getWidth(); c.drawColor(Color.BLACK); p.setColor(Color.RED); p.setStrokeWidth(2); p.setStyle(Paint.Style.STROKE); r = new Rect(2, 2, width - 2, height - 2); c.drawRect(r, p); p.reset(); p.setColor(Color.RED); p.setStrokeWidth(5); float[] lines = new float[max_unit]; lines = evalPosition(result, unit_x, unit_y, origin); / / lines = new float [],0,50,500,100,400,100,400,150,500,0,0 {0}; DrawLines (lines, 2, lines.length-2, p); // drawLines(lines, 2, lines.length-2, p); // drawLines(lines, 2, lines.length-2, p); p.reset(); p.setColor(Color.parseColor("#dcdcdc")); drawEndPoint(lines, 2, lines.length - 2, p, c); } private void drawEndPoint(float[] lines, int offset, int count, Paint p2, Canvas c) { for (int i = offset; i < count; i += 2) { float x = lines[i]; float y = lines[i + 1]; c.drawCircle(x, y, 8, p2); } } private float[] evalPosition(float[] result2, int unit_widht, int unit_height, Point origin) { if (result2 == null) return new float[0]; float[] val = new float[result2.length * 4]; for (int i = 0; i < result2.length; i++) { float y = origin.y - result2[i] * unit_height; float x = origin.x + unit_widht * i; val[i * 4 + 0] = x; val[i * 4 + 1] = y; val[i * 4 + 2] = x; val[i * 4 + 3] = y; } return val; } final int max_unit = 6; public void onSurfaceChanged() { } }Copy the code
-
Register gestures that change as the finger drags.
surfaceView1.setOnTouchListener(new OnTouchListener() { int state = 0; float x_start; @Override public boolean onTouch(View v, MotionEvent event) { // mGestureDetector.onTouchEvent(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { state = 1; x_start = event.getX(); } if (event.getAction() == MotionEvent.ACTION_UP) { state = 0; x_start = 0; } if (event.getAction() == MotionEvent.ACTION_MOVE) { if (state == 1) { if (mMySurfaceCallback ! = null && mMySurfaceCallback.mMyDraw ! = null) { float xEnd = event.getX(); Float x_changed = (float) ((xend-x_start) / 1.3); If (math.abs (x_changed) > 5) {log. I ("PDWY", "moved" + x_changed); mMySurfaceCallback.mMyDraw.onFliing(x_changed); x_start = xEnd; } } } } return true; }});Copy the code
6. Remember to calculate the coordinate position, and when you keep dragging to the left at the end, trigger a custom event onScrollToEnd. Objects subscribed to this event can “load more data” at the appropriate time
/** * The drag range, x > 0 indicates the drag from left to right. * * @param x_changed */ public void onFliing(float x_changed) {float newX = origin. X + x_changed; if (newX > preInit_x) newX = preInit_x; int minNewX = -((result.length) * unit_x - surfaceView1.getWidth()); boolean isToEnd = false; // Whether the last point has been reached. I drag it to the extreme right-hand limit. if (newX < minNewX) { newX = minNewX; isToEnd = true; } int x = (int) newX; if (x == origin.x) return; origin = new Point(x, origin.y); // Change the position of the coordinate origin draw(); If (isToEnd) {// Trigger the method to reach the vertex. raiseScrollToEnd(); }}Copy the code
Implementation of custom events
ScrollToEndListener mScrollToEndListener; private void raiseScrollToEnd() { if (mScrollToEndListener ! = null) mScrollToEndListener.onScrollToEnd(); } public void setScrollToEndListener(ScrollToEndListener scrollToEndListener) { mScrollToEndListener = scrollToEndListener; } public static interface ScrollToEndListener { public void onScrollToEnd(); }Copy the code
Finally, how to use it:
public class MainActivity extends Activity { SurfaceView surfaceView1; MyCustomCurve mMyCustomCurve; float[] result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Package pck = Package.getPackage(this.getPackageName()); Resources resource = this.getResources(); surfaceView1 = (SurfaceView)findViewById(resource.getIdentifier("surfaceView1", "id", pck.getName())); mMyCustomCurve = new MyCustomCurve(this,surfaceView1); Result = new float[] {1, 30, 50, 40, 30, 5,15, 35, 20,3,12,15,31, 30, 50, 40, 30, 5,15, 35, 20,3,12,15,15}; mMyCustomCurve.setResult(result); / / when the end of the read data mMyCustomCurve setScrollToEndListener (new ScrollToEndListener () {@ Override public void onScrollToEnd () { ArrayList<Float> lst = new ArrayList<Float>(); for (int i = 0; i < result.length; i++) { lst.add(result[i]); } // Append new data, add 10 Random numbers, the value is not greater than 50. for (int j = 0; j < 10; j++) { lst.add(r.nextFloat() * 50); } float[] newArray = new float[lst.size()]; for (int i = 0; i < lst.size(); i++) { newArray[i] = lst.get(i); } result = newArray; // Set the new data source mmyCustomCurve.setresult (result); Toast.maketext (mainactivity.this, "loading a new data ", 0).show(); toast.maketext (mainactivity.this," loading a new data ", 0).show(); }}); }Copy the code
Code download extraction code: 883C