Custom controls for Flutter

You can write most OF your UI pages using common layouts and child widgets, but sometimes you see UI controls that are not as basic as these.

Just like Android and iOS native development, Flutter offers two ways to implement Flutter: composition and self-painting.

The combination control

Sometimes, the UI requirements can be met by combining some of the basic widgets into a new widget, even though the basic controls do not fulfill them.

Take a UI page in development, analyze it from top to bottom and left to right, and then write the page with the appropriate widgets. The following takes the item of the application list in a Huawei application market as an example to analyze it and combine it into a new widget.

Take Toutiao as an example for analysis: Firstly, determine the data in item and define the data structure of item

class UpdateItemModel { String appIcon; //App icon String appName; //App name String appType; //App category String appDecs; UpdateItemModel({this.appicon, this.appName, this.appType, this.appdecs}); }Copy the code

First: Split into left and right parts, you can use Row. On the left is an Image using Image, but the Image is rounded, but normal images do not support rounded corners. At this point, we can use the ClipRRect control to solve this problem; The right-hand side is a little more complicated, so let’s call it widget1,

“Widget1” : you can divide the top part and the bottom part. You can use the Column. The following is a dividing line. The top part is more complicated and is defined as widget2;

Widget2: Can be divided into two parts, you can use Row, the right side is a FlatButton, the left side is a review, defined as widget3;

Widget3: several vertically placed texts, using Column; Just come here and the analysis is done. Let’s take a look at the code and how it actually works.

It is divided into two parts, the lower part is a dividing line, and the upper part can continue to divide

Horizontal layout can be done using a Row with a Column on the left and a FlatButton on the right

Here’s the code:

class CustomDemo1 extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(" custom control "),), body: UpdateWidget(model: UpdateItemModel(appName: "新 headlines ", appIcon: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Foss.huangye88.net%2Flive%2Fuser%2F0%2F1502268284008709600-0.png&r Efer=http%3A%2F%2Foss.huangye88.net & app = 2002 & size = f9999, 10000 & q = a80 & n = 0 & g = 0 n & FMT = jpeg? The SEC = 1618804524 & b2eff4563a5421ed t = 3 62be433277abe06", appType: "News ", appDecs:" Mass video hot news efficient search "), onPressed: () {print(" Install Headlines "); },),); } } class UpdateWidget extends StatelessWidget { final UpdateItemModel model; // Final VoidCallback onPressed; UpdateWidget({Key key, this.model, this.onPressed}) : super(key: key); @override Widget build(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(10), child: ClipRect( child: Image.network( model.appIcon, width: 80, height: 80, ), ), ), Padding( padding: EdgeInsets.fromLTRB(0, 10, 10, 0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( model.appName, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20, color: Colors.black), ), Text( model.appType, style: TextStyle(fontSize: 14, color: Colors.black26), ), Text( model.appDecs, style: TextStyle(fontSize: 14, color: Colors.black26), ), ], ), Container( padding: EdgeInsets.fromLTRB(30, 0, 0, 0), alignment: Alignment.topRight, child: MaterialButton( onPressed: this.onPressed, textColor: Colors.blue, color: Colors.grey, minWidth: 30, height: 25, child: Text(" rectangleborder: rectangleradius. Circular (8), rectangleBorder: rectangleborder (borderRadius: borderRadius. Circular (8),)),),],),),); }}Copy the code

Since the draw controls

In native iOS and Android development, we can inherit UIView/View and draw in the drawRect/onDraw methods. There is a similar solution for Flutter: CustomPaint.

We all know that there are two important things in the painting process — the canvas and the brush. The brush Paint, we can configure its properties like color, style, thickness, etc. Canvas provides various common drawing methods, such as drawing line drawLine, drawing rectangle drawRect, drawing point DrawPoint, drawing path drawPath, drawing circle drawCircle, drawing arc drawArc, etc.

The general drawing process is divided into three parts:

  1. Custom class inherits CustomPainter
  2. With CustomPaint, put custom controls into widgets
  3. Use the new widget as you would use a normal widget

Here’s an example of a pie chart:

// 1. Inherit CustomPainter, Class CustomWidget extends CustomPainter {// Generates Paint getPaintByColor(Color Color) {Paint Paint = Paint();  paint.color = color; return paint; } @override void paint(Canvas Canvas, Size Size) {double wheelSize = min(sie.width, sie.height)/2; double nbElem = 6; Double radius = (2 * PI)/nbElem; // Create a rectangle Rect boundingRect = rect. fromCircle(center: Offset(wheelSize, wheelSize),radius: wheelSize); DrawArc (boundingRect, 0, radius, true, getPaintByColor(colors.blueGrey)); canvas.drawArc( boundingRect, radius * 1, radius, true, getPaintByColor(Colors.red)); canvas.drawArc( boundingRect, radius * 2, radius, true, getPaintByColor(Colors.green)); canvas.drawArc( boundingRect, radius * 3, radius, true, getPaintByColor(Colors.blue)); canvas.drawArc( boundingRect, radius * 4, radius, true, getPaintByColor(Colors.brown)); canvas.drawArc( boundingRect, radius * 5, radius, true, getPaintByColor(Colors.amber)); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return oldDelegate ! = this; }} //2. Wrap the pie chart into a new control, CustomPaint class Cake extends StatelessWidget {@override Widget Build (BuildContext context) {return CustomPaint( size: Size(200, 200), painter: CustomWidget(), ); Class CustomDemo2 extends StatelessWidget {@override Widget Build (BuildContext context) { Return Scaffold(appBar: appBar (title: Text(" draw control "), body: Center(Child: Cake(),)); }}Copy the code

conclusion

There are two ways to customize Flutter controls: composition and self-drawing. This is done by stacking up some basic widget elements to form a new control. The CustomPainter method is a bit trickier. It inherits the paint logic from the CustomPainter method. Finally, add CustomPainter to CustomPaint as a new control.

Still remember the beginning of learning Android custom controls, always very repellent, but found serious to learn, or very simple. Flutter, too, can be improved quickly through learning. Work hard to refuel!