opt: image radius

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-01-15 00:30:03 +08:00
parent 229901de96
commit 230325d171
2 changed files with 110 additions and 61 deletions

View File

@@ -47,6 +47,41 @@ Widget imageview(
} else if (picArr.length == 2) { } else if (picArr.length == 2) {
imageWidth = imageHeight = 2 * imageWidth; imageWidth = imageHeight = 2 * imageWidth;
} }
BorderRadius borderRadius(index) {
if (picArr.length == 1) {
return BorderRadius.circular(12);
}
final int row = picArr.length == 4 ? 2 : 3;
return BorderRadius.only(
topLeft: Radius.circular(
(index - row >= 0 ||
((index - 1) >= 0 && (index - 1) % row < index % row))
? 0
: 12,
),
topRight: Radius.circular(
(index - row >= 0 ||
((index + 1) < picArr.length &&
(index + 1) % row > index % row))
? 0
: 12,
),
bottomLeft: Radius.circular(
(index + row < picArr.length ||
((index - 1) >= 0 && (index - 1) % row < index % row))
? 0
: 12,
),
bottomRight: Radius.circular(
(index + row < picArr.length ||
((index + 1) < picArr.length &&
(index + 1) % row > index % row))
? 0
: 12,
),
);
}
return NineGridView( return NineGridView(
type: NineGridType.weiBo, type: NineGridType.weiBo,
margin: const EdgeInsets.only(top: 6), margin: const EdgeInsets.only(top: 6),
@@ -75,14 +110,36 @@ Widget imageview(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(12), borderRadius: borderRadius(index),
child: NetworkImgLayer( child: NetworkImgLayer(
radius: 0,
src: picArr[index].url, src: picArr[index].url,
width: imageWidth, width: imageWidth,
height: imageHeight, height: imageHeight,
isLongPic: () => picArr[index].isLongPic, isLongPic: () => picArr[index].isLongPic,
callback: () => callback: () =>
picArr[index].safeWidth <= picArr[index].safeHeight, picArr[index].safeWidth <= picArr[index].safeHeight,
getPlaceHolder: () {
return Container(
width: imageWidth,
height: imageHeight,
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.onInverseSurface
.withOpacity(0.4),
borderRadius: borderRadius(index),
),
child: Center(
child: Image.asset(
'assets/images/loading.png',
width: imageWidth,
height: imageHeight,
cacheWidth: imageWidth.cacheSize(context),
),
),
);
},
), ),
), ),
if (picArr[index].isLongPic) if (picArr[index].isLongPic)

View File

@@ -21,6 +21,7 @@ class NetworkImgLayer extends StatelessWidget {
this.imageBuilder, this.imageBuilder,
this.isLongPic, this.isLongPic,
this.callback, this.callback,
this.getPlaceHolder,
}); });
final String? src; final String? src;
@@ -36,71 +37,61 @@ class NetworkImgLayer extends StatelessWidget {
final ImageWidgetBuilder? imageBuilder; final ImageWidgetBuilder? imageBuilder;
final Function? isLongPic; final Function? isLongPic;
final Function? callback; final Function? callback;
final Function? getPlaceHolder;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double radius = this.radius != null
? this.radius!
: type == 'avatar'
? 50
: type == 'emote'
? 0
: StyleString.imgRadius.x;
return src.isNullOrEmpty.not
? radius != 0
? ClipRRect(
borderRadius: BorderRadius.circular(radius),
child: _buildImage(context),
)
: _buildImage(context)
: getPlaceHolder?.call() ?? placeholder(context);
}
Widget _buildImage(context) {
late final int defaultImgQuality = GlobalData().imgQuality; late final int defaultImgQuality = GlobalData().imgQuality;
bool thumbnail = true; bool thumbnail = true;
int? memCacheWidth, memCacheHeight; int? memCacheWidth, memCacheHeight;
if (callback?.call() == true || width <= height) { if (callback?.call() == true || width <= height) {
memCacheWidth = width.cacheSize(context); memCacheWidth = width.cacheSize(context);
} else { } else {
memCacheHeight = height.cacheSize(context); memCacheHeight = height.cacheSize(context);
} }
Widget res = src != '' && src != null return CachedNetworkImage(
? ClipRRect( imageUrl:
clipBehavior: Clip.antiAlias, '${src?.startsWith('//') == true ? 'https:$src' : src?.http2https}${type != 'emote' && thumbnail ? '@${quality ?? defaultImgQuality}q.webp' : ''}',
borderRadius: BorderRadius.circular( width: width,
radius != null height: ignoreHeight == null || ignoreHeight == false ? height : null,
? radius! memCacheWidth: memCacheWidth,
: type == 'avatar' memCacheHeight: memCacheHeight,
? 50 fit: BoxFit.cover,
: type == 'emote' alignment:
? 0 isLongPic?.call() == true ? Alignment.topCenter : Alignment.center,
: StyleString.imgRadius.x, fadeOutDuration: fadeOutDuration ?? const Duration(milliseconds: 120),
), fadeInDuration: fadeInDuration ?? const Duration(milliseconds: 120),
child: Builder( filterQuality: FilterQuality.low,
builder: (context) => CachedNetworkImage( // errorWidget: (BuildContext context, String url, Object error) =>
imageUrl: // placeholder(context),
'${src?.startsWith('//') == true ? 'https:$src' : src?.http2https}${type != 'emote' && thumbnail ? '@${quality ?? defaultImgQuality}q.webp' : ''}', placeholder: (BuildContext context, String url) =>
width: width, getPlaceHolder?.call() ?? placeholder(context),
height: ignoreHeight == null || ignoreHeight == false imageBuilder: imageBuilder,
? height // errorListener: (value) {
: null, // thumbnail = false;
memCacheWidth: memCacheWidth, // if (context.mounted) {
memCacheHeight: memCacheHeight, // (context as Element).markNeedsBuild();
fit: BoxFit.cover, // }
alignment: isLongPic?.call() == true // },
? Alignment.topCenter );
: Alignment.center,
fadeOutDuration:
fadeOutDuration ?? const Duration(milliseconds: 120),
fadeInDuration:
fadeInDuration ?? const Duration(milliseconds: 120),
filterQuality: FilterQuality.low,
// errorWidget: (BuildContext context, String url, Object error) =>
// placeholder(context),
placeholder: (BuildContext context, String url) =>
placeholder(context),
imageBuilder: imageBuilder,
// errorListener: (value) {
// thumbnail = false;
// if (context.mounted) {
// (context as Element).markNeedsBuild();
// }
// },
),
),
)
: placeholder(context);
if (semanticsLabel != null) {
return Semantics(
label: semanticsLabel,
child: res,
);
}
return res;
} }
Widget placeholder(BuildContext context) { Widget placeholder(BuildContext context) {
@@ -108,14 +99,15 @@ class NetworkImgLayer extends StatelessWidget {
return Container( return Container(
width: width, width: width,
height: height, height: height,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onInverseSurface.withOpacity(0.4), color: Theme.of(context).colorScheme.onInverseSurface.withOpacity(0.4),
borderRadius: BorderRadius.circular(type == 'avatar' borderRadius: BorderRadius.circular(
? 50 type == 'avatar'
: type == 'emote' ? 50
? 0 : type == 'emote'
: StyleString.imgRadius.x), ? 0
: StyleString.imgRadius.x,
),
), ),
child: type == 'bg' child: type == 'bg'
? const SizedBox() ? const SizedBox()