使用Flutter中的Provider来更改UI。

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

Change UI with Provider in Flutter

问题

以下是代码部分的翻译:

我想要创建一个筛选功能。当我选择一个筛选器时,然后我从API中获取数据并更改UI

UI大致如下
[![UI][1]][1]

然后,当我选择筛选器时,数据已更改,但UI未更改

这是我的CustomerPage代码
[CustomerPage代码][2]

class _CustomerPageState extends State<CustomerPage> {
  getCustomer({String? filter}) async {
    EasyLoading.show(status: '加载中...');
    await Provider.of<CustomerProvider>(context, listen: false)
      .getCustomer(filter: filter);
    EasyLoading.dismiss();
  }

  @override
  Widget build(BuildContext context) {
    CustomerProvider customerProvider = Provider.of<CustomerProvider>(context);
    return Consumer<CustomerProvider>(
      builder: (context, customer, _) => Scaffold(
        backgroundColor: Colors.white,
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            showModalBottomSheet(
              shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.vertical(top: Radius.circular(30))),
              context: context,
              builder: (context) {
                return StatefulBuilder(builder: (context, setState) {
                  return SizedBox(
                    height: 200,
                    width: MediaQuery.of(context).size.width,
                    child: Padding(
                      padding: const EdgeInsets.all(20.0),
                      child: Column(
                        children: [
                          const SizedBox(height: 20),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceAround,
                            children: [
                              TextButton(
                                onPressed: () {
                                  getCustomer(filter: 'all');
                                  Navigator.pop(context);
                                },
                                style: TextButton.styleFrom(
                                    backgroundColor: primaryColor),
                                child: Text('全部',
                                    style: whiteTextStyle.copyWith(
                                        fontSize: 13, fontWeight: medium)),
                              ),
                              TextButton(
                                onPressed: () {
                                  getCustomer(filter: 'suspect');
                                  Navigator.pop(context);
                                },
                                style: TextButton.styleFrom(
                                    backgroundColor: primaryColor),
                                child: Text('可疑',
                                    style: whiteTextStyle.copyWith(
                                        fontSize: 13, fontWeight: medium)),
                              ),
                              TextButton(
                                onPressed: () {
                                  getCustomer(filter: 'low');
                                  Navigator.pop(context);
                                },
                                style: TextButton.styleFrom(
                                    backgroundColor: primaryColor),
                                child: Text('低',
                                    style: whiteTextStyle.copyWith(
                                        fontSize: 13, fontWeight: medium)),
                              ),
                              TextButton(
                                onPressed: () {
                                  getCustomer(filter: 'medium');
                                  Navigator.pop(context);
                                },
                                style: TextButton.styleFrom(
                                    backgroundColor: primaryColor),
                                child: Text('中',
                                    style: whiteTextStyle.copyWith(
                                        fontSize: 13, fontWeight: medium)),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  );
                });
              },
            );
          },
          backgroundColor: primaryColor,
          child: Icon(
            Icons.filter_list_rounded,
            size: 30,
            color: accentColor,
          ),
        ),
        appBar: AppBar(
          automaticallyImplyLeading: false,
          elevation: 0,
          backgroundColor: primaryColor,
          title: RichText(
            text: TextSpan(
              text: '客户 ',
              style: whiteTextStyle.copyWith(fontSize: 25, fontWeight: bold),
              children: <TextSpan>[
                TextSpan(
                  text: '(${customer.responseCustomer?.data?.length})',
                  style: whiteTextStyle.copyWith(fontSize: 15, fontWeight: bold),
                ),
              ],
            ),
          ),
        ),
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: Column(
            children: [
              SizedBox(
                width: MediaQuery.of(context).size.width,
                height: MediaQuery.of(context).size.height - 166,
                child: ChangeNotifierProvider(
                  create: (context) => CustomerProvider(),
                  child: GridView.builder(
                    gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                      maxCrossAxisExtent: 200,
                      childAspectRatio: 3 / 2,
                      crossAxisSpacing: 3,
                      mainAxisSpacing: 5,
                    ),
                    itemCount: customer.responseCustomer?.data?.length,
                    itemBuilder: (context, index) {
                      return Card(
                        elevation: 4,
                        color: secondaryColor,
                        child: InkWell(
                          splashColor: accentColor,
                          onTap: () {
                            debugPrint('索引号 $index 被点击');
                          },
                          child: Padding(
                            padding: const EdgeInsets.all(7.0),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Icon(
                                      Icons.account_circle_rounded,
                                      size: 40,
                                      color: accentColor,
                                    ),
                                  ],
                                ),
                                Text(
                                  '${customer.responseCustomer?.data?[index].nmCustomer}',
                                  style: whiteTextStyle.copyWith(
                                    fontSize: 13,
                                    fontWeight: bold,
                                  ),
                                ),
                                Text(
                                  '+62 ${customer.responseCustomer?.data?[index].hpCustomer}',
                                  style: whiteTextStyle.copyWith(
                                    fontSize: 13,
                                    fontWeight: bold,
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

这是我的Provider类:

class CustomerProvider with ChangeNotifier {
  ResponseCustomer? _responseCustomer;
  ResponseCustomer? get responseCustomer => _responseCustomer;

  set responseCustomer(ResponseCustomer? responseCustomer) {
    _responseCustomer = responseCustomer;
    notifyListeners();
  }

  Future<ResponseCustomer> getCustomer({String? filter}) async {
    ResponseCustomer responseCustomer =
        await CustomerService().getCustomer(filter: filter);
    _responseCustomer = responseCustomer;
    debugPrint(responseCustomer.data?.length.toString());
    return responseCustomer;
  }
}

请注意,我已将代码中的注释和部分文本进行了翻译,以提供更好的理解。希望这有助于您理解代码中的内容。如果您有任何其他问题,请随时提问。

英文:

I want to make a filter feature. When I pick a filter, then I fetch data from API and change the UI.

The UI is something like this.
使用Flutter中的Provider来更改UI。

Then I debug the data when I pick the filter, the data was changed, but the UI didn't change.

This is my CustomerPage code
CustomerPage code]

class _CustomerPageState extends State&lt;CustomerPage&gt; {
  getCustomer({String? filter}) async {
    EasyLoading.show(status: &#39;Loading . . .&#39;);
    await Provider.of&lt;CustomerProvider&gt;(context, listen: false)
     .getCustomer(filter: filter);
    EasyLoading.dismiss();
  }
  @override
  Widget build(BuildContext context) {
     CustomerProvider customerProvider = Provider.of&lt;CustomerProvider&gt;(context);
     return Consumer&lt;CustomerProvider&gt;(
    builder: (context, customer, _) =&gt; Scaffold(
          backgroundColor: Colors.white,
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              showModalBottomSheet(
                shape: const RoundedRectangleBorder(
                    borderRadius:
                        BorderRadius.vertical(top: Radius.circular(30))),
                context: context,
                builder: (context) {
                  return StatefulBuilder(builder: (context, setState) {
                    return SizedBox(
                      height: 200,
                      width: MediaQuery.of(context).size.width,
                      child: Padding(
                        padding: const EdgeInsets.all(20.0),
                        child: Column(
                          children: [
                            const SizedBox(height: 20),
                            Row(
                              mainAxisAlignment:
                                  MainAxisAlignment.spaceAround,
                              children: [
                                TextButton(
                                    onPressed: () {
                                      getCustomer(filter: &#39;all&#39;);
                                      Navigator.pop(context);
                                    },
                                    style: TextButton.styleFrom(
                                        backgroundColor: primaryColor),
                                    child: Text(&#39;All&#39;,
                                        style: whiteTextStyle.copyWith(
                                            fontSize: 13,
                                            fontWeight: medium))),
                                TextButton(
                                    onPressed: () {
                                      getCustomer(filter: &#39;suspect&#39;);
                                      Navigator.pop(context);
                                    },
                                    style: TextButton.styleFrom(
                                        backgroundColor: primaryColor),
                                    child: Text(&#39;Suspect&#39;,
                                        style: whiteTextStyle.copyWith(
                                            fontSize: 13,
                                            fontWeight: medium))),
                                TextButton(
                                    onPressed: () {
                                      getCustomer(filter: &#39;low&#39;);
                                      Navigator.pop(context);
                                    },
                                    style: TextButton.styleFrom(
                                        backgroundColor: primaryColor),
                                    child: Text(&#39;Low&#39;,
                                        style: whiteTextStyle.copyWith(
                                            fontSize: 13,
                                            fontWeight: medium))),
                                TextButton(
                                    onPressed: () {
                                      getCustomer(filter: &#39;medium&#39;);
                                      Navigator.pop(context);
                                    },
                                    style: TextButton.styleFrom(
                                        backgroundColor: primaryColor),
                                    child: Text(&#39;Medium&#39;,
                                        style: whiteTextStyle.copyWith(
                                            fontSize: 13,
                                            fontWeight: medium)))
                              ],
                            ),
                          ],
                        ),
                      ),
                    );
                  });
                },
              );
            },
            backgroundColor: primaryColor,
            child: Icon(
              Icons.filter_list_rounded,
              size: 30,
              color: accentColor,
            ),
          ),
          appBar: AppBar(
            automaticallyImplyLeading: false,
            elevation: 0,
            backgroundColor: primaryColor,
            title: RichText(
              text: TextSpan(
                  text: &#39;Pelanggan &#39;,
                  style: whiteTextStyle.copyWith(
                      fontSize: 25, fontWeight: bold),
                  children: &lt;TextSpan&gt;[
                    TextSpan(
                        text:
                            &#39;(${customer.responseCustomer?.data?.length})&#39;,
                        style: whiteTextStyle.copyWith(
                            fontSize: 15, fontWeight: bold))
                  ]),
            ),
          ),
          body: Padding(
            padding: const EdgeInsets.all(10.0),
            child: Column(
              children: [
                SizedBox(
                    width: MediaQuery.of(context).size.width,
                    height: MediaQuery.of(context).size.height - 166,
                    child: ChangeNotifierProvider(
                      create: (context) =&gt; CustomerProvider(),
                      child: GridView.builder(
                        gridDelegate:
                            const SliverGridDelegateWithMaxCrossAxisExtent(
                                maxCrossAxisExtent: 200,
                                childAspectRatio: 3 / 2,
                                crossAxisSpacing: 3,
                                mainAxisSpacing: 5),
                        itemCount: customer.responseCustomer?.data?.length,
                        itemBuilder: (context, index) {
                          return Card(
                            elevation: 4,
                            color: secondaryColor,
                            child: InkWell(
                              splashColor: accentColor,
                              onTap: () {
                                debugPrint(&#39;index number $index tapped&#39;);
                              },
                              child: Padding(
                                padding: const EdgeInsets.all(7.0),
                                child: Column(
                                  crossAxisAlignment:
                                      CrossAxisAlignment.start,
                                  children: [
                                    Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        Icon(
                                          Icons.account_circle_rounded,
                                          size: 40,
                                          color: accentColor,
                                        )
                                      ],
                                    ),
                                    // const SizedBox(height: 7),
                                    Text(
                                      &#39;${customer.responseCustomer?.data?[index].nmCustomer}&#39;,
                                      style: whiteTextStyle.copyWith(
                                          fontSize: 13, fontWeight: bold),
                                    ),
                                    Text(
                                      &#39;+62 ${customer.responseCustomer?.data?[index].hpCustomer}&#39;,
                                      style: whiteTextStyle.copyWith(
                                          fontSize: 13, fontWeight: bold),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          );
                        },
                      ),
                    )),
              ],
            ),
          ),
        ));
  }
}

And this is my Provider class

class CustomerProvider with ChangeNotifier {
  ResponseCustomer? _responseCustomer;
  ResponseCustomer? get responseCustomer =&gt; _responseCustomer;

  set responseCustomer(ResponseCustomer? responseCustomer) {
   _responseCustomer = responseCustomer;
   notifyListeners();
  }

  Future&lt;ResponseCustomer&gt; getCustomer({String? filter}) async {
     ResponseCustomer responseCustomer =
     await CustomerService().getCustomer(filter: filter);
    _responseCustomer = responseCustomer;
    debugPrint(responseCustomer.data?.length.toString());
    return responseCustomer;
  }
 }

Am I did something wrong in UI? Thanks in advance

答案1

得分: 1

只添加以下代码。

并在 getCustomer 函数中添加 notifyListeners();

CustomerPage 中,将 A 更改为 B。

A

class _CustomerPageState extends State<CustomerPage> {
  getCustomer({String? filter}) async {...}

  @override
  Widget build(BuildContext context) {
    CustomerProvider customerProvider = Provider.of<CustomerProvider>(context);

    return Consumer<CustomerProvider>(...
  }
}

B

class _CustomerPageState extends State<CustomerPage> {
  getCustomer({String? filter}) async {...}

  late CustomerProvider customerProvider;
  @override
  Widget build(BuildContext context) {
    customerProvider = Provider.of<CustomerProvider>(context);

    return Consumer<CustomerProvider>(...
  }
}

将 A 更改为 B。

A

child: ChangeNotifierProvider(
  create: (context) => CustomerProvider(),

B

child: ChangeNotifierProvider(
  create: (context) => customerProvider,
英文:

you did made a very simple mistake.

just add following code.

and Add notifyListeners

Future&lt;String&gt; getCustomer({String? filter}) async { ...

 notifyListeners();  
 return ..
 }  // CustomerProvider

And regardless of the function, I think the code below is better.

in CustomerPage

change A to B

A

 class _CustomerPageState extends State&lt;CustomerPage&gt; {

   getCustomer({String? filter}) async {...}

   @override
   Widget build(BuildContext context) {

   CustomerProvider customerProvider = Provider.of&lt;CustomerProvider&gt;(context);

 return Consumer&lt;CustomerProvider&gt;( ......

B

 class _CustomerPageState extends State&lt;CustomerPage&gt; {

   getCustomer({String? filter}) async {...}

   late CustomerProvider customerProvider;
   @override
   Widget build(BuildContext context) {

   customerProvider = Provider.of&lt;CustomerProvider&gt;(context);

 return Consumer&lt;CustomerProvider&gt;( ......

change A to B

A

 child: ChangeNotifierProvider(
 create: (context) =&gt; CustomerProvider(),

B

 child: ChangeNotifierProvider(
 create: (context) =&gt; customerProvider,  

huangapple
  • 本文由 发表于 2023年2月24日 11:39:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75552411.html
匿名

发表评论

匿名网友

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

确定