Android開發(fā) 學(xué)習(xí)Flutter 入門
一、前言
最近項(xiàng)目準(zhǔn)備用Flutter混合開發(fā),寫寫學(xué)習(xí)的筆記吧,學(xué)習(xí)Flutter首先需要了解Dart語(yǔ)言,(當(dāng)然安全上網(wǎng)推薦一個(gè)Chrome插件(SetupVpn)),了解Dart相關(guān)語(yǔ)法之后,可以到Flutter中文網(wǎng)學(xué)習(xí)Flutter啦。
二、Flutter 環(huán)境搭建
Flutter中文網(wǎng)有詳細(xì)的教程,我在Mac和Windows上都已經(jīng)成功安裝。
-
Flutter SDK 獲取
去flutter官網(wǎng)下載其最新可用的安裝包,轉(zhuǎn)到下載頁(yè) 。下載后將其解壓,當(dāng)前目錄將為環(huán)境變量需要配置的。
image.png mac 環(huán)境變量設(shè)置:
alias br="flutter packages pub run build_runner build" # br 快捷鍵
alias rmlock="rm -rf /Users/ningzhen942/app/flutter/bin/chche/lockfile" #刪除lockfile 快捷鍵
export PATH=/Users/ningzhen942/app/flutter/bin:$PATH
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

image.png
-
配置好環(huán)境變量 運(yùn)行flutter --version 查看版本
image.png -
運(yùn)行 flutter doctor 查看環(huán)境狀態(tài)
image.png
三、Flutter 工程目錄結(jié)構(gòu)

四、Flutter Widget 與Android 控件聯(lián)想

image.png
五、Demo(ListView)

168336246614882_result.gif
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:vscodeflutter/home.dart';
import 'package:vscodeflutter/muti_phote_page.dart';
import 'package:vscodeflutter/phote_view_page.dart';
import 'package:vscodeflutter/widght/gradient_text.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(new MyApp(
items: new List<ListItem>.generate(1000, (i) {
if (i % 8 == 0) {
return new HeadingItem("Heading I am No.$i");
} else if (i % 8 == 1) {
return new ImageItem(
"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2572170802,3058063046&fm=26&gp=0.jpg",
"Message body $i");
} else if (i % 8 == 2) {
List<String> urls = new List<String>.generate(8, (i) {
return "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3806557979,3233516071&fm=27&gp=0.jpg";
});
return new ListImageItem(urls, "多圖片瀏覽");
} else {
return new MessageItem("Sender $i", "Message body $i");
}
}),
));
}
class MyApp extends StatelessWidget {
final List<ListItem> items;
MyApp({Key key, @required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
final title = 'Flutter List';
return new MaterialApp(
title: title,
home: new Scaffold(
appBar: new AppBar(
title: new Text(title),
backgroundColor: Colors.green,
),
body: new ListView.builder(
// Let the ListView know how many items it needs to build
itemCount: items.length,
// Provide a builder function. This is where the magic happens! We'll
// convert each item into a Widget based on the type of item it is.
itemBuilder: (context, index) {
final item = items[index];
if (item is HeadingItem) {
return getTitleItem(item, context);
} else if (item is MessageItem) {
return new ListTile(
title: new Text(item.sender),
subtitle: new Text(item.body),
);
} else if (item is ImageItem) {
return getImageItem(item, context);
} else if (item is ListImageItem) {
return new Container(
height: 220,
width: double.infinity,
padding: EdgeInsets.fromLTRB(10, 10, 0, 10),
child: ListView.builder(
itemBuilder: (context, index) {
return getListItem(context, item, index);
},
itemCount: item.urls.length,
scrollDirection: Axis.horizontal,
));
}
},
),
),
);
}
ListTile getTitleItem(HeadingItem item, BuildContext context) {
return new ListTile(
title: new GestureDetector(
child: new GradientText(
item.heading,
textAlign: TextAlign.left,
gradient: LinearGradient(colors: [Colors.redAccent, Colors.green]),
style: TextStyle(
fontSize: 30.0,
),
),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new HomePage()),
);
},
));
}
Widget getImageItem(ImageItem item, BuildContext context) {
return new Container(
height: 100,
margin: EdgeInsets.only(left: 10),
child: Stack(
children: <Widget>[
new GestureDetector(
/*child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: new CachedNetworkImage(
imageUrl: item.url,
height: 100,
),
),*/
child: new ClipOval(
child: new CachedNetworkImage(
imageUrl: item.url,
height: 100,
),
),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new PhoteViewPage(item.url)));
},
),
],
),
);
}
Container getListItem(BuildContext context, ListImageItem item, int index) {
return new Container(
width: 220,
height: 220,
padding: new EdgeInsets.only(right: 10),
child: GestureDetector(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new MutiPhotePage(item.urls, index)));
},
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: new CachedNetworkImage(
imageUrl: item.urls[index],
fit: BoxFit.cover,
placeholder: (context, url) => new CircularProgressIndicator(),
errorWidget: (context, url, error) => new Icon(Icons.error),
),
),
));
}
}
// The base class for the different types of items the List can contain
abstract class ListItem {}
// A ListItem that contains data to display a heading
class HeadingItem implements ListItem {
final String heading;
HeadingItem(this.heading);
}
// A ListItem that contains data to display a message
class MessageItem implements ListItem {
final String sender;
final String body;
MessageItem(this.sender, this.body);
}
// A ListItem that contains data to display a message
class ImageItem implements ListItem {
final String url;
final String title;
ImageItem(this.url, this.title);
}
// A ListItem that contains data to display a message
class ListImageItem implements ListItem {
final List<String> urls;
final String title;
ListImageItem(this.urls, this.title);
}
六、Demo直接貼代碼(圖片瀏覽放大)
-
首先在pubspec.yaml引用phote_view 和網(wǎng)絡(luò)圖片加載庫(kù)
image.png
#https://github.com/renefloor/flutter_cached_network_image
cached_network_image: ^0.7.0
#https://github.com/renancaraujo/photo_view
photo_view: ^0.2.2
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
// ignore: must_be_immutable
class PhoteViewPage extends StatefulWidget {
String url;
PhoteViewPage(this.url);
@override
PhoteViewPageState createState() => new PhoteViewPageState(this.url);
}
class PhoteViewPageState extends State<PhoteViewPage> {
String url;
PhoteViewPageState(this.url);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('圖片瀏覽'),
backgroundColor: Colors.green,
),
body: new Container(
color: Colors.white,
child: PhotoView(imageProvider: new CachedNetworkImageProvider(url),
backgroundDecoration: new BoxDecoration(color: Colors.white),
),
),
);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
void didUpdateWidget(PhoteViewPage oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
}
七、多圖片瀏覽
使用TabbarView 與PhoteView 實(shí)現(xiàn)多圖片的瀏覽
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:photo_view/photo_view.dart';
class MutiPhotePage extends StatefulWidget {
List<String> urls;
int postion;
MutiPhotePage(this.urls, this.postion);
@override
MutiPhotePageState createState() => new MutiPhotePageState(urls, postion);
}
class MutiPhotePageState extends State<MutiPhotePage> with SingleTickerProviderStateMixin{
List<String> urls;
int postion;
TabController tabController;
MutiPhotePageState(this.urls, this.postion);
List<Widget> getTabView() {
return urls.map((url) {
return new Container(
child: PhotoView(
imageProvider: new CachedNetworkImageProvider(url),
backgroundDecoration: new BoxDecoration(color: Colors.white),
),
);
}).toList(growable: true);
}
@override
void initState() {
super.initState();
this.tabController =
new TabController(length: urls.length, initialIndex: postion,vsync: this);
}
@override
void dispose() {
super.dispose();
}
@override
void didUpdateWidget(MutiPhotePage oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("查看多張圖片"),
backgroundColor: Colors.green,
),
body: new Container(
child: new TabBarView(
children: getTabView(),
controller: tabController,
),
),
);
}
}



