flutter 常用代码块

1,575 阅读4分钟

问题

  1. container match_parent 无法使用 见 flutter_slide_move
  2. wrap 无效 见flutter_search_site common_view.dart
  3. win 10 Android studio 连接不了 iphone
  4. 解决 github.com/flutter/flu… behavior: HitTestBehavior.opaque, GestureDetector padding 部分点击无效 height 有效 见 flutter_search_site _topBar
  5. position 无效 _DesignHomeSceneState
  6. ios 端运行报错,可能是自己写的调用原生没写iOS端出现的问题.关系到平台到第三方和所有自己写到原生都要双端运行bian

报错

Android dependency 'androidx.versionedparcelable:versionedparcelable' has different version for the compile (1.0.0) and runtime (1.1.0-rc01) classpath. You should manually set the same version via DependencyResolution stackoverflow.com/questions/5…

规范

1.方法私有前面带_,这样这个方法没有用到就会是灰色的。不带_的都是黄色的。(没Java的智能)

2.注释最顶部加个对于tab的名字,没像Android xml 一样的预览视图,加些文字标识回头修改应该会方便些

网址

常量(final和const) final和const区别 blog.csdn.net/hxl51711627…

flutter 命令 www.cnblogs.com/cag2050/p/1… 切换flutter sdk到稳定版 flutter channel stable

dart 基础 dart.dev/guides/lang… pub 包 库 pub.flutter-io.cn/

苹果下载库慢 pod repo update mirror.tuna.tsinghua.edu.cn/help/CocoaP…

Automatically assigning platform Podfile # platform :ios, '9.0' (去了#号)

http 协议

<application ... android:usesCleartextTraffic="true" ...>

打包

flutterchina.club/android-rel…

关闭页面 刷新父视图

关闭子页面,父页面会调用build

函数默认值

TextStyle defaultTextStyle({color = SQColor.darkGray}) {
    return TextStyle(
        fontSize: 15,
        color: color,
        decorationColor: SQColor.white,
        fontWeight: FontWeight.normal);
  }

延迟 暂停

await Future.delayed(const Duration(milliseconds: 100), () {});

List

map

返回一个新的list

List<Widget> categoriesText = categories.map((f) {
      return categoryText(f.title);
    }).toList();
// dynamic 声明的变量可以赋值任意对象    
// 不指定类型 返回的是dynamic 再添加widget类型元素时会报类型错误    
Widget categoryText(String title, {TextStyle textStyle}) {
    return Container(
      alignment: AlignmentDirectional.bottomStart,
      padding: EdgeInsets.symmetric(horizontal: 8),
      child: Text(title, style: textStyle,),
    );
  }    

view旋转

juejin.cn/post/684490…

弹窗

void showCleanCacheDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (build) {
          return Center(
            child: dialogBody(), // 现在container 宽高才有效
          );
        });
  }

布局

stack

重叠布局

text style

text 的 style 和当前页面最外层的环境有关 一般最外层为 Scaffold 字体比较正常,非scaffold样式为

Container

在一个页面最外面的container 高度是match_parent,在children 中高度是wrap_content

wrap_content match_parent

默认是 match_parent

  1. ListView shrinkWrap: true
  2. Row mainAxisSize: MainAxisSize.min

水平滚动wrap_content

 Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        new SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: new Row(
            children: <Widget>[
              Container(width: 300, height: 60, color: Colors.green,),
              Container(width: 300, height: 60, color: Colors.red,)
              // ...
            ],
          ),
        ),
      ],
    );

列表

subjectColumnImage() {
    List images = data.subjects.map((f) => Column(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 8.0),
          child: Image.network(f.pic, height: 40, width: 40,),
        ),
        Text(f.title, style: TextStyle(fontSize: 11),)
      ],
    )).toList();
    return Center(
      child: Wrap( // 列表
        spacing: 40,
        children: images,
      ),
    );
  }

底部导航栏 navigation

效果见图

坑:放图片在目录下img/2.0x放了,img/没放会不显示

import 'package:flutter/material.dart';
import 'package:flutter_search_site/app/sq_color.dart';
import 'package:flutter_search_site/home/home_scene.dart';

class RootScene extends StatefulWidget {
  @override
  _RootSceneState createState() => _RootSceneState();
}

class _RootSceneState extends State<RootScene> {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        children: <Widget>[
          HomeScene(),
          HomeScene(),
          HomeScene(),
          HomeScene(),
        ],
        index: _currentIndex,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
              icon: bottomImage('img/ic_b1.png'),
              activeIcon: bottomImage('img/ic_b1_click.png'),
              title: Text('搜潮流')),
          BottomNavigationBarItem(
              icon: bottomImage('img/ic_b2.png'),
              activeIcon: bottomImage('img/ic_b2_click.png'),
              title: Text('设计师家园')),
          BottomNavigationBarItem(
              icon: bottomImage('img/ic_b3.png'),
              activeIcon: bottomImage('img/ic_b3_click.png'),
              title: Text('我的')),
          BottomNavigationBarItem(
              icon: bottomImage('img/ic_b4.png'),
              activeIcon: bottomImage('img/ic_b4_click.png'),
              title: Text(
                '联系我们',
                style: TextStyle(color: SQColor.gray), // 固定的颜色,点击后不变色
              )),
        ],
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
          });
        },
        type: BottomNavigationBarType.fixed,
        selectedFontSize: 12,
        unselectedItemColor: SQColor.gray,  // 未选中文字颜色
        selectedItemColor: SQColor.darkGray, // 选中文字颜色
      ),
    );
  }

  bottomImage(String imgSrc) {
    return Padding(
      padding: EdgeInsets.only(bottom: 4),
      child: Image.asset(imgSrc, width: 24, height: 24),
    );
  }
}

页面间跳转

class VideoPlayScene extends StatefulWidget {
  final String url;
  
  VideoPlayScene(this.url);

  // 打开新页面
  static push(BuildContext context, String url){ 
    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return VideoPlayScene(url);
    }));   
  }
  
  @override
  _VideoPlaySceneState createState() => _VideoPlaySceneState();
}

关闭页面

Navigator.pop(context);

状态栏 statusBar

statusBar() {
    SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(
      // 设置状态栏背景色透明
      statusBarColor: Colors.transparent,
      // 设置状态栏图标是黑的
      statusBarIconBrightness: Brightness.dark,
    );
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  }

文字圆角背景

searchView() {
    return Container(
      margin: EdgeInsets.only(left: 16, right: 16),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(32),  // 圆弧的大小
        color: SQColor.lightGray,   //  圆弧的颜色
      ),
      height: 32,
      child: FlatButton(
        onPressed: search,
        child: Text(
          '搜索"街拍"关键字',
          style: TextStyle(fontSize: 12, color: SQColor.gray),
        ),
      ),
    );
  }

圆弧线

Container(
          decoration: BoxDecoration(
            border: Border.all(color: SQColor.darkGray, width: 0.5),
            borderRadius: BorderRadius.circular(20)
          ),
          padding: EdgeInsets.fromLTRB(10, 4, 8, 6),
          child: Row(
            children: <Widget>[
              Image.asset('img/ic_thumb.png'),
              Text("  赞${data.praiseNum}"),
            ],
          ),
        )

图片

加载网络图片

Image.network(url, fit: BoxFit.cover,)

缓存网络图片

cached_network_image: ^0.8.0

return Image(
        image: CachedNetworkImageProvider(images[0]),
        width: 300,
        fit: BoxFit.cover,
      );

轮播图 圆角图片

carousel_slider: ^1.3.0

return Container(
      margin: EdgeInsets.symmetric(vertical: 8),
      child: CarouselSlider(
        viewportFraction: 1.0,
        aspectRatio: 328 / 200, // 指定高,无效
        autoPlayInterval: Duration(seconds: 5),
        autoPlay: true,
        items: lamps.map((info) {
          return Builder(
            builder: (BuildContext context) {
              return Container(
                width: 328,
                decoration: BoxDecoration(  // 圆角图片
                  borderRadius: BorderRadius.circular(32), // 圆弧的大小
                  color: getColor(), //  圆弧的颜色
                  image: DecorationImage(fit: BoxFit.cover, image: NetworkImage(info.pic == "" ? info.videoPic : info.pic),)
                ),
              );
            },
          );
        }).toList(),
      ),
    );

混合图片和文字

searchView() {
    return Container(
        margin: EdgeInsets.only(left: 16, right: 16),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(32), // 圆弧的大小
          color: SQColor.lightGray, //  圆弧的颜色
        ),
        height: 32, // 设置大小
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 间隙样式
          children: <Widget>[
            FlatButton(
              onPressed: search,
              child: Text(
                '    搜索"街拍"关键字',  // 文字 文字用‘ ’的多少来控制和图片的间隙
                style: TextStyle(fontSize: 12, color: SQColor.gray),
              ),
            ),
            Image.asset('img/ic_search.png') // 图片
          ],
        ));
  }

分割线

Divider(height: 16,)

网络请求

json 解析成 dart 对象 javiercbk.github.io/json_to_dar… json ]}的前一个属性结尾没有, 属性中 “《img src=“”>”有""解析不出来

"video_url":null, 这种要判断类型,dart 中 null 是对象

if (json['video_url'] is String) {
      videoUrl = json['video_url'];
    }

列表

垂直列表嵌套水平列表

listView 中

shrinkWrap: true, //解决无限高度问题
physics:NeverScrollableScrollPhysics(),//禁用滑动事件
listViewHorizontalView() {   // 垂直列表中的一个child
    return Container(
      margin: EdgeInsets.symmetric(vertical: 20.0),
      height: 200.0,      // 必须指定高度
      child: ListView(  // list view 外层要指定高度,不然会报没有指定高度的错误
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          Container(
            width: 160.0,
            color: Colors.red,
          ),
          Container(
            width: 160.0,
            color: Colors.blue,
          ),
          Container(
            width: 160.0,
            color: Colors.green,
          ),
          Container(
            width: 160.0,
            color: Colors.yellow,
          ),
          Container(
            width: 160.0,
            color: Colors.orange,
          ),
        ],
      ),
    );
  }

进度条 slider

return Container(child: Slider(
      value: progressValue,
      onChanged: (double value) {   // 在滑动中
        setState(() {
          progressValue = value;
        });
      },
      onChangeEnd: (double value) {  // 滑动停止

      },
      activeColor: SQColor.primary, // 颜色
      inactiveColor: SQColor.gray,  
    ),);

位置 重叠布局

文字折叠在点图片上

hotspotLeftText() {
    return Stack(
        children: <Widget>[
          Positioned(
            left: 12,
            top: 8,
            child: Opacity(opacity: 0.8, child: Image.asset('img/ic_red_point.png')),
          ),
          Container(
            child: Text(
              "热点\n精选",
              style: TextStyle(fontStyle: FontStyle.italic),
            ),
          ),
        ],
      );
  }

混合开发

static const platform = const MethodChannel('android_log');
// .invokeMethod 源码上有demo 包括Android和iOS
logD(dynamic data) => platform.invokeMethod('logD', {"msg": data});