component

Input box

FillColor: Colors. White, filled:trueThe width and height of the TextField can be modified by using the contentPadding (decoration: InputDecoration). InputDecoration( contentPadding: const EdgeInsets.symmetric(vertical: 10.0),),),) this change can be implemented without prefixIcon, if the prefixIcon is added, a minimum height will appear, then the change will fail if the height is too small. New ConstrainedBox(constraints: BoxConstraints(maxHeight: 25, maxWidth: 25) 200 ), child: new TextField( decoration: InputDecoration( contentPadding: const EdgeInsets.symmetric(vertical: 4.0), hintText:'Please enter search content',
            prefixIcon: Icon(Icons.search),
            // contentPadding: EdgeInsets.all(10),
            border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(15),
                borderSide: BorderSide.none),
            filled: true, fillColor: Color(0xffaaaaaa),),),), maxHeight is the maximum height, which can be changed as required. MaxWidth is the maximum width. You can modify the width of the TextField. Container(width: adapt.dp (326), height: adapt.dp (95), child: TextField(maxLines:99, // keyboardType: TextInputType.number, style: TextStyle( color: MyColors.black_00, fontSize: MyFonts.mediumminus, ), // textAlign: Textalign.center, decoration: InputDecoration(// fillColor: MyColors. Grey_f5, Filled:true,

//                          hintText: "Minimum value", hintStyle: TextStyle( color: MyColors.grey_99, fontSize: MyFonts.small), contentPadding: Edgeinsets.fromltrb (adapt.dp (5.0), adapt.dp (7.0), adapt.dp (5.0), adapt.dp (6.0)), border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(Adapt.dp(7))), borderSide: BorderSide.none), ), ), ),Copy the code

With rounded corners

Drawer rounded: Widget build(BuildContext context) {returnContainer( decoration: BoxDecoration( color: MyColors.white, // borderRadius: BorderRadius.circular(Adapt.dp(20)), ), child: ClipRRect( borderRadius: BorderRadius.circular(Adapt.dp(20)), child: Drawer(common Container: borderRadius: Borderradius. only(topLeft: radius.circular (adapt.dp (20))),bottomLeft: Radius.circular (Adapt.dp(20),)),Copy the code

Add a border

                decoration: BoxDecoration(
                  border: Border(right:BorderSide(
                    width: 1,color: Color(0xffddd)
                  ))
                ),
Copy the code

Pop-up drawer

'Scaffold. Of () called with a context that does not contain a Scaffold.' Use GlobalKey < ScaffoldState > key = new GlobalKey (); void_handlerDrawerButton() {
    key.currentState.openEndDrawer();
  }

  Widget build(BuildContext context) {
    returnScaffold( key: key, backgroundColor: MyColors.grey_f5, appBar: _appbar, endDrawer: Child: DrawerWidget (), or the Container (...). body: Container( ), ); }Copy the code

Regular InkWell rounded button

InkWell( onTap: () { // _captchaPressed(); // Reset operation}, child: Container(height: adapt.dp (44), width: adapt.dp (110), alignment: alignment (0, 0), decoration: new BoxDecoration( color: MyColors.white, borderRadius: BorderRadius.all( Radius.circular(Adapt.dp(22))), border: new Border.all(width: 1, color: Colors.red),), child: Text("Reset", style: TextStyle(color: mycolors.text_font_black, fontSize: myfontfonts. Large, fontWeight: fontweight.bold,)),) Container(margin: EdgeInsets. Only (left: 40, top: 40), child: new Material(// Color: color. Red, decoration: new BoxDecoration(// background color: color: color. BorderRadius: borderradius. all(radius.circular (25.0)), // Set border: new border. 1, color: color.red),), child: new InkWell(// Set the rounded corner, also set the same rounded corner for the water ripple // If this is not set there will be a rectangular water ripple effect. New BorderRadius. Circular (25.0), // Sets the click event callback onTap: () {}, child: Container(// Sets the child center alignment: Alignment(0, 0), height: 50, width: 300, child: Text("Click on the rounded border of the Container"() (() (() (() (() (Copy the code

WidgetSpan

Text.rich(
            TextSpan(children: <InlineSpan>[
              TextSpan(text: Breaks down "XXXXXXXXXXXX breaks down they dizzy dizzy dizzy dizzy dizzy dizzy dizzy dizzy dizzy dizzy dizzy dizzy x"),
              WidgetSpan(
                  child: Container(
                color: Colors.blue,
                width: 30.0,
                height: 100.0,
              )),
              TextSpan(text: "xxy"),
            ]),
            overflow: TextOverflow.ellipsis,
            maxLines: 2.)Copy the code

RaisedButton RaisedButton

RaisedButton: Container(width: adapt.dp (265), height: adapt.dp (40), Child: RaisedButton(color: mycolor.ls, shape: RoundedRectangleBorder( side: BorderSide.none, borderRadius: BorderRadius.all(Radius.circular(25))), child: Text(test['complete'],
                        style: TextStyle(
                            color: Colors.white, fontWeight: FontWeight.bold),
                      ),
                      textColor: Theme.of(context).accentColor,
                      onPressed: () {
                        print('x');
                      })), 
Copy the code

Render list data

1.ListView
Expanded(
          child: ListView.builder(
            shrinkWrap: true, / /trueCan solve the problem of child controls must set the height of the physics: NeverScrollableScrollPhysics (), / / disable sliding event itemBuilder: (the context, the index) {return _buildList(list[index]);
            },
            itemCount: list.length,
          ),
        )
Widget _buildList(item) {
    returnGestureDetector( behavior: HitTestBehavior.translucent, // onTap: CommonUtil.openPage(context, widget), child: Adapt.dp(13), right: adapt.dp (13), left: adapt.dp (13) Adapt.dp(13)), padding: EdgeInsets.all(Adapt.dp(13)), decoration: BoxDecoration( color: MyColors.white, borderRadius: BorderRadius.circular(10)), child: Row( 2.map Expanded( child: ListView( children: getDistributorList(), ), )getDistributorList() {
    return productNameList.map((item) {
      return GestureDetector(
        onTap: () {

        },
        behavior: HitTestBehavior.translucent,
        child: Container(
          padding: EdgeInsets.only(top: Adapt.dp(13)),
          child: Row(
            children: <Widget>[
              Text(
                item['name']????"",
                style: TextStyle(
                    fontSize: MyFonts.mediumminus, color: MyColors.black_33),
              )
            ],
          ),
        ),
      );
    }).toList();
  }
Copy the code

The sliding box showModalBottomSheet

  1. Unable to set rounded corners directly;

  2. Components can only fill half the screen, and any more is out of bounds;

Reference: blog.csdn.net/cpcpcp123/a…

ShowDialog and showModalBottomSheet status updates do not refresh the solution

Cloud.tencent.com/developer/a…

Add controllers to each list in the listView

  void initState() {
    // TODO: implement initState
    super.initState();
//    this.getTotalPrice();
    for (int i = 0; i < productList.length; i++) {
//      controller.add (TextEditingController(text: "1")); productList[i]["getNum"] = "1"; }}return productList.map((item){
      var textEditingController = new TextEditingController(text: item["getNum"]);
     
     TextField(
                    controller: textEditingController,
                          onChanged: (text){
//                  _onChanceCount(item,text);
//                      setState(() {returns the input box item["getNum"]=text;
//                      });
                    },
Copy the code

Some thoughts on Dialog

https://juejin.cn/post/6844903833575882759 https://github.com/liyabin1105/flutter_dialog/blob/master/lib/MyHomePage.dart Other studies of FLUTTER: Teach you the custom Dialog https://www.codercto.com/a/92081.html https://blog.csdn.net/ulddfhv/article/details/91491918 https://www.jianshu.com/p/4bbbb5aa855d ios style box, with input box showCupertinoDialog (context: context, builder: (context) {return CupertinoAlertDialog(
                          title: Text('tip'Content: Card(elevation: 0.0, child: Column(children: <Widget>)'Confirm the goods are in storage? '),
                                SizedBox(height: 10,),
                                Container(height: 26,
//                                color:  Colors.grey.shade50,
//                                padding: EdgeInsets.only(top: ),
                                child: TextField(
                                  controller: null,
                                  style: TextStyle(
                                    color: MyColors.black_00,
                                    fontSize: MyFonts.mediumminus,
//                        fontWeight: FontWeight.bold,
                                  ),
                                  decoration: InputDecoration(
                                      contentPadding: EdgeInsets.only(left: 16,top: 5,bottom: 4),
                                      border: OutlineInputBorder(
                                          borderRadius: BorderRadius.all(Radius.circular(Adapt.dp(13))),
                                          borderSide: BorderSide.none),
                                      hintText: 'Fill in the notes',
                                      filled: true,
                                      fillColor: Colors.grey.shade50),
                                ),)

                              ],
                            ),
                          ),
                          actions: <Widget>[
                            CupertinoDialogAction(
                              onPressed: () {
                                Navigator.pop(context);
                              },
                              child: Text('cancel',style: TextStyle(color: MyColors.black_33),),
                            ),
                            CupertinoDialogAction(
                              onPressed: () {
                                Navigator.pop(context);
                              },
                              child: Text('sure',style: TextStyle(color: Colors.red),),
                            ),
                          ],
                        );
                      });
Copy the code

‘alertDialogLabel’ was called on null.

The main reference https://juejin.cn/post/6844903763543588877. Js

localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, YabandLocalizationsDelegate.delegate, Const FallbackCupertinoLocalisationsDelegate (), / / to join this, the above three is I used to international], class FallbackCupertinoLocalisationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> { const FallbackCupertinoLocalisationsDelegate(); @override bool isSupported(Locale locale) =>true;

  @override
  Future<CupertinoLocalizations> load(Locale locale) =>
      DefaultCupertinoLocalizations.load(locale);

  @override
  bool shouldReload(FallbackCupertinoLocalisationsDelegate old) => false;
}

Copy the code

Capture application exit interception pop-up dialog box

Reference: www.cnblogs.com/pjl43/p/994…

Future<bool>  _isSave() {if(productList! = []) {return
        showDialog(
            context: context,
            builder: (context) =>
                CustomDialog(
                   title: 'tip',
                  content: 'Shipping order not saved, confirm exit? ', // confirmTextColor: Colors.red[400], confirmCallback: () { CommonUtil.closePage(context); })); }else{
        CommonUtil.closePage(context);
      }
}
  Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: _isSave,
        child: Scaffold(
      resizeToAvoidBottomPadding: false,
      appBar: MyAppBar(
        title: "New Delivery Note",
        isBack: trueBackEvent: _isSave,// click the icon to return the result does not trigger, the result button is triggeredCopy the code

Tabbar is not used at the top and bottom

import 'package:flutter/cupertino.dart';
import 'package:yilingpharmacy_doctor/common/CommonInsert.dart';


class MyPatientMainPage extends StatefulWidget {
  @override
  _MyPatientMainPageState createState() => _MyPatientMainPageState();
}

class _MyPatientMainPageState extends State<MyPatientMainPage>
    with SingleTickerProviderStateMixin {
  String dropdownValue = "Online";
  var _tabController;
  var _tabIndex = 0;
  void initState() {
    super.initState();
    _tabController = new TabController(length: 2, vsync: this);
    _tabController.addListener((){
      setState(() {
        _tabIndex = _tabController.index;
      });
      print(_tabController.index);    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
/ / SizedBox (height: Adapt. ScreenH () * 0.052,),
      Container(
// alignment: Alignment.bottomLeft,
          height: Adapt.screenH() * 0.153,
          color: MyColors.lv,
          padding: EdgeInsets.only(
            top: Adapt.screenH() * 0.052,
          ),
          child: Row(
            children: <Widget>[
              SizedBox(
                width: Adapt.dp(10),
              ),
              Container(
                // There are two ways to set your avatar.
                height: Adapt.dp(50),
                width: Adapt.dp(50),
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(Adapt.dp(25))),
                child: LocalImageSelecter.getImage("b1_data_ic_yszczd"),
              ),
              SizedBox(
                width: Adapt.dp(11),
              ),
              Container(
                height: Adapt.dp(50),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(
                      height: 3,
                    ),
                    Row(
                      children: <Widget>[
                        Text(
                          "Liu Haifan",
                          style: TextStyle(
                              fontSize: Adapt.dp(14),
                              color: Colors.white,
                              fontWeight: FontWeight.bold),
                        ),
                        SizedBox(
                          width: Adapt.dp(13.5),
                        ),
                        GestureDetector(
                          onTap: null,
                          child: Container(
                            width: Adapt.dp(54),
                            decoration: BoxDecoration(
                              color: Colors.white,
                              borderRadius: BorderRadius.circular(Adapt.dp(2)),
                            ),
                            child: Row(
                              children: <Widget>[
                                SizedBox(
                                  width: Adapt.dp(6),
                                ),
                                Text(
                                  dropdownValue,
                                  style: TextStyle(color: MyColors.lv),
                                ),
                                SizedBox(
                                  width: Adapt.dp(6),
                                ),
                                LocalImageSelecter.getImage(
                                    "b1_arrow_drop_green",
                                    imageHeight: 10),
                                SizedBox(
                                  width: Adapt.dp(5),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: Adapt.dp(12),
                    ),
                    Row(
                      children: <Widget>[
                        Text(
                          'First-grade Psychological Consultant, Mental Health Instructor of Chinese Academy of Sciences',
                          style: TextStyle(
                              fontSize: Adapt.dp(12), color: Colors.white),
                        ),
                      ],
                    )
                  ],
                ),
              )
            ],
          )),
      Container(
// color: Colors.black,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Expanded(
              flex: 1,
              child: TabBar(
                indicator: const BoxDecoration(),// Do not add a dash
                controller: _tabController,
                tabs: <Widget>[
                  Tab(
                      child:
                     Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                       crossAxisAlignment: CrossAxisAlignment.center,
                       children: <Widget>[
                         Text(
                           "Graphic consultation",
                           style: _tabIndex==0? TextStyle( color: MyColors.black_33, fontSize: MyFonts.f_14, fontWeight: FontWeight.bold):TextStyle( color: MyColors.black_33, fontSize: MyFonts.f_14, ), ), _tabIndex==0? SizedBox(height:12,):SizedBox(height: 15,),
                         _tabIndex==0? Container(color: MyColors.lv,height:3,width: 20,):SizedBox()
                       ],
                     )
                  ),
                  Tab(
                      child:
                      Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                          Text(
                            "Appointment for consultation.",
                            style: _tabIndex==1? TextStyle( color: MyColors.black_33, fontSize: MyFonts.f_14, fontWeight: FontWeight.bold):TextStyle( color: MyColors.black_33, fontSize: MyFonts.f_14, ), ), _tabIndex==1? SizedBox(height:12,):SizedBox(height: 15,),
                          _tabIndex==1? Container(color: MyColors.lv,height:3,width: 20,):SizedBox()
                        ],
                      )
                  ),
                ],
              ),
            )
          ],
        ),

// body: ,
      ),
      Expanded(
        child: TabBarView(
          controller: _tabController,
          children: <Widget>[Text("xx"), Text("xx")],),)]); }}Copy the code

Animation Controler can transform the slider in the later stage

Minor bug: The TAB bold effect appears a little slow when swiping over

Blog.csdn.net/yechaoa/art…

www.jianshu.com/p/8f2fa2882…

Android Studio

Open the Android Studio home screen: Ctrl +Alt+S open the search box on the left side of the screen and type keyMap. For example, if you want to find the name completion of a class, You can put the class name keyword in the search box on the right and you can make any modifications that you want shortcut meaning abbreviationCopy the code

other

Add color

Color: const color (0xFF0099ff), or /Colors. Grey/Opacity: child:Opacity(0, child: Container(width: 100.0, height: 0) 100.0, margin: EdgeInsets. All (20.0), color: color (0xffff0000),), color: color.transparent or rgboCopy the code

Lazy loading

whensetState() or markNeedsBuild() called during build. Void onDataChange2(val) {if (mounted)
      Future.delayed(Duration(milliseconds: 200)).then((e) {
        setState(() { isTab = val; }); }); }Copy the code

Migrating androidX (runtime and usetime inconsistent)

Stackoverflow.com/questions/5…

  1. At the project level, build.gradle changes the classpath toCom. Android. Tools. Build: gradle: 3.3.1.
  2. At the application level, build.gradle puts yourcompileSdkVersionAnd changetargetSdkVersionFor 28.
  3. Now, right click on the Android directory in the Flutter project, go to Flutter, and then click on the Open Android module in Android Studio. Open the project in a new window.
  4. Now, go to “refactor” in the toolbar, and click “migrate to AndroidX.”
  5. Then click “Perform Refactoring” and wait for Gradle to build.

Change gradle version

android/gradle/wrapper/grade-wrapper.properties

#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\:/ / services.gradle.org/distributions/gradle-5.4.1-all.zip
Copy the code

Globally timed invoke request

I usually use it after login, but I use it after login

class IndexPage extends StatefulWidget {

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

class _IndexPageState extends State<IndexPage> {
  void initState() {
    super.initState();
    countdown();
  }
    Timer countdownTimer;

  void countdown() { countdownTimer = new Timer.periodic(new Duration(seconds: 10), (timer) { _getUnread(); }); } _getUnread() async {// The interface you want to callif(LocalStorage.get(BaseCommon.USER_ID)! =null) { var res = await HttpManager.netFetch( context, Address.findByAccountIdAndAlias(), {"accountId": LocalStorage.get(BaseCommon.USER_ID)},
          null,
          null,
          noTip: true);
      if(res ! = null) { LocalStorage.save("Unread", res.data['unread']);
        LocalStorage.save("MessagePcketid", res.data['id']);
        print('Unread interface');
        print(LocalStorage.get(("Unread")).toString());
        print('MessagePcketid Interface with unread ID ');
        print(LocalStorage.get(("MessagePcketid")).toString());
      } else{ toast(BaseCommon.SERVER_ERROR); }}}Copy the code

The timer

Captcha kind of thing

    _countdownTimer =
              new Timer.periodic(new Duration(seconds: 1), (timer) {
                if (mounted) {
                  setState(() {
                    if (countDownNum > 1) {
                      countDownNum--;
                    } else {
                      showCountDown = false; _countdownTimer.cancel(); _countdownTimer = null; }}); }});Copy the code

Qualify TextField input content

www.jianshu.com/p/627a7acde…

www.jianshu.com/p/1ef43e6da…

The pop-up menu in the upper right corner of the page

www.jianshu.com/p/1ce574ddb…

Scaffold(
        resizeToAvoidBottomInset: false,
        backgroundColor: MyColors.bg,
        appBar: MyAppBar(
          title: test['myTeam'],
          rightEvent: Container(height: 50,width: 30,child: new PopupMenuButton(
              itemBuilder: (BuildContext context) => <PopupMenuEntry>[
                PopupMenuItem(
                    child: GestureDetector(onTap: (){
                      ClipboardData data = new ClipboardData(text:'xx');
                      Clipboard.setData(data);
                      Toast.show(test['toast_copy_invitation_code_success'], context,
                          duration: Toast.LENGTH_SHORT, gravity: Toast.CENTER);
                      Navigator.pop(context);
                    },
                      child: Text(test['copy_invitation_code'],style: TextStyle(fontSize: 12),),)
                ),
                PopupMenuItem(
                    child: GestureDetector(onTap: null,
                      child: Text(test['dissolveTeam'],style: TextStyle(fontSize: 12(() (() (() (() (() [() (()Copy the code

Copy to the paste board

GestureDetector(onTap: (){
                      ClipboardData data = new ClipboardData(text:'xx');
                      Clipboard.setData(data);
})
Copy the code

Components: ClipboardData. Dart

import 'package:flutter/services.dart';


class ClipboardData {
  /// Creates data for the system clipboard.
  const ClipboardData({this.text});

  /// Plain text variant of this clipboard data.
  final String text;
}

class Clipboard {
  Clipboard._();


  static const String kTextPlain = 'text/plain';

  /// Stores the given clipboard data on the clipboard.
  /// Paste board to copy the contents of ClipboardData
  static Future<void> setData(ClipboardData data) async {
    await SystemChannels.platform.invokeMethod<void> ('Clipboard.setData',
      <String.dynamic> {'text': data.text, }, ); }}//ClipboardData data = new ClipboardData(text:"1231231231231231");
//Clipboard.setData(data);
//showMyToast(' copied to paste board ');
Copy the code

Flutter TabBarView toggles pages to prevent refreshing resets

Blog.csdn.net/qq_27981847…

There are also some bugs,

He goes in, he gets the data, he goes to TAB, he comes back and he gets a page refresh render

Mounted = if (mounted) mounted

This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree

Ignore it.

The bottomNavigationBar in THE FLUTTER switches the component saving state scheme

Cloud.tencent.com/developer/a…

Partial modification:

  var _pages= [
      new WebPage(),
      new DiscoverPage(),
      new UserPage(),
    ];
Copy the code

The data source

The standard ListView constructor works for small lists. To handle lists that contain a large amount of data, it is best to use the ListView.Builder constructor.

The ListView constructor needs to create all the items at once, but the ListView.builder constructor does not, and will create the list item as it scrolls onto the screen.

https://flutterchina.club/cookbook/lists/long-lists/
final controller = new List<String>.generate(3, (i) => "controller$i"); / / the following error https://blog.csdn.net/dpl12/article/details/92012226 final List < String > items; items:new List<String>.generate(1000, (i)=>"item $i") /Copy the code

Delay time to refresh

  _dataRefresh(){
    Future.delayed(Duration(milliseconds: 200)).then((e) {
      _list = [];
      _getDataList();
    });
  }
Copy the code

packaging

www.jianshu.com/p/093e17686…

Blog.csdn.net/DeckeDeng/a…

flutter build apk

Packing should be noted:

The repackage location is not in the original android, app, but under build/app

C:\workFlutter\warehouse\build\app\outputs\apk\release

Flutter modifies the App name and icon

Blog.csdn.net/mengks1987/…

Image upload (with backend)

  void _uploadPictures() async {
    var list =
    await MultiImagePicker.pickImages(maxImages: 9, enableCamera: true);
    setState(() {
      images = images+list;
    });
    for (var r in list) {
      var t = await r.filePath;
      await _upLoadImage(File(t));
    }
  }



  _upLoadImage( File croppedFile) async {
    String _path = croppedFile.path;
    var _name = _path.substring(_path.lastIndexOf("/") + 1, _path.length);
    String _suffix = _name.split(".").last.toLowerCase();

    ContentType _contentType;

    if (_suffix == "jpg") {
      _contentType =ContentType("image"."jpeg");
    } else if (_suffix == "png") {
      _contentType =ContentType("image".'png');
    }

    FormData _formData = new FormData.from({
      "file": new UploadFileInfo(croppedFile, _name,contentType: _contentType)
    });

    String host = 'https://app.ji-hong.com.cn/api';
    String url='/attachment/upload';

    Dio dio = new Dio();
    Response response =await dio.post("$host$url", data: _formData);

    if (response.statusCode == 200) {
      var resCode = response.data['code'];
      if (resCode == 200) {
        uploadimageList.add(response.data['data']);
        print(response.data['data']);
      } else if (resCode == 400) {
        showToast(response.data['message']);
      }
    }
  }



  Widget buildGridView() {
    return GridView.builder(
        itemCount: images.length + 1,
        shrinkWrap: true,
        physics: NeverScrollableScrollPhysics(),
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3, crossAxisSpacing: 4, mainAxisSpacing: 3),
        itemBuilder: (BuildContext context, int index) {
          returnindex ! = images.length ? Stack(children: <Widget>[ GestureDetector( onTap: () { showDialog( context: context, builder: (_) => Center( child: AssetThumb( asset: images[index], width:300,
                        height: 300,),)); }, child: AssetThumb( asset: images[index], width:105,
                height: 105,),),new Positioned(
                right: 10,
                top: 0.05,
                child: new GestureDetector(
                    onTap: () {
                      setState(() {
                        if(uploadimageList.length == images.length){ images.remove(images[index]); uploadimageList.removeAt(index); }else{
                          toast("Wait until the pictures are uploaded and delete them."); }}); }, child:new Container(
                      decoration: new BoxDecoration(
                        color: Colors.black45,
                        shape: BoxShape.circle,
                      ),
                      child: new Icon(
                        Icons.close,
                        color: Colors.white,
                        size: 20.0,
                      ),
                    )))
          ])
              : GestureDetector(
              onTap: _uploadPictures,
              child: Container(
                alignment: Alignment.topLeft,
                  child: LocalImageSelecter.getImage('d_icon_sczp_n',
                      imageWidth: Adapt.dp(105),
                      imageHeight: Adapt.dp(105))));
        });
  }

// Validation before submission
_getDataList2() async {
    if(uploadimageList.length! =images.length){toast("Pictures have not been uploaded, wait...");return; }Copy the code

Dart Grammar notes

Add request backend return data

This adds the array _list.addall (res.data);

This one adds map_list.add(list);

Data is the map object res.data[‘productDTOList’]

Check whether the map contains a keyif (res.data.containsKey(“productDTOList”)).

If (_list.length! = 0) {