在ListView.builder中计算显示项之间的时间 – [已解决]

huangapple go评论68阅读模式
英文:

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&lt;EveryNewCubit, EveryNewState&gt;(
            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(&#39;${state.news[index].title}&#39;);   // 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&lt;ExploreNewsItem&gt; createState() =&gt; _ExploreNewsItemState();
}

class _ExploreNewsItemState extends State&lt;ExploreNewsItem&gt; {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  final stopwatch = Stopwatch();
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () =&gt; Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) =&gt; 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 &amp;&amp; !stopwatch.isRunning) {
            stopwatch.start();
            log(widget.title, name: &#39;start&#39;);
            print(widget.title);
          }
          if (info.visibleFraction &lt; 0.5 &amp;&amp; stopwatch.isRunning) {
            log(widget.title, name: &#39;reset&#39;);
            log(&quot;${stopwatch.elapsed}&quot;, name: &quot;spent time&quot;);
            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(&#39;${state.news[index].title}&#39;);   // 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(),
                          ),
                        ),
                      );

huangapple
  • 本文由 发表于 2023年6月13日 12:54:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461784.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定