英文:
Calculate time between displayed item in ListView.builder - [SOLVED]
问题
我想追踪用户并了解他的兴趣,为了实现这个目标,我想知道他在每篇帖子上花了多少时间,根据这些信息,我将发送这些数据到AI模型进行分析,并重新生成符合用户兴趣的帖子。
以下是我的代码
Expanded(
child: BlocBuilder<EveryNewCubit, EveryNewState>(
builder: (context, state) {
if (state is EveryNewSuccess) {
return ListView.builder(
itemCount: state.news.length,
itemBuilder: (context, index) {
return VisibilityDetector(
key: Key(index.toString()),
onVisibilityChanged: (info) {
print('${state.news[index].title}'); // 我想在这里打印每个项目的时间
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(
0, 3), // 改变阴影的位置
),
],
),
child: ExploreNewsItem(),
),
),
);
},
);
} else if (state is EveryNewFailure) {
print(state.failure.toString());
return CustomErrorWidget(errMessage: state.failure);
} else {
return const CustomLoadingIndicator();
}
},
),
)
如果您知道在这个应用程序中使用更好的解决方案或技巧,我将不胜感激。谢谢。
我实际上使用了visibility_detector
,但我无法为每个帖子计算时间。
英文:
I want to track user and know his interests and to achieve that i want to know how much time does he spend in each post, Based on this information i will send this data to AI model to analyze it and regenerate posts with user interests.
here is my code
Expanded(
child: BlocBuilder<EveryNewCubit, EveryNewState>(
builder: (context, state) {
if (state is EveryNewSuccess) {
return ListView.builder(
itemCount: state.news.length,
itemBuilder: (context, index) {
return VisibilityDetector(
key: Key(index.toString()),
onVisibilityChanged: (info) {
print('${state.news[index].title}'); // i want to print time here for each item
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(
0, 3), // changes position of shadow
),
],
),
child: ExploreNewsItem(),
),
),
);
});
} else if (state is EveryNewFailure) {
print(state.failure.toString());
return CustomErrorWidget(errMessage: state.failure);
} else {
return const CustomLoadingIndicator();
}
},
),
)
if you know better solution or technique to use in this app i will be grateful
thanks.
I actually used visibility_detector but i can not calculate time for each post.
答案1
得分: 1
以下是您要翻译的内容:
最后我找到了解决方案:
首先,我使用VisibilityDetector包装ExploreNewItem的内容,而不是将其包装在ListView中。
其次,我在项目自身中声明了定时器,这让我能够计算每个项目的时间,而不是为所有项目使用一个定时器。
像这样:
class ExploreNewsItem extends StatefulWidget {
const ExploreNewsItem({
super.key,
required this.imageUrl,
required this.category,
required this.title,
required this.source,
required this.date,
required this.content,
});
final String imageUrl;
final String category;
final String title;
final String source;
final String date;
final String content;
@override
State<ExploreNewsItem> createState() => _ExploreNewsItemState();
}
class _ExploreNewsItemState extends State<ExploreNewsItem> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
final stopwatch = Stopwatch();
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ItemDetailScreen(
imageUrl: widget.imageUrl,
source: widget.source,
title: widget.title,
date: widget.date,
category: widget.category,
content: (widget.content),
))),
child: VisibilityDetector(
key: Key(widget.title.toString()),
onVisibilityChanged: (info) {
if (info.visibleFraction == 1 && !stopwatch.isRunning) {
stopwatch.start();
log(widget.title, name: 'start');
print(widget.title);
}
if (info.visibleFraction < 0.5 && stopwatch.isRunning) {
log(widget.title, name: 'reset');
log("${stopwatch.elapsed}", name: "spent time");
stopwatch.stop();
}
},
child: Container(),
),
);
}
}
而不是这样:
ListView.builder(
itemCount: state.news.length,
itemBuilder: (context, index) {
return VisibilityDetector(
key: Key(index.toString()),
onVisibilityChanged: (info) {
print('${state.news[index].title}'); // 我想在这里为每个项目打印时间
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(
0, 3), // 改变阴影的位置
),
],
),
child: ExploreNewsItem(),
),
),
);
},
),
英文:
Finally i found the solution:
Firstly i wrap content of ExploreNewItem with VisibilityDetector instead of wrapping it in ListView
Secondly i declare the timer in item itself this let me calculate each item time instead of one timer for all items.
Like this:
class ExploreNewsItem extends StatefulWidget {
const ExploreNewsItem({
super.key,
required this.imageUrl,
required this.category,
required this.title,
required this.source,
required this.date,
required this.content,
});
final String imageUrl;
final String category;
final String title;
final String source;
final String date;
final String content;
@override
State<ExploreNewsItem> createState() => _ExploreNewsItemState();
}
class _ExploreNewsItemState extends State<ExploreNewsItem> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
final stopwatch = Stopwatch();
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ItemDetailScreen(
imageUrl: widget.imageUrl,
source: widget.source,
title: widget.title,
date: widget.date,
category: widget.category,
content: (widget.content),
))),
child: VisibilityDetector(
key: Key(widget.title.toString()),
onVisibilityChanged: (info) {
if (info.visibleFraction == 1 && !stopwatch.isRunning) {
stopwatch.start();
log(widget.title, name: 'start');
print(widget.title);
}
if (info.visibleFraction < 0.5 && stopwatch.isRunning) {
log(widget.title, name: 'reset');
log("${stopwatch.elapsed}", name: "spent time");
stopwatch.stop();
}
},
child: Container(),),),},},
instead of this:
ListView.builder(
itemCount: state.news.length,
itemBuilder: (context, index) {
return VisibilityDetector(
key: Key(index.toString()),
onVisibilityChanged: (info) {
print('${state.news[index].title}'); // i want to print time here for each item
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(
0, 3), // changes position of shadow
),
],
),
child: ExploreNewsItem(),
),
),
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论