博客文章鏈接:https://hanbaoaaa.xyz/index.php/archives/23/k.html
已經完成了。在這裏總結一下。
然後是做和服務器的接口訪問。
使用的是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或者域名。
好了。要說的說完了。