我试过CachedNetworkImage
,但当我在CarouselSlider
中切换页面时,它总是重新加载。
验证码:
// HeroBannerModel
class HeroBannerWidget extends StatefulWidget {
final List<HeroBannerModel> heroBanner;
const HeroBannerWidget({
Key? key,
required this.heroBanner,
}) : super(key: key);
@override
_HeroBannerWidgetState createState() => _HeroBannerWidgetState();
}
class _HeroBannerWidgetState extends State<HeroBannerWidget> {
int _current = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_preCacheImages();
}
void _preCacheImages() {
final _heroBanner = widget.heroBanner;
if (_heroBanner.isEmpty) return;
for (final item in _heroBanner) {
precacheImage(NetworkImage(item.file.url.original), context);
}
}
@override
Widget build(BuildContext context) {
final _heroBanner = widget.heroBanner;
if (_heroBanner.isEmpty) return const SizedBox.shrink();
return Stack(
alignment: Alignment.center,
children: [
CarouselSlider(
items: _heroBanner.map((item) {
return GestureDetector(
onTap: () async {
final _link = item.link;
if (_link == null) return;
BaseUtils.launchURL(_link);
},
child: BaseImageView(
url: item.file.url.original,
width: size.width,
fit: BoxFit.cover,
),
);
}).toList(),
options: CarouselOptions(
height: getSize(453),
initialPage: 0,
viewportFraction: 1,
enableInfiniteScroll: false,
onPageChanged: (index, reason) {
setState(() {
_current = index;
});
},
),
),
Positioned(
bottom: 4,
child: AnimatedSmoothIndicator(
activeIndex: _current,
count: _heroBanner.length,
effect: ExpandingDotsEffect(
dotWidth: getSize(8.0),
dotHeight: getSize(8.0),
spacing: getSize(8.0),
expansionFactor: getSize(12.0),
dotColor: AppColor.greyV07,
activeDotColor: AppColor.greyV09,
),
),
),
],
);
}
}
// BaseImageView
class BaseImageView extends StatelessWidget {
///[url] is required parameter for fetching network image
final String? url;
///[imagePath] is required parameter for showing png,jpg,etc image
final String? imagePath;
///[svgPath] is required parameter for showing svg image
final String? svgPath;
///[file] is required parameter for fetching image file
final File? file;
final double? height;
final double? width;
final Color? color;
final BoxFit? fit;
final String placeHolder;
final Alignment? alignment;
final VoidCallback? onTap;
final EdgeInsetsGeometry? margin;
final BorderRadius? radius;
final BoxBorder? border;
///a [BaseImageView] it can be used for showing any type of images
/// it will shows the placeholder image if image is not found on network image
const BaseImageView({
super.key,
this.url,
this.imagePath,
this.svgPath,
this.file,
this.height,
this.width,
this.color,
this.fit,
this.alignment,
this.onTap,
this.radius,
this.margin,
this.border,
this.placeHolder = 'assets/images/img_not_found.png',
});
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment!,
child: _buildWidget(),
)
: _buildWidget();
}
Widget _buildWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: InkWell(
onTap: onTap,
child: _buildCircleImage(),
),
);
}
///build the image with border radius
dynamic _buildCircleImage() {
if (radius != null) {
return ClipRRect(
borderRadius: radius,
child: _buildImageWithBorder(),
);
} else {
return _buildImageWithBorder();
}
}
///build the image with border and border radius style
Widget _buildImageWithBorder() {
if (border != null) {
return Container(
decoration: BoxDecoration(
border: border,
borderRadius: radius,
),
child: _buildImageView(),
);
} else {
return _buildImageView();
}
}
Widget _buildImageView() {
if (svgPath != null && svgPath!.isNotEmpty) {
return SizedBox(
height: height,
width: width,
child: SvgPicture.asset(
svgPath!,
height: height,
width: width,
fit: fit ?? BoxFit.contain,
color: color,
),
);
} else if (file != null && file!.path.isNotEmpty) {
return Image.file(
file!,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
} else if (url != null && url!.isNotEmpty) {
return CachedNetworkImage(
height: height,
width: width,
fit: fit,
imageUrl: url!,
color: color,
cacheManager: BaseCustomCacheManager(),
placeholder: (context, url) => SizedBox(
height: 30,
width: 30,
child: LinearProgressIndicator(
color: Colors.grey.shade200,
backgroundColor: Colors.grey.shade100,
),
),
errorWidget: (context, url, error) => Image.asset(
placeHolder,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
),
);
} else if (imagePath != null && imagePath!.isNotEmpty) {
return Image.asset(
imagePath!,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
}
return Image.asset(
placeHolder,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
// return const SizedBox();
}
}
// BaseCustomCacheManager
class BaseCustomCacheManager extends CacheManager with ImageCacheManager {
static const String key = "customCache";
static BaseCustomCacheManager? _instance;
BaseCustomCacheManager._()
: super(
Config(
key,
stalePeriod: const Duration(days: 30),
maxNrOfCacheObjects: 1000,
repo: JsonCacheInfoRepository(databaseName: key),
fileSystem: IOFileSystem(key),
fileService: HttpFileService(),
),
);
factory BaseCustomCacheManager() {
return _instance ??= BaseCustomCacheManager._();
}
}
// IOFileSystem
class IOFileSystem implements c.FileSystem {
final Future<Directory> _fileDir;
IOFileSystem(String key) : _fileDir = createDirectory(key);
static Future<Directory> createDirectory(String key) async {
var baseDir = await getTemporaryDirectory();
var path = p.join(baseDir.path, key);
var fs = const LocalFileSystem();
var directory = fs.directory((path));
await directory.create(recursive: true);
return directory;
}
@override
Future<File> createFile(String name) async {
return (await _fileDir).childFile(name);
}
}
我想它显示图像,没有加载像一个gif文件。请帮助我。我尝试了许多不同的方法来解决这个问题,但我不能
1条答案
按热度按时间hkmswyz61#
首先把这个换掉
与
而您的主
build
方法删除以下代码
你可以设定条件