(安卓,flutter)【項目記錄】flutter項目記錄,各種大坑小坑

博客文章鏈接:https://hanbaoaaa.xyz/index.php/archives/23/k.html
已經完成了。在這裏總結一下。

圖片名稱 一開始剛接觸flutter先搞了下界面佈局

然後是做和服務器的接口訪問。

使用的是dio的庫。爲了使用方便 再次封裝了一下。

import 'package:dio/dio.dart';
import 'main.dart';

class HttpUtil{
  static String tokenHttp;
  bool getting=false;
  static Options options= Options(headers: {"token": tokenHttp});
  static updateHttpUtil(){
    options=Options(headers: {"token": tokenHttp});
    //print("update:"+options.headers.toString());
  }
  onlyParaHttp(var data,String address,{String absoluteAddress})async{
    //print(options.headers);
    try {
      Response response;
      if(data==null){
        response = await Dio().post(
          absoluteAddress==null?RootAddress + address:absoluteAddress,
          options: options,
        );
      }else{
        response = await Dio().post(
          absoluteAddress==null?RootAddress + address:absoluteAddress,
          options: options,
          queryParameters: data,
        );
      }

      return response.data;
    } catch (e) {
      //Toast.toast(context1, msg: "鏈接超時", position: ToastPostion.bottom);
      getting = false;
      print("httpfailed:"+absoluteAddress==null?RootAddress + address:absoluteAddress);
      return print(e);
    }
  }
  onlyPara(var data,String address,Null whenComp(val),{String absoluteAddress}){

    if(!getting){
      getting=true;
      onlyParaHttp(data,address,absoluteAddress: absoluteAddress).then((val){
        getting=false;
        return val;
      }).then(whenComp);
      return false;
    }else{
      return true;
    }
  }

}

將token設置爲靜態變量。這裏提一下。建議把面向對象裏的全局變量設置成靜態變量。之前普通的全局變量是相當於一直加載着的,會面臨不更新的情況,dart裏面的非必要參數寫在{ }裏面和js比較像。

然後的話dart裏的函數可以像參數一樣傳遞。不用像java c#那種要藉助委託來實現。所以把回調函數作爲參數傳遞給整個執行函數就行了。然後再http接受完的.then();裏面執行回調的函數


然後是彈出窗口。

showDialog<Null>(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
        return StatefulBuilder(
            builder: (context, state) {
                return new AlertDialog(
                    title: new Text('當前劇本要花費'+fee.toString()+"個幣"),
                    actions: <Widget>[
                        new FlatButton(
                            child: new Text('取消'),
                            onPressed: () {
                                Navigator.of(context).pop();
                            },
                        ),
                        new FlatButton(
                            child: new Text(text),
                            onPressed: (){
                                buyHttp.onlyPara({
                                    "id":id
                                }, "/buyFileServlet", (val){
                                    ////print(val);
                                    switch(val['status']){
                                        case 454:
                                            state(() {
                                                text="餘額不足";
                                            });
                                            break;
                                        case 1:
                                            Navigator.of(context).pop();
                                            gotoDetail(index,pagecount);
                                            break;
                                    }
                                });
                            },
                        ),
                    ],
                );

            },
        );

    },
);

使用statefulBuilder可以動態的更新彈出窗口內的內容。不過setstate名字被參數名替換掉了。


Navigator.of(context)..pop()..pop("deleted!");

使用這個語句來連續彈出兩個頁面,


waitForUpload(BuildContext context) async {
  var result=await Navigator.of(context1).pushNamed('/jubenUpload', arguments: {"name": "上傳我的劇本"});
  print('result');
  print(result);
  if(result!=null){
    updateInfo();
  }

}

使用這種異步函數來抓取彈出後返回的變量。


flutter的build函數屬於一直在執行的那種。

@override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

這個函數的話屬於初始話只執行一次。

像界面啓動後做請求或者做彈窗就可以用這個。

但是一定要在build完畢的時候執行界面繪製。

所以界面繪製相關的內容。要用來註冊回調。這個回調只會被執行一次。

WidgetsBinding.instance.addPostFrameCallback((_){
    /// 接口請求if (
    getList.onlyPara({
      "type":0
    }, "/showUserFileServlet", (val){
      ////print(val['list']);
      jubenstate.setState((){
        ////print(list);
        list=val['list'];
      });
      authors=List(list.length);
      for(int i=0;i<val['list'].length;i++){
        HttpUtil getname= HttpUtil();
        getname.onlyPara({"userid":list[i]['user_id']}, "/usernameServlet", (val1){
          ////print(val1);

          authors[i]=(val1['username']);
          jubenstate.setState((){});
        });
      }
      ////print(authors.length);
      ////print(list.length);

    });
  });

這裏面我state是作爲全局變量共享的。實際不建議這樣。以後一定要作爲參數傳遞。或者乾脆把setstate這句話作爲函數傳遞。


在flutter裏函數是變量。可以寫成局部函數。也可以作爲參數傳遞。


文件管理。直接嫖的網上現成,但不知道怎麼調用系統文件管理。


關於網絡權限

,安卓新的api需要申請各種權限。

這幾個權限是比較基本的,加載java的AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

還有網絡訪問http需要做手腳。不然會在視頻播放裏連不上。

這裏要對flutter的AndroidManifest.xml做處理。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.juben">
    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="juben"
        android:networkSecurityConfig="@xml/network_security_config"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/ic_launcher">


        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"

            android:windowSoftInputMode="adjustResize">

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

android:networkSecurityConfig="@xml/network_security_config"重點是這一句

在res文件夾裏建xml文件夾。xml文件夾裏建xml文件。內容爲:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">106.15.206.164</domain>
    </domain-config>
</network-security-config>

ip位置寫允許http的ip或者域名。


好了。要說的說完了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章