Flutter开发常见问题,解决小技巧
Posted 怀君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter开发常见问题,解决小技巧相关的知识,希望对你有一定的参考价值。
1.android Studio 4.0 以上打包编译报错;
Execution failed for task ':app:lintVitalRelease'.
> Could not resolve all artifacts for configuration ':app:debugRuntimeClasspath'.
> Failed to transform libs.jar to match attributes artifactType=processed-jar, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime.
> Execution failed for JetifyTransform: E:\\FlutterSpace\\xxxx\\build\\app\\intermediates\\flutter\\debug\\libs.jar.
> Transform's input file does not exist: E:\\FlutterSpace\\xxxx\\build\\app\\intermediates\\flutter\\debug\\libs.jar. (See https://issuetracker.google.com/
issues/158753935)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
1.在子build.gradle添加以下代码:
android
lintOptions checkReleaseBuilds false
解决方案:原文地址:https://my.oschina.net/u/4364921/blog/4725237
2.Exception: Gradle build failed to produce an .apk file. It’s likely that this file was generated under /build, but the tool couldn’t find it.
打包时找不到渠道包名导致;
1.通过VSCode找到项目当中有一 launch.json 文件
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
"name": "YOUR_PROJECT_NAME",//你项目的名称
"program": "lib/main.dart",
"request": "launch",
"type": "dart",
"args": [
"--flavor",
"ADD_YOUR_FLAVOR_NAME_HERE" //配置你的渠道包名
]
]
2.通过Andorid Studio 找到子build.gradle文件添加渠道配置;
android
compileOptions
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
android.applicationVariants.all
variant ->
variant.outputs.all
//在这里修改apk文件名
outputFileName = "-v$variant.versionName-$variant.productFlavors[0].name-release.apk"
productFlavors
pgyer // 蒲公英
huawei // 华为商店
baidu // 百度手机助手
yinyongbao // 应用宝
xiaomi // 小米
oppo // OPPO
vivo // VIVO
s360 // 360
lenovo // 联想
aliuc // 阿里UC
// 批量渠道包值替换(有些第三方库中需要用到渠道名)
productFlavors.all flavor ->
// 友盟推送渠道包, UMENG_CHANNEL_VALUE 是根据你AndroidManifest.xml来配置的,请看下面。
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
//解决打包异常的问题
lintOptions checkReleaseBuilds false
3._positions.isNotEmpty, ‘ScrollController not attached to any scroll views.’
具体报错问题;
The following assertion was thrown building Swiper(state: _SwiperState#e86c5):
ScrollController not attached to any scroll views.
'package:flutter/src/widgets/scroll_controller.dart':
Failed assertion: line 108 pos 12: '_positions.isNotEmpty'
解决方案:https://blog.csdn.net/youtiankeng/article/details/107419322
4.Android studio Flutter 开发快捷键
https://flutter.cn/docs/development/tools/android-studio
5.Flutter WebView js交互
html 测试代码块
<html>
<head>
<title>Js调用Flutter</title>
<script>
function Close()
AppWndClose.postMessage("JS调用了Flutter");
</script>
</head>
<body>
<br>
<input type="button" value="关闭" onclick="Close()"/>
</body>
</html>
flutter 测试代码块
WebView(
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: 'AppWndClose',
onMessageReceived: (JavascriptMessage message)
showToast(message.message);
)
].toSet(),
)
我们要注意的是代码里面使用的都是AppWndClose ;这个是我们要注意到的;
参考地址:https://zhuanlan.zhihu.com/p/124797055
6.Flutter WebView跳转dart界面
- 通过js的方法进行调用;
class CustomWebViewPage extends StatefulWidget
final String url;
CustomWebViewPage(
Key key,
@required this.url,
);
@override
createState() => _PageState();
class _PageState extends State<CustomWebViewPage> with WidgetsBindingObserver
_PageState();
FlutterWebviewPlugin _webViewPlugin = FlutterWebviewPlugin();
double lineProgress = 0.0;
bool loadError = false;
HomeModel homeModel;
initState()
super.initState();
_webViewPlugin.onProgressChanged.listen((progress)
print(progress);
setState(()
lineProgress = progress;
);
);
_webViewPlugin.onHttpError.listen((progress)
setState(()
loadError = true;
);
);
_webViewPlugin.onStateChanged.listen((event)
if (event.type == WebViewState.finishLoad)
setState(() );
);
WidgetsBinding.instance.addObserver(this);
EventBus.getDefault().register(this, (data)
if (data is PublishPostsEvent || data == 'tabRankList')
_webViewPlugin.evalJavascript("RefreshMissionList()").then((res)
print("evaluateJavascript-res: $res");
);
);
_wlakPermission(false);
@override
void didChangeAppLifecycleState(AppLifecycleState state)
print("-didChangeAppLifecycleState-" + state.toString());
switch (state)
case AppLifecycleState.inactive: // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
break;
case AppLifecycleState.resumed: //从后台切换前台,界面可见
_webViewPlugin.evalJavascript("AppOnShow()").then((res)
print("evaluateJavascript-res: $res");
);
break;
case AppLifecycleState.paused: // 界面不可见,后台
_webViewPlugin.evalJavascript("AppOnHide()").then((res)
print("evaluateJavascript-res: $res");
);
;
break;
case AppLifecycleState.detached: // APP结束时调用
break;
@override
Widget build(BuildContext context)
homeModel = Provider.of<HomeModel>(context);
return WebviewScaffold(
url: widget.url,
mediaPlaybackRequiresUserGesture: false,
withZoom: false,
withJavascript: true,
clearCookies: true,
hidden: true,
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: "AppWndClose",
onMessageReceived: (JavascriptMessage message)
NavigatorUtils.goBack(context);
),
_postThread(),
_partInTopic(),
].toSet(),
initialChild: Container(
child: Stack(
children: [
Center(
child: StateLayout(
type: loadError ? StateType.network : StateType.loading,
)),
_setTitle(context),
],
),
));
_postThread()
return JavascriptChannel(
name: "eventPostThread",
onMessageReceived: (JavascriptMessage message)
_webViewPlugin.hide();
print("参数: $message.message");
NavigatorUtils.push(context, ProfileRouter.publishPosts)
.then((value)
_webViewPlugin.show();
_webViewPlugin.evalJavascript("RefreshMissionList()").then((res)
print("evaluateJavascript-res: $res");
);
);
);
_partInTopic()
return JavascriptChannel(
name: "eventTaskPartinTopic",
onMessageReceived: (JavascriptMessage message)
// 因为flutter_webview_plugin 是浮在flutterUI上的一层视图,它不在widget树中,跳转到dart页面时,需要隐藏掉web页面
_webViewPlugin.hide();
NavigatorUtils.push(context, TopicRouter.topic).then((value)
//再跳回来时再显示web页面
_webViewPlugin.show();
_webViewPlugin.evalJavascript("RefreshMissionList()").then((res)
//同时调用web端接口进行刷新操作;
);
);
);
_setTitle(context)
return Positioned(
left: 15,
top: MediaQuery.of(context).padding.top + 5,
child: BackButton(
onPressed: ()
NavigatorUtils.goBack(context);
,
),
);
_progressBar(double progress, BuildContext context)
return Offstage(
offstage: progress == 1.0,
child: Container(
child: LinearProgressIndicator(
backgroundColor: Colors.blueAccent.withOpacity(0),
value: progress == 1.0 ? 0 : progress,
valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightBlue),
),
height: 2,
));
@override
void dispose()
_webViewPlugin.dispose();
WidgetsBinding.instance.removeObserver(this);
EventBus.getDefault().unregister(this);
super.dispose();
- 通过加载URL的形式进行监听响应跳转;
///省略上面代码;
@override
void initState()
super.initState();
flutterWebviewPlugin.onUrlChanged.listen((loadUrl)
//WebviewScaffold 加载的url变化时触发此方法
// print('===>>当前 url:$loadUrl');
// h5 点退出按钮,关闭webView
if (loadUrl.endsWith('/backapp'))
flutterWebviewPlugin.close();
pop();
// 跳转到dart页面
else if (loadUrl.endsWith('/policy'))
// 因为flutter_webview_plugin 是浮在flutterUI上的一层视图,它不在widget树中,跳转到dart页面时,需要隐藏掉web页面,再跳回来时再显示web页面
flutterWebviewPlugin.hide();
routePush(ClassRoomPage()).then((value)
flutterWebviewPlugin.show();
flutterWebviewPlugin.reloadUrl(widget.url);
);
//跳转到dart页面时,也可以关闭掉web页面,再跳回来时再创建一个web页面
// flutterWebviewPlugin.close();
// routePush(ClassRoomPage()).then((value)
// flutterWebviewPlugin.launch(widget.url,
// rect: new Rect.fromLTWH( // 设置web页面的尺寸
// 0.0,
// _navBarHeight,
// MediaQuery.of(_context).size.width,
// MediaQuery.of(_context).size.height-_navBarHeight,
// ),
// );
// );
);
//加载错误时监听
// flutterWebviewPlugin.onHttpError.listen((error)
// print('加载错误:$error.code $error.url');
// );
//加载状态变化监听
// flutterWebviewPlugin.onStateChanged.listen((state)
// print('状态监听:$state.type.toString()');
// );
参考文章:flutter_webview_plugin 与dart页面跳转使用
7. cmdline-tools component is missing Run path/to/sdkmanager --install "cmdline-tools;latest"
参考文章:https://blog.csdn.net/weixin_41824429/article/details/118942087
8.android studio安装和flutter project创建卡住问题解决
参考文章:https://blog.csdn.net/lucynie/article/details/106928231
9. Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
参考文章:https://www.jianshu.com/p/4feeec038482
10.Flutter Getx 结合 TabView
参考文章:https://stackoverflow.com/questions/63924491/how-to-build-a-tabview-using-flutter-getx
11. Flutter 项目window应用鼠标无法滚动
const Set<PointerDeviceKind> _kTouchLikeDeviceTypes = <PointerDeviceKind>
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
PointerDeviceKind.unknown
;
MaterialApp(
...
scrollBehavior: const MaterialScrollBehavior().copyWith(
scrollbars: true,
dragDevices: _kTouchLikeDeviceTypes
),
...
);
//如果你使用的是Getx框架同上,有相同的属性;scrollBehavior
参考文章:https://www.cnblogs.com/yangyxd/p/15080537.html
12. Flutter 项目window应用运行异常
问题:
CMake Error at CMakeLists.txt:2 (project):
Generator
Visual Studio 16 2019
could not find any instance of Visual Studio.
具体解决方法:
https://stackoverflow.com/questions/69944913/cmake-error-while-running-flutter-desktop-application/69951396#69951396 。 Flutter 2.9 版支持 VS 2022,而您使用的 2.8.1 版仅支持 VS 2019。只需安装 2019 并试一试。
如果你想在 2.8.1 版本中使用 VS 2022,这里是解决方法。 stackoverflow.com/a/69951396/6566310 我想这个解决方法是值得的。
感谢您提供这两种解决方案。但我确实选择了第一个,现在它正在工作。
解决方案:https://www.likecs.com/ask-5954170.html
12. Flutter创建本地 Library 工具类
解决方案:https://www.jianshu.com/p/70f874765965
以上是关于Flutter开发常见问题,解决小技巧的主要内容,如果未能解决你的问题,请参考以下文章
iOS开发小技巧--学会包装控件(有些view的位置由于代码或系统原因,位置或者尺寸不容易修改或者容易受外界影响)