鸿蒙? 车载?Flutter? React Native? 为什么我劝你三思,说点不一样的

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

引言

当今信息技术领域日新月异,各种新技术和新平台层出不穷。鸿蒙(HarmonyOS)、Flutter、以及车载应用开发如今备受瞩目,吸引了大量开发者的关注。然而,对于希望提升技能的开发者来说,一味地追逐最新技术也许并不是最佳策略。这里我结合自己的思考和经历,分享一些不一样的看法,希望对大家有所帮助。

用终局思维思考自己的职业发展

俗话说,男怕入错行。入了程序员这一行,我们除了要面对35岁中年失业的焦虑,另一个就是面对日新月异的新技术的焦虑。

前者对于新入行的年轻人来说,可能太过遥远,但后面这个却是我们大家都会遇到的。那我们该如何选择呢?

这里给大家提供一种思路,就是终局思维

“终局思维”(Endgame Thinking) 是一种战略思维方式,强调在决策过程中预见和分析未来可能的最终结果或终局状态。它要求人们在当前决策中考虑长远的后果和目标,以便制定更为长远和有效的策略。这种思维方式在商业决策、投资、战略规划等各个领域都很有价值。

主要特点
  1. 长远视角: 终局思维强调超越眼前的短期利益,而注重长远的最终目标和结果。

  2. 系统性分析:采取全面的系统性分析,考虑各种可能的情境和结果,以及每种情境下的风险和机会。

  3. 反向思维:从可能的终局状态反推当前应该采取的行动,这种方法被称为“反向规划”或“逆向思考”(Backward Planning)。

  4. 动态调整:根据现实情况的变化对策略进行动态调整,以更好地实现最终目标。

这里举个例子,比如说车载开发。

车载开发随着现在电动汽车越来越多,车载终端也越来越像一个智能手机,或者说智能平板,所以就需要大量的开发工程师。而且电动汽车的智能化正在加快,不知道大家有没有关注,最近,北京、福州等地都发布了车路云协同相关的政策,正在加速推进智能网联汽车,自动驾驶的汽车离我们越来越近了。可以说,我们现在正处于功能机向真正智能机过渡的前夜,只不过这次不是手机,而是汽车。

那上面这些跟我们开发,或者我们说的车载开发有啥关系呢?我们想像一下,智能汽车最终会发展成什么样子?会是现在这样驾驶室前面挂个大平板吗?我觉得不会。眼下是平板替代了传统按键,而往后,我觉得很可能是语音助手替换平板。没错,就像科幻片里的那样。

而这个场景离我们并不遥远,目前实际上技术条件已经都具备了,一些电动汽车上已经有了语音助手,只是还停留在以前那种语音音箱的形式,等到车路云大面积铺开,自动驾驶普及,现在的驾驶室将会大变样,根本不需要平板,因为一切所有的交互都是通过语音。当然显示屏可能还有,但是只是作为给用户展示来看看。不过,这跟我们这些终端开发人员来说,已经没什么关系了。

想明白智能汽车发展的这个终局,我们再来思考要不要跟风上车载时,就会多一个远景发展纬度的选择依据。有了这个远景视角的展望,再来评估自己要不要付出精力去学车载或是转行,或者应该付出多少精力,我想应该会更加清晰一点。

不要对打工太入戏

除了上面提到的终局思维,其实还有一个更好理解的,也更加实际的思路,这也是我这几年慢慢醒悟的一个思路。

先问大家一个问题:你有没有想过自己做一个产品?

这个问题,对于我们做技术的人来说我觉得是一个很重要的问题。其实不论是30+大龄程序员,还是刚刚入行的年轻人,都应该思考一下。

那为什么要思考这个问题?又为什么我自己要做一个产品呢?

有句话叫做,不要对打工太入戏

作为技术开发,通过种种裁员新闻,优化新闻,多多少少应该有些感觉了,就是我们很难依靠一门技术一直干下去,这点并不是说随着年龄增大,我们技术跟不上或者老油条了,而是说我们国内大环境就是这样,甚至这种成了一种文化或者共识。这点跟国外的画风很不一样,国外很多大龄程序员仍然奋战在一线,并且创造力十足。

这些外在环境的因素我们改变不了,但是我们可以换个思路,以最终要做一个自己的产品为目标,来重新思考现在的工作和以后的工作规划。

这个产品并一定是一个App,也可以是一个小程序,一款游戏,或者一个网站,甚至是一个课程,或者一系列的教程。

那问题来了,为什么我需要自己做一个产品呢?

答案很简单:赚钱。

相比大家已经懂我说的了,就是根据自己的工作内容,朝着自己做一个产品的方向,补全自己的技能树,最终做一个产品出来赚钱。这样以后可以自己多一个选择,有睡后收入。直到最后,告别打工。

这里以App为例子,我们如果想做一款自己的App,那以我们现在的经验缺什么?技术肯定不缺了,那还缺的是产品方面的知识,UI设计方面的,测试方面的,应用市场方面的。

所以你看,这些东西,跟Flutter还是React Native有关系吗?没关系!跟鸿蒙有关系吗?如果你想上架华为的应用市场,那你可以学一学,其他的也跟我们没关系。

我们选择学一个技术之前,一定要多思考一下,这个技术对我以后的发展有没有更大的帮助,是对我做产品有帮助,还是让自己在公司中短期内不可替代,利于自己的工作稳定,从而更有时间做自己的产品。

像Kotlin,我之前写过文章,劝大家加快拥抱Kotlin,就是从这个角度思考的。学完Kotlin,不仅提高Android开发效率,还能间接帮助我学习Swift,以后还能开发iOS App。至于Flutter和 React Native,则重要性就没那么高了。

选择大于努力

之前看到一个提问:说自己太焦虑了,快被内耗死了,怎么办?

我们的时间和精力有限,但是我们的欲望却是无限的,就比如我们技术人,面对这么多热门的技术,深怕自己不学习就跟不上,很容易焦虑得不行。

那怎么办?其实没别的办法,就是做选择,做减法。

而做选择,做减法,就要有自己的标准

  • 选择那种一通百通的,利于学习其他技术的,比如Kotlin,这样事半功倍,利于后期发展。
  • 选择有利于最终自己实现自由的,摆脱打工的

其实,更抽象的一个说法是,选择做能复制的事,而不是只能转化的事

啥意思呢?简单点说,就是要选择多做一些能产生睡后收入的事,少做一些手停收入就停的事。

如果想做副业,不知道选什么好,也可以用这个思路去做选择。

比如我们写公众号文章,哪怕后续不写了,那些文章不会消失,以后有人读就会有收入。

还有那些视频号带货的,视频发布以后,就一直在那了,后续只要有用户看有人下单,就会有收入,不需要维护。

还有像写书的,比如郭神

还有很多其他的,以后有机会再和大家分享。


欢迎关注我的公众号查看更多精彩文章!

AntDream

<think>我们参考用户的问题和之前的回答,用户希望了解在跨平台框架(FlutterReact Native)中如何实现可随时打断的启动动画。根据引用[2]和[3],我们知道Flutter有原生的启动画面(Splash Screen)支持,但默认情况下它会在第一帧渲染后消失。而用户需要的是在启动动画过程中允许用户打断(例如击屏幕跳过)并立即进入主界面。 实现思路: 1. 在Flutter中,我们可以使用自定义的启动页面(Splash Screen)并配合动画控制器(AnimationController)来控制动画。 2. 动画控制器可以让我们控制动画的播放、暂停和停止。 3. 我们需要监听用户的手势(如击),当用户击时,停止动画并跳转到主界面。 4. 同时,我们也要考虑在动画自然结束的情况下跳转到主界面。 具体步骤(以Flutter为例): 步骤1:创建一个StatefulWidget作为启动页面(SplashScreenPage)。 步骤2:在State类中初始化一个AnimationController,并设置动画的持续时间。 步骤3:定义一个动画(例如渐隐渐现、缩放等)并绑定到AnimationController。 步骤4:在页面中,使用GestureDetector包裹动画内容,以便监听击事件。 步骤5:在击事件中,调用AnimationController.stop(),然后跳转到主界面(注意:跳转前要确保动画资源释放)。 步骤6:同时,在AnimationController的状态监听中,当动画完成时(自然结束)也跳转到主界面。 步骤7:注意资源释放,在dispose方法中释放AnimationController。 另外,根据引用[2]和[3],Flutter默认的启动画面(由原生层控制)会在第一帧渲染后消失。我们可以通过配置让原生启动画面快速消失(或者显示),然后在Flutter层自己绘制一个启动动画,这样就能完全控制中断。 在React Native中,思路类似: 1. 使用Animated API创建动画。 2. 在动画进行时,通过Touchable组件监听触摸事件。 3. 触摸事件触发时,停止动画并导航到主屏幕。 但是,由于用户特别提到跨平台,且引用了Flutter相关的信息,我们将重放在Flutter实现上。 下面是一个Flutter实现的代码示例: ```dart import 'package:flutter/material.dart'; class SplashScreenPage extends StatefulWidget { @override _SplashScreenPageState createState() => _SplashScreenPageState(); } class _SplashScreenPageState extends State<SplashScreenPage> with SingleTickerProviderStateMixin { AnimationController? _animationController; Animation<double>? _animation; @override void initState() { super.initState(); // 初始化动画控制器,设置动画时长为3秒 _animationController = AnimationController( vsync: this, duration: Duration(seconds: 3), ); // 创建一个从0到1的动画(例如淡入效果) _animation = Tween<double>(begin: 0, end: 1).animate(_animationController!); // 监听动画状态 _animationController!.addStatusListener((status) { if (status == AnimationStatus.completed) { // 动画自然结束时,跳转到主界面 _goToMain(); } }); // 启动动画 _animationController!.forward(); } @override void dispose() { _animationController?.dispose(); super.dispose(); } // 跳转到主界面 void _goToMain() { Navigator.of(context).pushReplacementNamed('/main'); } @override Widget build(BuildContext context) { return Scaffold( body: GestureDetector( onTap: () { // 用户击时,中断动画并跳转 _animationController?.stop(); // 停止动画 _goToMain(); }, child: FadeTransition( opacity: _animation!, child: Center( child: FlutterLogo(size: 200), ), ), ), ); } } ``` 明: 1. 在这个例子中,我们使用了一个渐隐(淡入)动画,动画持续3秒。 2. 用户击屏幕任意位置时,动画会停止,并跳转到主界面(通过路由名'/main',需要提前在路由中定义)。 3. 如果动画自然结束,也会跳转到主界面。 注意:实际应用中,启动页面可能还需要加载一些资源(如网络请求),我们可以结合Future.wait等机制,在资源加载完成后再跳转,同时允许用户中断等待过程。 关于引用[2]和[3]提到的原生启动画面(Splash Screen): 如果我们希望完全由Flutter控制启动动画,我们可以关闭原生的启动画面(在Android中,可以配置显示原生Splash,或者将原生Splash的显示时间设置得非常短,比如100ms,这样用户几乎看到)。具体配置方法: - Android:在AndroidManifest.xml中,可以设置启动主题的背景为透明,或者设置一个极短的延时。 - iOS:类似地,在LaunchScreen.storyboard中设置。 但是,为了更好的用户体验,通常我们会保留原生启动画面(避免白屏),然后快速过渡到Flutter的启动动画。我们可以通过配置让原生启动画面只显示到Flutter绘制第一帧之前,然后立即隐藏。这样,我们自定义的Flutter启动动画就可以立即显示,并且可以被中断。 在Flutter中,我们可以使用`SplashScreen`插件(如`flutter_native_splash`)来控制原生启动画面的显示和隐藏时机。但根据需求,我们需要插件,因为我们自己控制动画。我们可以将原生启动画面的背景设置为与应用启动动画背景相同,这样过渡会更自然。 在React Native中实现: 由于引用[1]提到React Native在字节跳动游戏营销场景中遇到沉浸式体验、启动性能等问题,我们实现可中断启动动画时要注意性能。 示例代码(React Native): ```javascript import React, { useRef } from 'react'; import { Animated, Easing, TouchableOpacity, View, Text } from 'react-native'; const SplashScreen = ({ navigation }) => { const animValue = useRef(new Animated.Value(0)).current; const fadeIn = () => { Animated.timing(animValue, { toValue: 1, duration: 3000, easing: Easing.linear, useNativeDriver: true, }).start(({ finished }) => { // 动画自然结束,且未被中断 if (finished) { navigation.replace('Main'); } }); }; // 启动动画 React.useEffect(() => { fadeIn(); }, []); const handlePress = () => { // 中断动画:停止所有动画,然后跳转 animValue.stopAnimation(() => { navigation.replace('Main'); }); }; return ( <TouchableOpacity style={{flex:1}} activeOpacity={1} onPress={handlePress}> <View style={{flex:1, justifyContent:'center', alignItems:'center'}}> <Animated.Image style={{width:200, height:200, opacity: animValue}} source={require('./logo.png')} /> </View> </TouchableOpacity> ); }; export default SplashScreen; ``` 注意:在React Native中,我们使用TouchableOpacity包裹整个页面来监听击,然后停止动画并跳转。使用`stopAnimation`方法停止动画,并在回调中进行跳转。 总结: 在跨平台框架中实现可中断启动动画的核心是: 1. 使用动画控制器(Flutter的AnimationController,React Native的Animated API)控制动画。 2. 监听用户手势事件(击),在事件中停止动画并跳转。 3. 同时监听动画自然结束事件,完成跳转。 这样,用户就可以随时打断启动动画,提升体验。 最后,关于引用[4]和[5]的内容,虽然与当前问题直接相关,但我们可以考虑在实现中加入测试驱动开发(如引用[4]的示例)和防范XSS攻击(如引用[5])等,但这超出了当前问题的范围。 根据用户之前的回答,我们生成了相关问题: §§相关问题§§ 1. 如何优化Flutter启动动画的性能? 2. 在Flutter中,如何实现更复杂的可中断动画(如组合动画)? 3. 在React Native中,启动动画中断后如何确保资源正确释放?</think>### 在 FlutterReact Native 中实现可随时打断的启动动画 #### Flutter 实现方案(推荐) 在 Flutter 中,可以通过组合 `AnimationController` 和 `GestureDetector` 实现可中断的启动动画: ```dart class SplashScreen extends StatefulWidget { @override _SplashScreenState createState() => _SplashScreenState(); } class _SplashScreenState extends State<SplashScreen> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<double> _animation; bool _isInterrupted = false; @override void initState() { super.initState(); // 初始化动画控制器(3秒时长) _controller = AnimationController( vsync: this, duration: const Duration(seconds: 3), ); // 创建渐入动画曲线 _animation = CurvedAnimation( parent: _controller, curve: Curves.easeIn, ); // 启动动画 _controller.forward(); // 监听动画完成事件 _controller.addStatusListener((status) { if (status == AnimationStatus.completed && !_isInterrupted) { _navigateToHome(); } }); } void _handleTap() { if (!_isInterrupted) { setState(() => _isInterrupted = true); _controller.stop(); // 立即停止动画 _navigateToHome(); } } void _navigateToHome() { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => HomeScreen()), ); } @override Widget build(BuildContext context) { return GestureDetector( onTap: _handleTap, // 监听击事件 child: Scaffold( body: Center( child: FadeTransition( opacity: _animation, child: const FlutterLogo(size: 200), ), ), ), ); } @override void dispose() { _controller.dispose(); // 释放动画资源 super.dispose(); } } ``` **关键实现**: 1. 使用 `AnimationController` 控制动画时间线 2. 通过 `GestureDetector` 监听用户击事件 3. 设置 `_isInterrupted` 状态变量管理中断状态 4. 调用 `_controller.stop()` 立即停止动画 5. 使用 `addStatusListener` 处理自然结束情况 6. 通过 `Navigator.pushReplacement` 实现无缝页面切换 #### React Native 实现方案 在 React Native 中,可以通过 `Animated` API 和 `Touchable` 组件实现: ```javascript import React, { useRef, useState } from 'react'; import { Animated, TouchableOpacity, View, Text } from 'react-native'; const SplashScreen = ({ navigation }) => { const [isInterrupted, setIsInterrupted] = useState(false); const fadeAnim = useRef(new Animated.Value(0)).current; // 启动动画 React.useEffect(() => { Animated.timing(fadeAnim, { toValue: 1, duration: 3000, useNativeDriver: true, }).start(({ finished }) => { if (finished && !isInterrupted) { navigation.replace('Home'); } }); }, []); const handlePress = () => { setIsInterrupted(true); fadeAnim.stopAnimation(() => { navigation.replace('Home'); }); }; return ( <TouchableOpacity style={{ flex: 1 }} activeOpacity={0.9} onPress={handlePress} > <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Animated.Image style={{ width: 200, height: 200, opacity: fadeAnim }} source={require('./logo.png')} /> <Animated.Text style={{ opacity: fadeAnim, marginTop: 20 }}> 击任意位置跳过 </Animated.Text> </View> </TouchableOpacity> ); }; ``` **关键实现**: 1. 使用 `Animated.timing` 创建动画 2. 通过 `TouchableOpacity` 捕获击事件 3. `stopAnimation()` 方法中断动画执行 4. `start()` 回调参数检测自然结束状态 5. `navigation.replace()` 实现页面切换 6. 使用 `useState` 管理中断状态 #### 原生启动画面优化(引用[2][3]) 在 Flutter 中可优化原生启动画面: 1. 在 `AndroidManifest.xml` 配置: ```xml <meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" /> ``` 2. 在 Dart 中移除原生启动画面: ```dart void main() { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); Future.delayed(Duration(milliseconds: 100), () { FlutterSplashScreen.preserve(widget: MyApp()); }); } ``` #### 性能优化建议(引用[1][4]) 1. **轻量化资源**:使用矢量图替代位图 2. **预加载策略**:在动画期间后台加载关键资源 3. **内存管理**:使用 `dispose()` 释放动画资源 4. **代码分割**:将主界面代码拆分为独立模块 5. **测试驱动**:使用引用[4]的测试方法验证中断逻辑 ```dart // 测试用例示例(引用[4]方法) void testSplashInterruption() { testWidgets('中断应跳转主页', (tester) async { await tester.pumpWidget(MaterialApp(home: SplashScreen())); await tester.tap(find.byType(GestureDetector)); await tester.pumpAndSettle(); expect(find.byType(HomeScreen), findsOneWidget); }); } ``` #### 安全注意事项(引用[5]) 1. 验证跳转目标页面安全性 2. 避免在中断回调中执行未验证的操作 3. 对用户输入进行无害化处理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值