使用Flutter中的Provider来更改UI。

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

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:

确定