Stateless 和 Stateful widget,可以同时使用吗?

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

Stateless and Stateful widget, can i use both?

问题

可以将这两个小部件组合吗?
现在我正在学习Flutter,如果我想要保持我的AppBar固定或其他什么。我可以同时使用这两个小部件吗?如果可以,我应该在两者上都使用build()小部件吗?

我还没有尝试过,因为我不太明白何时应该使用build()函数。但我看到Stateless是当屏幕状态没有更改时使用,而Stateful是当有更改时使用。

英文:

Is it possible to combine the two widgets?
Now I'm studying flutter and if I want to keep my AppBar fixed or something else. Can I have both widgets? If it's possible, should I use the build widget on both?

I haven't tried it yet because I don't understand when I should use the build() function. But I saw that Stateless is when there are no changes in the state of the screen and Stateful when there are changes.

答案1

得分: 2

是的
您可以将它们结合使用
通过将Stateless作为Stateful的子元素或Stateless作为父元素

例如:Scaffold小部件是一个Stateful,可以“接收”很多Stateless

SafeArea小部件是一个Stateless,并且您可以将Stateful小部件设置为其子元素。

要保持您的AppBar固定,只需像这样做:

Scaffold(
  appBar: AppBar(
    title: const Text('AppBar'),
  ), //AppBar
)
英文:

Yes
You can combine both
By Using Stateless as Child of a Stateful or stateless as Parent

eg: The Scaffold Widget is a Stateful that can 'receive' lots of Stateles

The SafeArea widget is a Stateless,and you can set a Stateful widget as child.

Too keep your AppBar fixed just need something like that :

Scaffold(

      appBar: AppBar(

        title: const Text('AppBar'),

      ), //AppBar
)

答案2

得分: 1

你可以结合使用有状态(Stateful)和无状态(Stateless)小部件。这有助于更好地控制build()的成本。以下是一个示例:你有一个屏幕,显示了一些物品和每个物品的数量。在物品的尾部,有一个按钮 增加 用于增加物品的数量。

以下是解决方案:

无状态小部件(屏幕显示物品列表)

import 'package:demoapp/have_state.dart';
import 'package:flutter/material.dart';

class NoState extends StatelessWidget {
  const NoState({Key? key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List.generate(
            5,
            (index) => HaveState(title: 'item $index'),
          ),
        ),
      ),
    );
  }
}

有状态小部件(物品自身维护状态)

import 'package:flutter/material.dart';

class HaveState extends StatefulWidget {
  const HaveState({
    Key? key,
    required this.title,
  });

  final String title;

  @override
  _State createState() => _State();
}

class _State extends State<HaveState> {
  int state = 0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(24),
      child: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('${widget.title} 数量: ${state.toString()}'),
            TextButton(
              onPressed: () => setState(() {
                state += 1;
              }),
              child: const Text('增加'),
            )
          ],
        ),
      ),
    );
  }
}

当你点击增加按钮时,只有HaveState项目会重新构建,而不是整个NoState小部件。这有助于更好地控制你的build()方法。

英文:

You can combine both of Stateful and Stateless widget. This is better to control build() costs. This is a example: You have a screen with a list of items and quantity for each item. At the trailing of item, you have a button add more to increase quantity of item by one.
This is solution for this:

Stateless widget (screen shows list of items)

import &#39;package:demoapp/have_state.dart&#39;;
import &#39;package:flutter/material.dart&#39;;

class NoState extends StatelessWidget {
  const NoState({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List.generate(
            5,
            (index) =&gt; HaveState(title: &#39;item $index&#39;),
          ),
        ),
      ),
    );
  }
}

Stateful widget (item hold state itself)

import &#39;package:flutter/material.dart&#39;;

class HaveState extends StatefulWidget {
  const HaveState({
    super.key,
    required this.title,
  });

  final String title;

  @override
  State&lt;StatefulWidget&gt; createState() =&gt; _State();
}

class _State extends State&lt;HaveState&gt; {
  int state = 0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(24),
      child: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(&#39;${widget.title} quantity: ${state.toString()}&#39;),
            TextButton(
              onPressed: () =&gt; setState(() {
                state += 1;
              }),
              child: const Text(&#39;add more&#39;),
            )
          ],
        ),
      ),
    );
  }
}

When you click add more button, only HaveState item will be rebuit, not entire NoState widget. It takes you more controls your build() method.

huangapple
  • 本文由 发表于 2023年7月7日 01:06:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76631100.html
匿名

发表评论

匿名网友

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

确定