Android 您所在的位置:网站首页 Flutter20黑马 Android

Android

2023-08-28 14:55| 来源: 网络整理| 查看: 265

前言

比较Kotlin OR Flutter 谁好, 就像在比较[程序员]和[画家]谁[唱歌]比较好听 Kotlin是语言,完美平复了我对Java的恨铁不成钢的心情。 Flutter是框架,完美实现了我一套代码,六端运行的梦想。

Flutter是和Android一个等级的,它们都是运行在设备上的框架 Kotlin是和Dart一个等级的,它们都是新时代的编程语言 那谁更香? 别问,问就都香。 如果你还在Kotlin和Flutter之间犹豫不定 那我就为你指条路: 去研究[数据结构和算法分析] 研究到想吐的时候再来选择,如果还是在Kotlin和Flutter犹豫不定 那我就为你指条路: 去研究[数据结构和算法分析] 研究到想吐的时候再来选择,如果还是在Kotlin和Flutter犹豫不定 那我就为你指条路: 去研究[数据结构和算法分析] 研究到想吐的时候再来选择,如果还是在Kotlin和Flutter犹豫不定 ... 这样最终你就会成为一个[数据结构和算法分析]的大师 而这样的大师拥有同时掌握Kotlin和Flutter的耐力和技术支持

通过本篇想说明: 不是什么技术好不好,而是你能干什么。 就像作文模板、中文汉字你都认识,却无法写出流芳百世的佳作 限制你的并非是语言/框架本身,而是你的思维分析和解决问题的能力

王侯将相宁有种乎? 何必贴上好坏的标签,非争个天下第一? 香不就行了吗!

KotlinFlutter Android-Kotlin 篇 一、自定义控件 1.类的定义 [1] 类通过[class]关键字定义,类名[大驼峰] [2] 构造器关键字[constructor],可直接跟在类名后 [3] 继承通过 : 指定父类 class HandleView constructor(context: Context, attrs: AttributeSet? = null) : View(context, attrs){ } 2.初始函数与变量定义 [1] 通过[var]关键字指定变量, [2] 通过[privite]关键字修饰私有权限 [3] 创建对象[不需要] new 关键字 [4] 一条语句的末尾[不需要] ; [5] init代码块内可以盛放数据初始逻辑 [6] 对于对象的get/set方法,可使用简写方式 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 } } 3.方法的覆写 [1] 方法的关键字[fun] [2] 复写的关键字[override] [3] 入参格式 [名称:类型 ] class HandleView constructor(context: Context, attrs: AttributeSet? = null) : View(context, attrs){ //英雄所见... override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawCircle(100f,100f,50f,paint) } } 4.使用自定义控件

这里先直接放在setContentView里看下效果

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(HandleView(this)) } } 二、事件响应

如下图,在移动时会触发事件,根据事件来处理小圆的坐标 当超越区域时,对其进行限定。放手时回到中心

1.变量介绍

zoneR:背景区域大小,即限定摇杆的区域 handleR:摇杆大小 centerX,centerY摇杆中心偏移

private var zoneR: Float = 150f private var handleR: Float = 80f priate var centerX: Float = 0f private var centerY: Float = 0f 2.绘制圆

绘制圆时,移动了一下画布,将画布左上角和中心重合

[1] 当函数返回值只要一行时,可以直接用 = 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 3.事件处理

核心就是处理好小圆的圆心在画布坐标系的位置。 分为在圆内和圆外两种情况: 触点在域内,根据触点位置确定摇杆圆心位置 触点在域外,摇杆圆心位置在域的边缘游走

在parser方法里,实现通过atan2获取夹角(图左) 然后转化为通常的坐标系(图左),由于再根据画布坐标系校正90°

[1] when 用于条件分支,相当于switch 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 zoneR) { centerX = zoneR * cos(thta) centerY = -zoneR * sin(thta) } } 4.监听器回调

现在数据是在View内部的,需要将它们暴露出去,比如旋转的角度,位移百分比 Java中设置监听,还要啰嗦一堆弄接口,校验回调。 由于Kotlin函数也是类型,回调起来就so easy

[1] (rad:Float, offset:Float) -> Unit 代表一种函数类型 lateinit var onHandleListener:(rad:Float, offset:Float) -> Unit private fun parser(event: MotionEvent) { //英雄所见... val len = sqrt(centerX * centerX + centerY * centerY) onHandleListener(rad,len/zoneR) }

使用:

[1] Kotlin 的lambda 表达式形式如下 handleView.onHandleListener= { rad,offset -> Log.e("MainActivity","角度${rad*180/Math.PI},位移:${offset}") } Flutter-Dart 篇 一、自定义组件 1. 继承自StatefulWidget

很明显,移动中需要改变状态,使用基础自继承自StatefulWidget

[1] 类通过[class]关键字定义,类名[大驼峰] [2] 继承通过 [extends] 指定父类 [3] final 修饰不可变量 [4] 构造函数通过 {this.XXX} 初始化变量,可通过具名传参 [5] 函数只要一行时,通过 => 简写 class HandleWidget extends StatefulWidget { final double zoneR; final double handleR; HandleWidget( {this.zoneR = 60.0, this.handleR = 30.0}); @override _HandleWidgetState createState() => _HandleWidgetState(); } 2.状态类中操作状态 [1] 覆写可使用 @override 注解 [2] get关键字XXX,可以像一样属性访问XXX [3] 私有包/类/字段 通过_XXX指定 class _HandleWidgetState extends State { 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; } 3 画板 [1] ..级联操作,相当于该对象

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; } } 二、事件处理

通过GestureDetector进行嵌套,即可让任意组件响应事件

@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), ), ), ); } 2.处理逻辑

逻辑和上面是一毛一样的,所以,你悟到了什么?

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; //旋转坐标系90度 if (sqrt(centerX * centerX + centerY * centerY) > zoneR) { centerX = zoneR * cos(thta); centerY = -zoneR * sin(thta); } setState(() {}); } 3.监听器回调

[1] 调用函数对象 Function(double,double) onHandleListener; class HandleWidget extends StatefulWidget { final double zoneR; final double handleR; final Function(double,double) onHandleListener; HandleWidget({this.zoneR = 60.0, this.handleR = 30.0,this.onHandleListener}); @override _HandleWidgetState createState() => _HandleWidgetState(); } parser(Offset offset) { //英雄所见... var len = sqrt(centerX * centerX + centerY * centerY); if(widget.onHandleListener!=null) widget.onHandleListener(rad,len/zoneR); setState(() {}); }

两种实现的核心是什么?也就那一个解析的过程 如果过程都明白,你管它是Kotlin还是Flutter,就是js也可以在浏览器上画出来 你需要学的从不是使用框架/语言的能力,而是思维分析和解决问题的能力 限制你的并非是框架/语言,而是你贫瘠的想象力、控制力、创造力 Flutter 可以用两天就能上手,Kotlin用一天就能了解语法 之后的是你的固有瓶颈,而非框架/语言的问题,知道做什么是最重要的 好了,如果你还在犹豫,你可以去研究[数据结构和算法分析]了,吐了再回来。

尾声

Kotlin和Dart的语法都非常简洁。Android本身的View体系比较臃肿,毕竟放在xml里,沟通起来需要费些劲 Flutter组件出来起来非常灵活,复用非常棒。最好的是属性可以很容易修改 Android里自定义View的属性挺麻烦,增加、删除、修改都费劲 Kotlin无可挑剔,除了移动端,Spring运用,还能玩js Flutter也无可挑剔,UI写起来非常爽,可以处理数据,管理状态,六端同开,前途无量 还在犹豫Flutter移动开发的人,现在Flutter对于桌面的支持,已经远远超过了你的想象。

@张风捷特烈 2020.01.21 未允禁转 我的公众号:编程之王 联系我--邮箱:[email protected] --微信:zdl1994328 ~ END ~



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有