Flutter個人外掛使用整理

_驍發表於2020-02-14

時間外掛和格式化

flutter_cupertino_date_picker+date_format

參考:

github.com/dylanwuzh/f…

www.cnblogs.com/yiweiyihang…

日曆格式化外掛date_format

cloud.tencent.com/developer/a…

import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
  void _showDatePicker() {
    DatePicker.showDatePicker(
      context,
      pickerTheme: DateTimePickerTheme(
        showTitle: true,
        confirm: Text('確定', style: TextStyle(color: Colors.red)),
        cancel: Text('取消', style: TextStyle(color: Colors.cyan)),
      ),
      minDateTime: DateTime.parse("2019-05-21"),
//      maxDateTime: DateTime.parse(MAX_DATETIME),
      initialDateTime: DateTime.now(),
      dateFormat: "yyyy-MM-dd",
      locale: DateTimePickerLocale.zh_cn,
      onConfirm: (dateTime, List<int> index) {
        setState(() {
          _date = dateTime;
        });
      },
    );
  }
複製程式碼

圖片選擇multi_image_picker

參考:

pub.dev/packages/mu…

sh1d0w.github.io/multi_image…

android/app/src/main/AndroidMainFest.xml中加入

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
複製程式碼

android/app/build.gradle中

android {
    compileSdkVersion 28

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.paoding.jihong_horticulture_warehouse"
        minSdkVersion 19   //16改成19
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
複製程式碼

android/build.gradle

    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
    }
}
複製程式碼

android/gradle/wrapper/gradle-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

複製程式碼

最後一條

然後刪掉gradle中原來版本的包

用法參考:

  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) {
          return index != 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("等圖片上傳成功再刪唄");
                        }
                      });
                    },
                    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))));
        });
  }

//提交前的驗證
_getDataList2() async {
    if(uploadimageList.length!=images.length){toast("圖片未上傳完畢,稍等。。");return;}
複製程式碼

側滑

flutter_slidable: 0.5.3

juejin.im/post/5d81ed…

toast

toast外掛 pub.flutter-io.cn/packages/ok…

OKToast(
  /// set toast style, optional
  child:MaterialApp()
);
複製程式碼

自定義封裝:

搞個dart檔案裝這個

import 'package:jihong_horticulture_warehouse/common/CommonInsert.dart';

ToastFuture toast(String text){
  return  showToast(text,
      textPadding:EdgeInsets.fromLTRB(Adapt.dp(14), Adapt.dp(9), Adapt.dp(13), Adapt.dp(9)),
      position: ToastPosition(align: Alignment.center,),
      backgroundColor: Colors.black,
      radius: Adapt.dp(4),
      textStyle:
      TextStyle(color: MyColors.white, fontSize: MyFonts.mediumminus));
}
複製程式碼

其中Adapt.dp是自適應寬度,要使用的時候引用這個檔案,toast('文字');即可

Flutter個人外掛使用整理
上面寫法:

 showToastWidget(Center(
            child: Container(
              decoration: BoxDecoration(
                  color: Colors.black.withOpacity(0.7),
                  borderRadius: BorderRadius.circular(10)),
              padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 28),
              child: Column(
                children: <Widget>[
                  LocalImageSelecter.getImage('icon_common_ok',
                      imageWidth: 44, imageHeight: 44),
                  SizedBox(
                    height: 10,
                  ),
                  Text(
                    'success',
                    style: TextStyle(fontSize: 12),
                  )
                ],
                mainAxisSize: MainAxisSize.min,
              ),
            ),
          ));
複製程式碼

掃描二維碼

pub.dev/packages/ba…

blog.csdn.net/qq_35905501…

有錯誤,由於在pub.dev中引用了最新的版本,導致需要向androidX 移植

juejin.im/post/5b700d…

改用低版本的,導致包重複。

高階的:不再卑微 - - jdk裡面寫成jre ext.kotlin_version = '1.2.31'圖是1.3.21

www.cnblogs.com/gxsyj/p/114…

 Android dependency ‘androidx.core:core’ has different version for the compile (1.0.0) and runtime (1.0.1) classpath. You should manually set the same version via DependencyResolution
複製程式碼

www.codercto.com/a/80137.htm…

閃光燈英文在

C:\flutter.pub-cache\hosted\pub.dartlang.org\barcode_scan-0.0.6\android\src\main\kotlin\com\apptreesoftware\barcodescan第一個kt檔案裡改成中文

生成二維碼

二維碼生成外掛qr_flutter 3.1.0

pub.dev/packages/qr…

低版本的會報錯,謹記。

Flutter picker外掛

彈出列表滑動選擇

https://github.com/yangyxd/flutter_picker/blob/master/example/lib/main.dart
複製程式碼

本地化,長按字元跳出的copy換成複製

在main檔案裡新增:

  Widget build(BuildContext context) {
    return OKToast(
      position: ToastPosition.bottom,
      backgroundColor: MyColors.button_bg_grey_deep,
      child: MaterialApp(
        onGenerateRoute: prefix0.onGenerateRoute,
        initialRoute: '/',
        title: 'JIHong',
          
          
           localizationsDelegates: [
          PickerLocalizationsDelegate.delegate, // 如果要使用本地化,請新增此行,則可以顯示中文按鈕
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        supportedLocales: [
          const Locale('en', 'US'),
          const Locale('zh', 'CH'),
        ],
複製程式碼

參考:blog.csdn.net/u010126792/…

www.jianshu.com/p/ac1615db8…

wifi外掛

後來換成wifi-iot,但是和二維碼外掛衝突,目前手機如果只需要開關wifi的話是挺容易解決的,但是要連線指定wifi應該是隻能android能做到

pub.dev/packages/wi…

跑了個deemo

報錯:

gradlew.bat" exited abnormally:

versionCode not found. Define flutter.versionCode in the local.properties file.

解決:

blog.csdn.net/qq_24550911…

在android/local.properties中加入

sdk.dir=C:\\Users\\EDZ\\AppData\\Local\\Android\\sdk
flutter.sdk=C:\\flutter
    下面三句話
flutter.buildMode=debug
flutter.versionName=1.0.0
flutter.versionCode=1
複製程式碼

Flutter 撥打電話和跳轉網頁

url_launcher

pub.flutter-io.cn/packages/ur…

最新版要求的dart.sdk版本要很高

換成url_launcher:5.2.1

blog.csdn.net/qq_33210042…

flutter_html

pub.flutter-io.cn/packages/fl…

import 'package:flutter_html/flutter_html.dart';
SingleChildScrollView(
          child: Html(
            data:‘’,
複製程式碼

微信登陸fluwx

獲取code,利用sendAuth

一直出現 沒有這個簽名這個錯誤

deemo的sendAuth我是跑步起來的

然後專案也跟著壞了

重啟了下手機,可以了

main.js

  await fluwx.register(
      appId: "wx747bca6f419ed7a3",
      doOnAndroid: true,
      doOnIOS: true,
      );
  var result = await fluwx.isWeChatInstalled();
  print("is installed $result");

複製程式碼

登陸頁面

  void initState(){
    super.initState();
    fluwx.responseFromAuth.listen((response) {
      //監聽授權登入回撥
      print("code: " + response.code);
    });
  }

在元件中
ontap:(){  fluwx.sendAuth(scope: "snsapi_userinfo", state: "wechat_sdk_demo_test");}
複製程式碼

相關網站:

github.com/OpenFlutter…

地址外掛

 import 'package:city_pickers/city_pickers.dart';
  String provinceS;
  String cityS;
  String districtS;
  void _selectCity() async {
    Result tempResult = await CityPickers.showCityPicker(
        context: context,
        locationCode: resultAttr != null
            ? resultAttr.areaId ??
            resultAttr.cityId ??
            resultAttr.provinceId
            : null,
        showType: ShowType.pca,
        height: 350,
        isSort: isSort,
        barrierOpacity: barrierOpacityAttr,
        itemExtent: customerItemExtent,
        cancelWidget: Text('取消',style: TextStyle(color: MyColors.blue_4f,fontSize: MyFonts.f14),),
        confirmWidget: Text('確定',style: TextStyle(color: MyColors.blue_4f,fontSize: MyFonts.f14),),
        itemBuilder: this.getItemBuilder());
    print("locationCode $tempResult");
    if (tempResult == null) {
      return;
    }
    this.setState(() {
      result = tempResult;
      provinceS = result.provinceName;
      cityS = result.cityName;
      districtS = result.areaName;
      pccAddress = "${result.provinceName}${result.cityName}${result?.areaName}";
    });
  }
複製程式碼

上拉重新整理下拉載入

import 'package:pull_to_refresh/pull_to_refresh.dart';
int biu = 0;//下拉狀態
  RefreshController _refreshController =
      RefreshController(initialRefresh: false);//是否進去就重新整理
//上拉方法+篩選頁面(方便)
  void _onRefresh() async {
    // monitor network fetch
    await Future.delayed(Duration(milliseconds: 1000));
    // if failed,use refreshFailed()
    _refreshController.refreshCompleted();
    _pageNo = _pageNo2=1;
    _list=[];
    if(!isPage2) {
      _getDataList();
    }else{
      _getDataList2();
    }
    _refreshController.loadComplete();
  }
//下拉方法
  void _onLoading() async {
    // monitor network fetch
    await Future.delayed(Duration(milliseconds: 1000));
    if(!isPage2) {
      _pageNo++;
      _getDataList();
    }else{
      _pageNo2++;
      _getDataList2();
    }
    if (biu == 2) {
      _refreshController.loadNoData();
        //發現只要出現這個無資料狀態就不能再下拉載入,會導致進入篩選頁面也不能下拉
        //需要_refreshController.loadComplete();重置下狀態
    } else if (biu == 0) {
      _refreshController.loadFailed();
    } else {
      _refreshController.loadComplete();
    }
  }
  bool flag = true; 
  bool isPage2 = false;//是否篩選頁
  int _pageNo = 1;//第幾頁
  int _pageNo2 = 1;
 List _list = [];

  void initState() {
    super.initState();
    _getDataList();
  }

  void dispose() { // 銷燬textEditingController
      controller1.dispose();
      controller2.dispose();
      controller3.dispose();
   	 super.dispose();
  }
//正常的請求
  _getDataList() async {
    var res = await HttpManager.netFetch(
        context, address.findAllWarehouseComplaint(), {"pageable": {"page": _pageNo, "size": 5}}, null, null, noTip: true);
    isPage2 = false;
    if (res != null) {
      if (res.result) {
        if (mounted) {
          setState(() {
            if (res.data.length != 0) {
              _list.addAll(res.data);
              biu = 3;
            } else {
              biu = 2;
            }
          });
        }
      }
    } else {
      biu = 0;
      toast(BaseCommon.SERVER_ERROR);
    }
  }

//篩選頁的請求+下拉
  _getDataList2() async{
    isPage2 = true;
    Map<String,dynamic> map = new Map();
    map = {"providerName":controller3.text,"plantName":controller1.text,"status":status,"complaintName":controller2.text,"pageable": {"page": _pageNo2, "size": 5}};
    var res = await HttpManager.netFetch(
        context, address.filterWarehouseComplaint(), map, null, null, noTip: true);
    if (res != null) {
      if (res.result) {
        if (mounted) {
          if(_pageNo2==1&&res.data.length == 0){
            if (mounted) {
              setState(() {
                flag = false;
              });
            }
          }
          else if (res.data.length != 0) {
            setState(() {
              _list.addAll(res.data);
            });
            biu = 3;
          } else {
            biu = 2;
          }
        }
      }
    } else {
      biu = 0;
      toast(BaseCommon.SERVER_ERROR);
    }
  }

 Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomPadding: false,//讓鍵盤可以覆蓋佈局
        key: key7,
        backgroundColor: MyColors.grey_f5,
        appBar: MyAppBar(
          title: "售後投訴",
          isBack: true,
          rightEvent: InkWell(
            child: Text("篩選"),
            onTap: _handlerDrawerButton,
//              Scaffold.of(context).openEndDrawer();
//          CommonUtil.openPage(context, forgetPassword2());
          ),
        ),
        body: SmartRefresher(
          enablePullDown: true,
          enablePullUp: true,
          header: WaterDropHeader(),
          footer: CustomFooter(
            builder: (BuildContext context, LoadStatus mode) {
              Widget body;
              if (mode == LoadStatus.idle) {
                body = Text("上拉載入");
              } else if (mode == LoadStatus.loading) {
                body = CupertinoActivityIndicator();
              } else if (mode == LoadStatus.failed) {
                body = Text("載入失敗!點選重試!");
              } else if (mode == LoadStatus.canLoading) {
                body = Text("鬆手,載入更多!");
              } else {
                body = Text("沒有更多資料了!");
              }
              return Container(
                height: 55.0,
                child: Center(child: body),
              );
            },
          ),
          controller: _refreshController,
          onRefresh: _onRefresh,
          onLoading: _onLoading,
          child: flag
              ? ListView.builder(
                  itemBuilder: (context, index) {
                    return _buildList(_list[index]);
                  },
                  itemCount: _list.length,
                )
              : new SearchError(callback: (val) => onDataChange(val)),
        ),
        endDrawer: Container(
            
複製程式碼

相關文章