Flutter從相簿選擇圖片並顯示出來,上傳到伺服器
阿新 • • 發佈:2021-02-10
文章目錄
在Android中從手機相簿選擇一些圖片出來是很常用的功能。Flutter也提供了很好用的第三方庫可以幫助我們快速實現這個需求。
實現效果如下
接下來看看該怎麼用。
匯入依賴包
版本號可以到puv.dev
上查詢最新的替換上去。
dependencies:
multi_image_picker: ^4.6.1
multi_image_picker的使用
使用這個外掛也很簡單。首先匯入包
import 'package:multi_image_picker/multi_image_picker.dart';
接著就訪問相簿選擇圖片。
- 先定義一個List<Asset> resultList用於儲存選擇後的圖片資訊。
- MultiImagePicker.pickImages的返回型別是List<Asset>
- 相關引數使用看程式碼中的註釋
// 選擇照片並上傳 Future<void> uploadImages() async { if (resultList == null) { resultList = List<Asset>(); } try { var tmp = await MultiImagePicker.pickImages( // 可選引數, 若resultList不為空,再次開啟選擇介面的適合,可以顯示之前選中的圖片資訊。 selectedAssets: resultList, // 選擇圖片的最大數量 maxImages: 9, // 是否支援拍照 enableCamera: true, materialOptions: MaterialOptions( // 顯示所有照片,值為 false 時顯示相簿 startInAllView: false, allViewTitle: '所有照片', actionBarColor: '#2196F3', textOnNothingSelected: '沒有選擇照片'), ); if (tmp.length != 0) { resultList = tmp; setState(() {}); } } on Exception catch (e) { e.toString(); } }
這樣選擇圖片的功能就以及做好了。
顯示圖片
接下來實現顯示圖片的功能。
使用gridview顯示。
因為選擇後的圖片是一個Asset型別。所以可以使用 AssetThumb
顯示圖片
AssetThumb(
asset: resultList[index],
width: 300,
height: 300,
)
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('發動態'), actions: [ IconButton( icon: Icon(Icons.send), onPressed: () async { }) ], ), body: Container( padding: EdgeInsets.all(5), child: ListView( children: [ TextField( controller: _controller, decoration: InputDecoration( border: OutlineInputBorder(), hintText: '說點什麼……'), maxLines: 7, ), Row( children: [ RaisedButton( onPressed: () { uploadImages(); }, child: Text('選擇圖片'), ), ], ), Container( width: double.infinity, height: 1000, child: GridView.builder( padding: EdgeInsets.all(0), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 2, mainAxisSpacing: 2), itemBuilder: (BuildContext context, int index) { return _createGridViewItem( AssetThumb( asset: resultList[index], width: 300, height: 300, ), index); }, itemCount: resultList.length, ), ) ], ), ), ); } _createGridViewItem(widget, index) { return Container( height: 100, width: 100, padding: EdgeInsets.all(0), margin: EdgeInsets.all(0), child: Stack( children: [ widget, Positioned( top: 0, right: 0, child: GestureDetector( onTap: () { setState(() { resultList.removeAt(index); }); }, child: Icon( Icons.close, color: Colors.grey, ), ), ) ], ), ); }
上傳圖片
匯入依賴dio
dependencies:
dio: ^3.0.10
dio_log: ^1.3.5
dio中提供了檔案上傳的方式,具體可以去看官方文件。
- MultipartFile 是Dio中使用者檔案上傳的類
- 如果一次性需要傳多個圖片,可以用一個List陣列儲存
List<MultipartFile> files = List();
// resultList就是之前獲取選擇圖片的List
for (int i = 0; i < resultList.length; i++) {
// 獲取 ByteData
ByteData byteData = await resultList[i].getByteData();
List<int> imageData = byteData.buffer.asUint8List();
MultipartFile multipartFile = MultipartFile.fromBytes(
imageData,
// 檔名
filename: 'some-file-name.jpg',
// 檔案型別
contentType: MediaType("image", "jpg"),
);
files.add(multipartFile);
}
封裝到FormData裡面。
- 這裡的image就是後端介面中接收檔案的引數名。如果傳入的是一個數組,則會自動加上
[]
FormData formData = FormData.fromMap({
// 後端介面的引數名稱
"image": files,
});
之後就可以上傳了。
HttpUtils.instance.post("/upload", formData,
success: (response) {
//這部分是對相應結果的處理,大家可以根據自己返回的資料型別進行修改
if (response['code'] == 200) {
List list = response['data'];
for (var i = 0; i < list.length; i++) {
if (i != 0) urls += "¥";
urls += list[i];
}
}
});
可能遇到的問題
理論上使用multi_image_picker是不用管許可權問題的,但是如果遇到了Permission denied的情況的話,則開啟
android\app\src\main\AndroidManifest.xml
這個檔案
然後加上這幾個許可權
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.jxj4869.flutter_imagepick_demo">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
完整程式碼已經上傳GitHubhttps://github.com/jiang4869/CSDNBlogCode/tree/master/flutter_imagepick_demo,喜歡的話可以start一些。這個demo是動態上傳介面。可以傳送文字和圖片資訊。
拒絕白嫖,從點一鍵三連開始