preface
Comparing Kotlin OR Flutter, who is better, is like comparing [programmer] and [painter] who [sings] better
Kotlin is the language that perfectly soothed my feelings about Java. The Flutter is the framework that perfectly fulfills my dream of one set of code, six terminals running.
Flutter is in the same class as Android, they are both frameworks that run on devices, Kotlin is in the same class as Dart, they are both new generation programming languages. Don't ask. It smells good to ask. If you're still hesitating between Kotlin and Flutter, here's a way to do it: Study data structures and algorithm analysis until you feel like throwing up. If you're still hesitating between Kotlin and Flutter, here's a way to do it: Study data structure and algorithm analysis until you feel like throwing up. If you're still hesitating about Kotlin and Flutter, I'll give you a path: Study data structure and algorithm analysis until you feel like throwing up. Eventually you will become a master of data structure and algorithm analysis who has the stamina and technical support to master both Kotlin and FlutterCopy the code
Through this article, I want to illustrate: it's not what technology is good, but what you can do.
It’s not the language/framework itself that limits you, but your analytical and problem-solving abilities
Wang Xiang ning have seed? Why label good or bad, not for the best in the world? Don't smell good!
Kotlin | Flutter |
---|---|
Android – Kotlin article
One, custom control
1. Class definition
[1] Classes are defined by the [class] keyword. The class name [hump] [2] constructor keyword can be inherited directly after the class name [3]Copy the code
class HandleView constructor(context: Context, attrs: AttributeSet? = null) : View(context, attrs){
}
Copy the code
2. Initial function and variable definition
[1] use the [var] keyword to specify variables, [2] use the [privite] keyword to modify private permissions, [3] create objects [not required] New keyword [4] End of a statement [not required]; [5] Init code block can hold data initial logic [6] for object get/set methods, use shorthandCopy the code
class HandleView constructor(context: Context, attrs: AttributeSet? = null) : View(context, attrs){
private var paint:Paint = Paint()
init {
paint.color = Color.BLUE
paint.isAntiAlias=true
paint.style=Paint.Style.FILL
}
}
Copy the code
3. Method overwriting
[1] method keyword [fun] [2] override [3] input parameter format [name: type]Copy the code
class HandleView constructor(context: Context, attrs: AttributeSet? = null) : View(context, attrs){// Hero saw... override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawCircle(100f,100f,50f,paint) } }Copy the code
4. Use custom controls
I’m going to put it directly in the setContentView to see what it looks like
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(HandleView(this))
}
}
Copy the code
2. Event response
As shown below, the coordinates of the small circle are processed according to the event that is triggered when moving
When a region is exceeded, it is qualified. Return to center when you let go
1. Introduction to variables
HandleR: Rocker size centerX,centerY Rocker center offset
private var zoneR: Float = 150f
private var handleR: Float = 80f
priate var centerX: Float = 0f
private var centerY: Float = 0f
Copy the code
2. The drawing circle
As I draw the circle, I move the canvas so that the top left corner of the canvas coincides with the center
[1] When a function returns a single line, we can use =Copy the code
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.translate(maxR(), maxR())
paint.alpha = 100
canvas.drawCircle(0f, 0f, zoneR, paint)
paint.alpha = 150
canvas.drawCircle(centerX, centerY, handleR, paint)
}
fun maxR():Float = zoneR + handleR
Copy the code
3. Event handling
The core is to handle the location of the center of the circle in the canvas coordinate system.
It can be divided into two situations: the contact is in the domain, and the center of the rocker is determined according to the position of the contact. The contact is outside the domain, and the center of the rocker moves on the edge of the domain
In the Parser method, atan2 is used to get the Angle (left)
It is then converted to the normal coordinate system (left) due to 90° correction according to the canvas coordinate system
[1] When is used for conditional branching, equivalent to switchCopy the code
override fun onTouchEvent(event: MotionEvent): Boolean { when (event.action) { MotionEvent.ACTION_UP -> reset() else -> parser(event) } invalidate() return true } private fun reset() { centerX = 0f centerY = 0f } private fun parser(event: MotionEvent) { centerX = event.x - maxR() centerY = event.y - maxR() var rad = atan2(centerX, CenterY) if(centerX<0){rad += 2* pi.tofloat ()} val thta = rad-pi.tofloat () if(SQRT (centerX * centerX + centerY * centerY) > zoneR) { centerX = zoneR * cos(thta) centerY = -zoneR * sin(thta) } }Copy the code
4. Listener callback
Now that the data is inside the View, you need to expose them, like the Angle of rotation, the percentage of displacement
Java to set up a listener, but also a lot of verbose interface, verification callback. Since the Kotlin function is also of type, the callback is so easy
[1] (rad:Float, offset:Float) -> Unit represents a function typeCopy the code
Lateinit var onHandleListener:(rad:Float, offset:Float) -> Unit private fun Parser (event: MotionEvent) { val len = sqrt(centerX * centerX + centerY * centerY) onHandleListener(rad,len/zoneR) }Copy the code
Use:
[1] Kotlin's lambda expression is as followsCopy the code
HandleView. OnHandleListener = {rad, offset - > enter the e (" MainActivity ", "Angle ${rad * 180 / Math. PI}, displacement: ${offset}")}Copy the code
Flutter – the Dart
1. Custom components
1. Inherited from StatefulWidget
Obviously, you need to change state while moving, using the base self-inheritance from the StatefulWidget
[1] Classes are defined by the [class] keyword, class name [hump] [2] extends through [extends] specifies that the parent class [3] final modifies an immutable [4] constructor initializes a variable through {this.xxx}, and can pass a named argument [5] on a single line. Pass the => abbreviationCopy the code
class HandleWidget extends StatefulWidget { final double zoneR; final double handleR; HandleWidget({this.zoner = 60.0, this.handler = 30.0}); @override _HandleWidgetState createState() => _HandleWidgetState(); }Copy the code
2. Operation status in the status class
[1] Override can be used with the @override annotation [2] get keyword XXX, and XXX [3] private packages/classes/fields can be accessed as properties specified by _XXXCopy the code
class _HandleWidgetState extends State<HandleWidget> { double zoneR; double handleR; Double centerX = 0.0; Double centerY = 0.0; @override void initState() { zoneR=widget.zoneR; handleR=widget.handleR; super.initState(); } @override Widget build(BuildContext context) { return CustomPaint( painter: _HandleView(zoneR: zoneR, handleR: handleR, centerX: centerX, centerY: centerY) ) ); } double get maxR => zoneR + handleR; }Copy the code
3 tablets
[1].. Cascade operation, equivalent to this objectCopy the code
class _HandleView extends CustomPainter { var _paint = Paint(); var zoneR; var handleR; var centerX; var centerY; _HandleView({this.zoneR, this.handleR, this.centerX, this.centerY}) { _paint .. color = Colors.blue .. style = PaintingStyle.fill .. isAntiAlias = true; } double get maxR => zoneR + handleR; @override void paint(Canvas canvas, Size size) { canvas.translate(maxR, maxR); _paint.color = _paint.color.withAlpha(100); canvas.drawCircle(Offset(0, 0), zoneR, _paint); _paint.color = _paint.color.withAlpha(150); canvas.drawCircle(Offset(centerX, centerY), handleR, _paint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return true; }}Copy the code
Ii. Event handling
Nested through GestureDetector, any component can respond to events
@override
Widget build(BuildContext context) {
return GestureDetector(
onPanEnd: (d) => reset(),
onPanUpdate: (d) => parser(d.localPosition),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: CustomPaint(
painter: _HandleView(
zoneR: zoneR,
handleR: handleR,
centerX: centerX,
centerY: centerY),
),
),
);
}
Copy the code
2. Process logic
The logic is exactly the same, so what do you get?
reset() { centerX = 0; centerY = 0; setState(() {}); } parser(Offset offset) { centerX = offset.dx - maxR; centerY = offset.dy - maxR; var rad = atan2(centerX, centerY); if (centerX < 0) { rad += 2 * pi; } var thta = rad - pi / 2; If (SQRT (centerX * centerX + centerY * centerY) > zoneR) {centerX = zoneR * cos(thta); centerY = -zoneR * sin(thta); } setState(() {}); }Copy the code
3. Listener callback
[1] Function(double,double) onHandleListener;Copy the code
class HandleWidget extends StatefulWidget { final double zoneR; final double handleR; final Function(double,double) onHandleListener; HandleWidget ({this. ZoneR = 60.0, enclosing handleR = 30.0, enclosing onHandleListener}); @override _HandleWidgetState createState() => _HandleWidgetState(); }Copy the code
Parser (Offset Offset) {// Hero see... var len = sqrt(centerX * centerX + centerY * centerY); if(widget.onHandleListener! =null) widget.onHandleListener(rad,len/zoneR); setState(() {}); }Copy the code
What is at the heart of both implementations? That’s just the process of parsing
If the process is understood, whether it’s Kotlin or Flutter, even JS can be drawn on a browser what you need to learn is never the ability to use frame/language, it’s the ability to think and analyze and solve problems and it’s not the frame/language that limits you, But your poor imagination, control, creativity, Flutter can be picked up in two days. Kotlin can understand grammar in one day. After that, your inherent bottlenecks, not framework/language problems, know what to do. Throw up and come back.
The end of the
Both Kotlin and Dart have very concise syntax. Android’s View system itself is a bit bloated, and it takes a bit of effort to communicate in XML
The Flutter components are very flexible and reusable. Best of all, attributes can be easily modified
Android custom View attributes are quite troublesome, add, delete, modify are difficult
Kotlin is impeccable, in addition to mobile, Spring and JS
There’s nothing to be said for Flutter, too. Its UI is fun to write, handles data, manages state, and has six terminals
For those of you who were hesitant to develop Flutter mobile, Flutter now supports the desktop much more than you might think.
@Zhang Fengjietele 2020.01.21 not allowed to transfer my public number: the king of programming contact me – email :[email protected] – wechat :zdl1994328 ~ END ~