Flutter:常见编码问题及解决1.
⾃定义组件开发:
* 看是否是继承statelesswidget还是stafulwidget
* 如果是纯展⽰的,没有和⽤户交互的就⽤statelesswidget,
* 但是例如和⽤户交互例如搜索框,就⽤stafulwidget
2.
StatelessWidget继承⾃widget,⽽@immutable abstract class Widget extends DiagnosticableTree,
其中@immutable注解标识了其⼦类不可变,所以下⾯的属性⽤final
3.
当2层会有重叠,⽤普通的BoxDecrotion会被上⾯的视图盖住,所以会看不出圆⾓的效果。
解决这个问题就使⽤PhysicalModel,这是flutter专门为我们提供的。
@override
Widget build(BuildContext context) {
return PhysicalModel(
child: Column(
children: _gridNavItems(context),
),
color: ansparent,//透明
borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.antiAlias,//裁切
);
}
4.
stack布局是后⾯的⼀个覆盖在前⾯的⼀个上⾯
5.
Dart语法中,forEach不要返回值。map要返回值。
_items(BuildContext context) {
if (localNavList == null) return null;
List<Widget> items = [];
localNavList.forEach((model) {
//forEach不要返回值。map要返回值
items.add(_item(context, model));
});
6.
mainAxisAlignment: MainAxisAlignment.spaceAround,//spaceAround是平均排列
7.下划线效果:
decoration: BoxDecoration(
//下划线
border: Border(
bottom: BorderSide(width: 1, color: Color(0xfff2f2f2)))),
8.获取⼿机屏幕的宽度:
child: Imagework(
model.icon,
fit: BoxFit.fill,
/
**
* 获取⼿机屏幕的宽度:MediaQuery.of(context).size.width
*/
width: MediaQuery.of(context).size.width/2-10,//减去10实际上是减去padding,减去多⼀点防⽌屏幕右边溢出 height: big? 129 : 80,
),
9.封装webview这个Widget:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
/**
* @date on 2019/5/11
* @author Yinlei
* @packagename
* @email 1099129793@qq
* @describe 引⼊webview插件,并重新封装他。.
*/
//⾃定义url⽩名单[协程的⾸页]
const CATCH_URLS = ['m.ctrip/', 'm.ctrip/html5/', 'm.ctrip/html5'];
class WebView extends StatefulWidget {
final String url;
final String statusBarColor;
final String title;
final bool hideAppBar;
final bool backForbid;//可空的,所以在构造函数中应该为它增加默认值
WebView(
{this.url,
this.statusBarColor,
this.title,
this.hideAppBar,
this.backForbid = false});
this.backForbid = false});
@override
_WebViewState createState() => _WebViewState();
}
class _WebViewState extends State<WebView> {
final webviewReference = FlutterWebviewPlugin();
StreamSubscription<String> _onUrlChanged;
StreamSubscription<WebViewStateChanged> _onStateChanged;
StreamSubscription<WebViewHttpError> _onHttpError;
bool exiting = false;//是否退出当前⽹页
@override
void initState() {
super.initState();
webviewReference.close();
_UrlChanged.listen((String url){
});
_StateChanged.listen((WebViewStateChanged state){
pe){
case WebViewState.startLoad:
//这⾥是混合开发|。如果跳转到webview后,加载的页⾯如果按顶部appbar的返回键的时候会返回到携程⽹站的⾸页,所以要拦截让他返回我们的⾸页
if(_isToMain(state.url)&&!exiting){
if(widget.backForbid){//根据接⼝的字段,如果他是禁⽌返回就还是加载当前页⾯
//意思就是它的上⼀级的url没有可以返回的或者说是禁⽌返回的就还是重复加载当前页⾯
webviewReference.launch(widget.url);
}else{
Navigator.pop(context);
exiting =true;//防⽌重复返回
}
}
break;
default:
break;
}
});
_HttpError.listen((WebViewHttpError error){
print(error);
});
}
/**
* 判断跳转的html的url是不是携程⽹的⼀些⾸页。
*/
_isToMain(String url){
bool contain = false;//默认不在⽩名单
for(final value in CATCH_URLS){
if(url?.endsWith(value)??false){//url不为空且在⽩名单⾥⾯
contain =true;
break;
}
}
return contain;
}
@override
void dispose() {
_onHttpError.cancel();
_onHttpError.cancel();
_onUrlChanged.cancel();
_onStateChanged.cancel();
webviewReference.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
//颜⾊的定义
String statusBarColorStr = widget.statusBarColor ?? 'ffffff';
Color backButtonColor;
if(statusBarColorStr == 'ffffff'){
backButtonColor = Colors.black;
}else{
backButtonColor = Colors.white;
}
border radius什么意思return Scaffold(
body: Column(
children: <Widget>[
//⼀个完整的颜⾊有8位,后4位是RGB,0x代表⼗六进制,0x后的2位数字代表alpha透明度 _appBar(Color(int.parse('0xff'+statusBarColorStr)),backButtonColor),
//webview要展⽰的内容,让他充满整个界⾯
Expanded(child: WebviewScaffold(
userAgent: 'null',
url: widget.url,
withZoom: true,//缩放
withLocalStorage: true,//缓存
hidden: true, //默认为隐藏
initialChild: Container(
color: Colors.white,
child: Center(
child: Text('你瞅啥,我就要让你等⼀会⼉,不服打我啊~'),
),
),//默认隐藏的时候初始化的界⾯
))
],
),
);
}
/**
* ⾃定义appbar
*/
_appBar(Color backgroundColor,Color backButtonColor){
if(widget.hideAppBar??false){//是否隐藏这个appbar,默认是false
return Container(//隐藏就返回⼀个container
color: backgroundColor,
height: 30,
);
}
/
/⾮隐藏appbar的情况下
return Container(
color: backgroundColor,
//解决刘海等⼿机挡住⾃定义appbar的返回键
padding: EdgeInsets.fromLTRB(0, 40, 0, 10),
child: FractionallySizedBox(//撑满屏幕的宽度
widthFactor: 1,//宽度的充满
child: Stack(
children: <Widget>[
GestureDetector(
onTap: (){
onTap: (){
//返回按钮的事件处理
Navigator.pop(context);
},
child: Container(
margin: ly(left: 10),
child: Icon(
Icons.close,
color: backButtonColor,
size: 26,
),
)
,
),
//设置标题:⽤绝对定位
Positioned(
left: 0,
right: 0,
child: Center(
child: Text(widget.title??'',style: TextStyle(color: backButtonColor,fontSize: 20),),//widget.title??''表⽰title为空就返回空字符串 ),
)
],
),
),
);
}
}
10.异步
//利⽤promise⽅式
// HomeDao.fetch().then((result){
// setState(() {
// resultString = de(result);
// });
// }).catchError((e){
/
/ setState(() {
// String();
// });
// });
//⽅式2:利⽤async await
11.
直接⽤ListView的话,对于刘海⼿机,listview⾃⾝会对它有个padding作为预留空间。但是此处为了好看,不想预留它,就⽤
因为系统⾃带的appbar不便于扩展,所以就采⽤⾃定义appbar来实现滚动渐变。此处还要设置⼀个层叠的布局效果,让appbar层叠在轮播图上。
stack布局中,后⼀个元素会层叠在上⼀个元素的上⾯
12.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论