发布 apk 时,Flutter 无法在真实设备中呈现 UI
Flutter not rendering UI in real device on release apk
我一直在为我的应用程序编写 ui,在调试模式下 building 时没问题。但是当我 uilt 发布 apk 时,UI 被弄脏了,文本也没有显示。小部件未按预期呈现,并且它们的大小未正确呈现。我在不同的手机上检查过,但结果是一样的。是我的代码有问题还是flutter的内部bug?有人以前看过这个吗?
It's in release apk
It's in debug apk
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:rx_shared_preferences/rx_shared_preferences.dart';
@override
Widget build(BuildContext context) {
return ListView(
children: [
const SizedBox(height: 12.0),
StreamBuilder(
stream: rxPrefs.getStringStream('firstName'),
builder: (context, snapshot) => Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
child: Text(
'${AppLocalizations.of(context)!.hello} ${snapshot.data ?? ''}',
style: AppTextStyles.headline,
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 12.h),
child: GestureDetector(
onTap: () => context.push(SearchPage.route),
child: Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
children: [
const Icon(Icons.search),
const SizedBox(width: 12.0),
Text(
AppLocalizations.of(context)!.search,
style: AppTextStyles.title0,
),
],
),
),
),
),
),
FutureBuilder(
future: ApiService.getInstance().getPromos(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Promo> promos = snapshot.data as List<Promo>;
return Padding(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
child: CarouselSlider.builder(
options: CarouselOptions(
enlargeCenterPage: true,
enableInfiniteScroll: true,
height: widget.mediaQuery.size.height * .25,
viewportFraction: 1,
),
itemCount: promos.length,
itemBuilder: (BuildContext context, int index, int realIndex) => Container(
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0)),
clipBehavior: Clip.hardEdge,
height: widget.mediaQuery.size.height * .25,
width: widget.mediaQuery.size.width,
child: CachedNetworkImage(
imageUrl: promos[index].image,
fit: BoxFit.fitWidth,
),
),
),
);
}
return Container(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0)),
clipBehavior: Clip.hardEdge,
height: widget.mediaQuery.size.height * .25,
width: widget.mediaQuery.size.width,
// alignment: Alignment.center,
child: const Card(child: Center(child: CircularProgressIndicator())),
);
}),
Padding(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.categories,
style: AppTextStyles.title0,
),
GestureDetector(
onTap: () => context.push(CategoriesPage.route),
child: Text(
AppLocalizations.of(context)!.seeAll,
style: AppTextStyles.title0.copyWith(color: AppColors.grey),
),
),
],
),
),
Consumer<CategoryBloc>(
builder: (context, bloc, child) => SizedBox(
height: widget.mediaQuery.size.height * .2,
child: ListView.builder(
padding: EdgeInsets.only(left: 18.w),
itemCount: bloc.categories.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => CategoryCard(category: bloc.categories[index]),
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.popular,
style: AppTextStyles.title0,
),
GestureDetector(
onTap: () => context.push(ProductsPage.route),
child: Text(
AppLocalizations.of(context)!.seeAll,
style: AppTextStyles.title0.copyWith(color: AppColors.grey),
),
),
],
),
),
Consumer<ProductBloc>(
builder: (context, bloc, child) =>
Column(children: bloc.products.take(4).map((e) => ProductWidget(product: e)).toList())),
const SizedBox(height: 16.0),
],
);
}```
我找到了解决方案,由于 class-based 个小部件的 const
个构造函数,小部件没有呈现。要解决此问题,有两种方法,首先是在小部件构造函数和使用之前删除 const
,其次是删除 screen_util
或另一个动态生成值的包。
这是我找到原始解决方案 https://github.com/OpenFlutter/flutter_screenutil/issues/341, https://github.com/OpenFlutter/flutter_screenutil/issues/350.
的 link
我一直在为我的应用程序编写 ui,在调试模式下 building 时没问题。但是当我 uilt 发布 apk 时,UI 被弄脏了,文本也没有显示。小部件未按预期呈现,并且它们的大小未正确呈现。我在不同的手机上检查过,但结果是一样的。是我的代码有问题还是flutter的内部bug?有人以前看过这个吗?
It's in release apk
It's in debug apk
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:rx_shared_preferences/rx_shared_preferences.dart';
@override
Widget build(BuildContext context) {
return ListView(
children: [
const SizedBox(height: 12.0),
StreamBuilder(
stream: rxPrefs.getStringStream('firstName'),
builder: (context, snapshot) => Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
child: Text(
'${AppLocalizations.of(context)!.hello} ${snapshot.data ?? ''}',
style: AppTextStyles.headline,
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 12.h),
child: GestureDetector(
onTap: () => context.push(SearchPage.route),
child: Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
children: [
const Icon(Icons.search),
const SizedBox(width: 12.0),
Text(
AppLocalizations.of(context)!.search,
style: AppTextStyles.title0,
),
],
),
),
),
),
),
FutureBuilder(
future: ApiService.getInstance().getPromos(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Promo> promos = snapshot.data as List<Promo>;
return Padding(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
child: CarouselSlider.builder(
options: CarouselOptions(
enlargeCenterPage: true,
enableInfiniteScroll: true,
height: widget.mediaQuery.size.height * .25,
viewportFraction: 1,
),
itemCount: promos.length,
itemBuilder: (BuildContext context, int index, int realIndex) => Container(
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0)),
clipBehavior: Clip.hardEdge,
height: widget.mediaQuery.size.height * .25,
width: widget.mediaQuery.size.width,
child: CachedNetworkImage(
imageUrl: promos[index].image,
fit: BoxFit.fitWidth,
),
),
),
);
}
return Container(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10.0)),
clipBehavior: Clip.hardEdge,
height: widget.mediaQuery.size.height * .25,
width: widget.mediaQuery.size.width,
// alignment: Alignment.center,
child: const Card(child: Center(child: CircularProgressIndicator())),
);
}),
Padding(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.categories,
style: AppTextStyles.title0,
),
GestureDetector(
onTap: () => context.push(CategoriesPage.route),
child: Text(
AppLocalizations.of(context)!.seeAll,
style: AppTextStyles.title0.copyWith(color: AppColors.grey),
),
),
],
),
),
Consumer<CategoryBloc>(
builder: (context, bloc, child) => SizedBox(
height: widget.mediaQuery.size.height * .2,
child: ListView.builder(
padding: EdgeInsets.only(left: 18.w),
itemCount: bloc.categories.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => CategoryCard(category: bloc.categories[index]),
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 12.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.popular,
style: AppTextStyles.title0,
),
GestureDetector(
onTap: () => context.push(ProductsPage.route),
child: Text(
AppLocalizations.of(context)!.seeAll,
style: AppTextStyles.title0.copyWith(color: AppColors.grey),
),
),
],
),
),
Consumer<ProductBloc>(
builder: (context, bloc, child) =>
Column(children: bloc.products.take(4).map((e) => ProductWidget(product: e)).toList())),
const SizedBox(height: 16.0),
],
);
}```
我找到了解决方案,由于 class-based 个小部件的 const
个构造函数,小部件没有呈现。要解决此问题,有两种方法,首先是在小部件构造函数和使用之前删除 const
,其次是删除 screen_util
或另一个动态生成值的包。
这是我找到原始解决方案 https://github.com/OpenFlutter/flutter_screenutil/issues/341, https://github.com/OpenFlutter/flutter_screenutil/issues/350.