preface

Flutter implements a scale.Copy the code

First, the effect picture:

An overview of the

This demo mainly uses the custom components of Flutter. Whether it is Vue, Android or Flutter, the idea of the front-end custom components is basically the same. Both are from 1. Package the original component 2. Combine the original component exposed method interface 3. Customize tall components with drawing (Drawing in Flutter also relies on Canvas and Paint)Copy the code

To customize a Widget with a draw method in Flutter, you need to do the following: Inherit the CustomPainter method and shouldRepaint method, draw content in Write Paint method, and use CustomPaint to build the Widget

class MyPainter extends CustomPainter { final int subGridWidth; final String valueStr; //0: first item 1: middle item 2: last item final int type; final Color colorType; Paint _linePaint; double _lineWidth = 2; MyPainter(this.subGridWidth, this.valueStr, this.type, this.colorType) { _linePaint = Paint() .. isAntiAlias = true .. style = PaintingStyle.stroke .. strokeWidth = _lineWidth .. color = colorType; } @override void paint(Canvas canvas, Size size) { drawLine(canvas, size); drawText(canvas, size); } void drawLine(Canvas canvas, Size size) { double startY, endY; Switch (type) {case 0: // startY = size.height / 2; endY = size.height; break; Case 2: // Draw only the lower part of the tail element startY = 0; endY = size.height / 2; break; Default: // Draw all middle elements startY = 0; endY = size.height; } // Draw a vertical line for (double y = startY; y <= endY; Y += subGridWidth) {if (y == size.height / 2) {canvas. DrawLine (Offset(size.width -100, y), Offset(size.width - 100 + size.height * 3 / 5, y), _linePaint); } else {canvas. DrawLine (Offset(sie.width -100, y), Offset(sie.width -100 + sie.height / 3, y), _linePaint); }}} void drawText(Canvas Canvas, Size Size) { Double halfWidth = p.minIntrinsicWidth / 2; double halfHeight = p.height / 2; canvas.drawParagraph( p, Offset(size.width - 160, size.height / 2 - halfHeight)); } ui.Paragraph _buildText(String content, double maxWidth) { ui.ParagraphBuilder paragraphBuilder = ui.ParagraphBuilder(ui.ParagraphStyle()); paragraphBuilder.pushStyle( ui.TextStyle( fontSize: 14, color: colorType, //fontFamily: "Montserrat", ), ); paragraphBuilder.addText(content); ui.Paragraph paragraph = paragraphBuilder.build(); paragraph.layout(ui.ParagraphConstraints(width: maxWidth)); return paragraph; } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }Copy the code

Among them

_linePaint = Paint() // Whether to enable anti-aliasing.. IsAntiAlias = true // Paint style, default is fill, there are two types of fill and stroke.. Style = paintingstyle. stroke width.. StrokeWidth = _lineWidth // Brush color.. color = colorType;Copy the code

Draw the string part by creating a ParagraphBuilder UI.ParagraphBuilder

/ / font style paragraphBuilder. PushStyle (UI) TextStyle (fontSize: 14, color: colorType, / / fontFamily: Montserrat,),); paragraphBuilder.addText(content); ui.Paragraph paragraph = paragraphBuilder.build(); // Limits drawing string width paragraph.Layout (UI.ParagraphConstraints(width: maxWidth));Copy the code

The ruler has a total of ten scales, but draws 11 scales. The first and last draw only half the scale. Everything else. Objective To place the long scale corresponding to the numerical point of the scale (e.g., 10 minutes) in the middle of item for easy drawing.

Switch (type) {case 0: // startY = size.height / 2; endY = size.height; break; Case 2: // Draw only the lower part of the tail element startY = 0; endY = size.height / 2; break; Default: // Draw all middle elements startY = 0; endY = size.height; }Copy the code

Draw a scale of 11 custom components to 10 scale units using ListView.

ListView.builder( physics: ClampingScrollPhysics(), padding: EdgeInsets.all(0), scrollDirection: Axis. Vertical, itemCount: 11, itemBuilder: (BuildContext Context, int index) { Color colorType; // The first normal element if (index == 0) {type = 0; } else if (index == 10) {type = 2; } else {type = 1; } if (index < 5) { colorType = Color(0xFF55D160); } else if (index > 6) { colorType = Color(0xFFFF2C2C); } else { colorType = Color(0xFFFFA82C); } return Container( child: NumberPickerItem( subGridCount: 10, subGridWidth: 5, itemWidth: Widget.widget.toint (), valueStr: ((10-index) * 10).toString() + 'mark ', type: type, colorType: colorType,); },),Copy the code

Welcome to learn and share FLUTTER with me. The project will continue to update new learning demo

Github address of this project: project address

Here is our public account: Flutter Programming Notes (CODE9871)Copy the code

The official accounts share their learning ideas from time to time

The HorizontalNumberPicker project is referenced in this demo.