Flutter實戰 從頭擼一個「孤島」APP(No.二、閃屏Splash Page、引導頁) 這篇發表以後呢,並無收到不少鼓勵,只有大佬,牛皮啊
這一條評論,是來自掘友平賀才人,那可能你們並不太清楚,這一系列的Flutter,是要作成什麼樣子
應用到什麼Flutter技術
,其中咱們會使用到html
有狀態``無狀態
那本篇我就先畫一下這個APP,會長什麼樣,UI並非我原創,其中會應用到一套後臺的API前端
完整的開發文檔 後臺API 這是[林間有風團隊]小程序相關的接口,暫時用這個先ios
APP完整的樣子git
回顧項目目錄github
之後我們儘可能以json
這樣的三部分來構建正篇文章的結構,那咱們這段旅程就來一塊兒開發【書單】這部分,do it,axios
咱們仍是秉承面向部件、面向組件開發的中心思想,二話不說 ,我仍是打算在widgwts
文件夾下新建搜索這個部件,並命名widget_search_bar.dart
使用第三方的插件小程序
當前版本 ^1.0.0api
使用:軟件包提供了一個搜索小部件,用於從數據列表中選擇一個選項。提供基於搜索文本的項目過濾。瀏覽器
import 'package:loader_search_bar/loader_search_bar.dart';
複製代碼
在main
函數中初始化一下兼容配置
// 兼容異常處理
void enablePlatformOverrideForDesktop() {
if (!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux)) {
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
}
}
複製代碼
那實際上是main
中主要是進行一些初始化操做
void main() {
enablePlatformOverrideForDesktop();
runApp(MyApp());
}
複製代碼
初始化list 數據
List<LeaderBoard> list = <LeaderBoard>[
LeaderBoard("Flutter", 54),
LeaderBoard("React", 22.5),
LeaderBoard("Vue", 24.7),
LeaderBoard("小程序", 22.1),
];
複製代碼
這些數據是顯示在列表這兒的
核心代碼即是
SearchWidget<LeaderBoard>(
dataList: list, // 數據源
hideSearchBoxWhenItemSelected: false,
listContainerHeight: MediaQuery.of(context).size.height / 4,
// 基於搜索查詢過濾數據列表的選項
queryBuilder: (query, list) {
return list
.where((item) =>
item.username.toLowerCase().contains(query.toLowerCase()))
.toList();
},
// 彈出列表項構建器的選項。這基本上返回一個小部件以在彈出窗口中顯示爲列表項
popupListItemBuilder: (item) {
return PopupListItemWidget(item);
},
// 爲選定的列表項構建器提供的選項,當用戶從彈出列表中選擇一個項時啓用
selectedItemBuilder: (selectedItem, deleteSelectedItem) {
return SelectedItemWidget(selectedItem, deleteSelectedItem);
},
// 定製小部件
noItemsFoundWidget: NoItemsFound(),
// 提供自定義TextField的選項。接受TextEditingController和FocusNode做爲參數
textFieldBuilder: (controller, focusNode) {
return MyTextField(controller, focusNode);
},
// 用於獲取所選擇的選項。返回所選項目;若是刪除了該項,則返回null
onItemSelected: (item) {
setState(() {
_selectedItem = item;
});
},
),
複製代碼
listContainerHeight: MediaQuery.of(context).size.height / 4,
複製代碼
在這部分,有用到MediaQuery
,它即是適配屏幕的一種方式,在以前第一段旅程的時候,也有提到屏幕適配
在搜索的時候,我並不想出它出現搜索的顯示
selectedItemBuilder: (selectedItem, deleteSelectedItem) {
return SelectedItemWidget(selectedItem, deleteSelectedItem);
},
複製代碼
看一下源碼,它仍是要求我們必須傳入的,那我們就把這部分返回一個空的Container
class SelectedItemWidget extends StatelessWidget {
const SelectedItemWidget(this.selectedItem, this.deleteSelectedItem);
final LeaderBoard selectedItem;
final VoidCallback deleteSelectedItem;
@override
Widget build(BuildContext context) {
return Container();
// 這Container()即是返回的選中後的值
// Container(
// padding: const EdgeInsets.symmetric(
// vertical: 2,
// horizontal: 4,
// ),
// child: Row(
// children: <Widget>[
// Expanded(
// child: Padding(
// padding: const EdgeInsets.only(
// left: 16,
// right: 16,
// top: 8,
// bottom: 8,
// ),
// child: Text(
// selectedItem.username,
// style: const TextStyle(fontSize: 14),
// ),
// ),
// ),
// IconButton(
// icon: Icon(Icons.delete_outline, size: 22),
// color: Colors.grey[700],
// onPressed: deleteSelectedItem,
// ),
// ],
// ),
// );
}
}
複製代碼
在初始化數據的時候LeaderBoard
,咱們填充了LeaderBoard("Flutter", 54),
這每個數據實際上是一個數據模型,這裏我們先不說JSON 與Model之間的轉換
在以後的旅程與後臺通訊的過程當中,咱們就選取dio
這個庫來輔助請求,這就相似於React、Vue 項目中的axios
,
dio是一個強大的Dart Http請求庫,支持Restful API、FormData、攔截器、請求取消、Cookie管理、文件上傳/下載、超時、自定義適配器等...意思是總得有個與後臺通訊的工具吧,不是嗎?當前的版本是3.0.7
dependencies:
dio: ^3.0.7
複製代碼
import 'package:dio/dio.dart';
複製代碼
讓咱們先來發送個請求試一下,那麼後臺的接口選哪一個呢,我記得以前有寫個在線模擬的接口,是用的淘寶開源的
接口地址 在線接口模擬
響應數據
{
"code": 200,
"data": [
{
"name": "洋小洋同窗",
"age": 18,
"flag": "up"
}
]
}
複製代碼
請求方式 GET 也就是說能夠直接在瀏覽器地址欄 輸入便會返回結果
那麼咱們怎麼利用前文所提到的dio
去發送請求呢?既然是一個網絡請求,那仍是老樣子,少不了是要封裝的,那本章節的我們先試試水,初探一下。
這個請求的方法暫且寫在utils
這個公共方法的文件夾裏,並命名my_http.dart
,寫上一段簡單的代碼
import 'package:dio/dio.dart';
void getHttp() async {
try {
Response response = await Dio().get(
"http://rap2api.taobao.org/app/mock/236998/isolated/island/api/v1/test");
print('後臺返回的結果是 ${response}');
} catch (e) {
print(e);
}
}
複製代碼
因爲咱們接下來將要請求書單
的數據,那咱們打算在book_list_page.dart
初始化調用,在有狀態的組件是有這個初始化的方法的,在其中能夠作一些事情,有點相似前端的生命週期鉤子,顯然在調試的控制檯返回的正是咱們預期的結果
先來看一下真實後臺返回的接口數據,其返回一個列表,包含全部熱門書籍的概要信息
/book/hot_list
[{
"author": "[\u7f8e]\u4fdd\u7f57\u00b7\u683c\u96f7\u5384\u59c6",
"fav_nums": 259,
"id": 7,
"image": "https://img3.doubanio.com/lpic/s4669554.jpg",
"like_status": 0,
"title": "\u9ed1\u5ba2\u4e0e\u753b\u5bb6"
}, {
"author": "MarkPilgrim",
"fav_nums": 145,
"id": 65,
"image": "https://img3.doubanio.com/lpic/s4059293.jpg",
"like_status": 0,
"title": "Dive Into Python 3"
}, {
"author": "MagnusLieHetland",
"fav_nums": 88,
"id": 183,
"image": "https://img3.doubanio.com/lpic/s4387251.jpg",
"like_status": 0,
"title": "Python\u57fa\u7840\u6559\u7a0b"
}, {
"author": "[\u54e5\u4f26\u6bd4\u4e9a]\u52a0\u897f\u4e9a\u00b7\u9a6c\u5c14\u514b\u65af",
"fav_nums": 99,
"id": 1002,
"image": "https://img3.doubanio.com/lpic/s6384944.jpg",
"like_status": 0,
"title": "\u767e\u5e74\u5b64\u72ec"
}, {
"author": "[\u65e5]\u5ca9\u4e95\u4fca\u4e8c",
"fav_nums": 78,
"id": 1049,
"image": "https://img1.doubanio.com/view/subject/l/public/s29775868.jpg",
"like_status": 0,
"title": "\u60c5\u4e66"
}, {
"author": "[\u7f8e]\u4e54\u6cbb\u00b7R\u00b7R\u00b7\u9a6c\u4e01",
"fav_nums": 52,
"id": 1061,
"image": "https://img3.doubanio.com/lpic/s1358984.jpg",
"like_status": 0,
"title": "\u51b0\u4e0e\u706b\u4e4b\u6b4c\uff08\u5377\u4e00\uff09"
}, {
"author": "[\u65e5]\u4e1c\u91ce\u572d\u543e",
"fav_nums": 81,
"id": 1120,
"image": "https://img3.doubanio.com/lpic/s4610502.jpg",
"like_status": 0,
"title": "\u767d\u591c\u884c"
}, {
"author": "\u91d1\u5eb8",
"fav_nums": 50,
"id": 1166,
"image": "https://img1.doubanio.com/lpic/s23632058.jpg",
"like_status": 0,
"title": "\u5929\u9f99\u516b\u90e8"
}, {
"author": "[\u65e5]\u4e1c\u91ce\u572d\u543e",
"fav_nums": 13,
"id": 1308,
"image": "https://img3.doubanio.com/lpic/s3814606.jpg",
"like_status": 0,
"title": "\u6076\u610f"
}, {
"author": "[\u82f1]J\u00b7K\u00b7\u7f57\u7433",
"fav_nums": 33,
"id": 1339,
"image": "https://img3.doubanio.com/lpic/s1074376.jpg",
"like_status": 0,
"title": "\u54c8\u5229\u00b7\u6ce2\u7279\u4e0e\u963f\u5179\u5361\u73ed\u7684\u56da\u5f92"
}, {
"author": "\u97e9\u5bd2",
"fav_nums": 21,
"id": 1383,
"image": "https://img1.doubanio.com/lpic/s3557848.jpg",
"like_status": 0,
"title": "\u4ed6\u7684\u56fd"
}, {
"author": "[\u82f1]J\u00b7K\u00b7\u7f57\u7433",
"fav_nums": 32,
"id": 1398,
"image": "https://img1.doubanio.com/lpic/s2752367.jpg",
"like_status": 0,
"title": "\u54c8\u5229\u00b7\u6ce2\u7279\u4e0e\u6b7b\u4ea1\u5723\u5668"
}, {
"author": "\u738b\u5c0f\u6ce2",
"fav_nums": 17,
"id": 1560,
"image": "https://img1.doubanio.com/lpic/s3463069.jpg",
"like_status": 0,
"title": "\u4e09\u5341\u800c\u7acb"
}, {
"author": "[\u4f0a\u6717]\u739b\u8d5e\u00b7\u838e\u5854\u78a7",
"fav_nums": 16,
"id": 7821,
"image": "https://img3.doubanio.com/lpic/s6144591.jpg",
"like_status": 0,
"title": "\u6211\u5728\u4f0a\u6717\u957f\u5927"
}, {
"author": "[\u65e5]\u6751\u4e0a\u6625\u6811",
"fav_nums": 10,
"id": 8854,
"image": "https://img1.doubanio.com/lpic/s29494718.jpg",
"like_status": 0,
"title": "\u8fdc\u65b9\u7684\u9f13\u58f0"
}, {
"author": "\u4e09\u6bdb",
"fav_nums": 18,
"id": 8866,
"image": "https://img3.doubanio.com/lpic/s2393243.jpg",
"like_status": 0,
"title": "\u68a6\u91cc\u82b1\u843d\u77e5\u591a\u5c11"
}, {
"author": "\u97e9\u5bd2",
"fav_nums": 21,
"id": 15198,
"image": "https://img1.doubanio.com/lpic/s1080179.jpg",
"like_status": 0,
"title": "\u50cf\u5c11\u5e74\u5566\u98de\u9a70"
}, {
"author": "\u9c81\u8fc5",
"fav_nums": 30,
"id": 15984,
"image": "https://img3.doubanio.com/lpic/s27970504.jpg",
"like_status": 0,
"title": "\u671d\u82b1\u5915\u62fe"
}, {
"author": "[\u65e5]\u4e95\u4e0a\u96c4\u5f66",
"fav_nums": 33,
"id": 21050,
"image": "https://img3.doubanio.com/lpic/s2853431.jpg",
"like_status": 0,
"title": "\u704c\u7bee\u9ad8\u624b31"
}, {
"author": "[\u65e5]\u65b0\u4e95\u4e00\u4e8c\u4e09",
"fav_nums": 24,
"id": 51664,
"image": "https://img3.doubanio.com/lpic/s29034294.jpg",
"like_status": 0,
"title": "\u4e1c\u4eac\u65f6\u5473\u8bb0"
}]
複製代碼
response_description
參數字段 | 含義 |
---|---|
author | 做者 |
fav_nums | 點贊數 |
id | 書籍ID |
image | 書籍圖片 |
like_status | 是否點贊 |
title | 書籍題目 |
未完待續。。。
那其實本週作的東西是有點少的,只是和你們熟悉了一下界面的樣子,而主要開發的書單這一塊呢,如今接口返回的數據已經知曉了,也明確了應用dio
這個庫,不過癮的話那就
謝謝你看到這裏,若是感到有點用的話,但願點點關注、給個贊、寫點我的見解在評論..本身也會穿插着寫一些深入的關於某個技能點的文章,先從Flutter 中的狀態管理
這個主題開始吧,那加油,我是洋小洋同窗
,全部的代碼都會同步到github
--END--THANKS--