【Flutter开发App开发笔记】

Flutter BottomNavgiationBar Widget 底部导航栏 切换后状态丢失

static List contentOptions = [
    new IndexPage(),
    Text(
      'Index 1 场馆预定',
      style: optionsStyle,
    ),
    PersonCenterPage(),
];
 
 // contentOptions 是widget List
  
方式一
body: Center(
    child: contentOptions.elementAt(_selectedIndex)
),
这种方式切换后会状态丢失

方式二
body:IndexedStack(
    index:_selectedIndex,
    children:contentOptions
)
这种方式切换后不会丢失状态

加了图片资源一定要记得去pubspec.yaml文件添加配置

  assets:
   - images/type1.png
   - images/type2.png
   - images/type3.png
   - images/banner.png
   

Json转Dart model类

1、新建实体类
import 'package:json_annotation/json_annotation.dart';

// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';

///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()

class User{
  User(this.name, this.email);

  String name;
  String email;
  //不同的类使用不同的mixin即可
  factory User.fromJson(Map json) => _$UserFromJson(json);
  Map toJson() => _$UserToJson(this);  
}
2、在根目录下运行命令生成文件
// 一次性生成
flutter packages pub run build_runner build

// 使用watcher可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并在需要时自动构建必要的文件。
// 只需启动一次观察器,然后它就会在后台运行,这是安全的。
flutter packages pub run build_runner watch
3、使用Dart models类
import 'package:hello/models/user.dart';

// 接口请求返回数据
Response response = await dio.get('https://api.apiopen.top/musicRankings');
// Json转Dart Model类
User user=User.fromJson(response.data);

复杂嵌套的JSON数据结构类型实例
import 'package:json_annotation/json_annotation.dart';

part 'musicRank.g.dart';

@JsonSerializable()
class MusicRank {
  List result;
  MusicRank(this.result);

  factory MusicRank.fromJson(Map  json) => _$MusicRankFromJson(json);
  Map  toJson()=>_$MusicRankToJson(this);
}

@JsonSerializable()
class Item {
  //@JsonKey 显式关联JSON字段名与Model属性的对应关系 
  @JsonKey(name:'bg_pic')
  String bgPic;
  String color;
  int count;
  int type;
  @JsonKey(name:'content')
  List content;

  Item(this.bgPic,this.color,this.count,this.type,this.content);

  factory Item.fromJson(Map  json)=>_$ItemFromJson(json);
  Map  toJson()=>_$ItemToJson(this);

  
}
@JsonSerializable()
class Content {
  @JsonKey(name:'song_id')
  String songId;
  @JsonKey(name:'rank_change')
  String rankChange;
  String author;
  String title;
  @JsonKey(name:'pic_big')
  String picBig;

  Content(this.songId,this.rankChange,this.author,this.title,this.picBig);

  factory Content.fromJson(Map  json)=>_$ContentFromJson(json);
  Map  toJson()=>_$ContentToJson(this);

}

Flutter踩坑之video_player无法在Android9及以上播放

问题原因

安卓上从9.0(API level28)开始,明文通信支持默认是被禁用的,官方说法是不安全。因为我们播放的视频源是http协议,所以无法播放。

解决方法

修改AndroidManifest.xml


    
    
        ...
    


// 在application上 加 android:usesCleartextTraffic="true"
// 加一个权限 

清空输入框报错

// 报错信息
════════ Exception caught by gesture ═════════
The following assertion was thrown while handling a gesture:
invalid text selection: TextSelection(baseOffset: 4, extentOffset: 4, affinity: TextAffinity.upstream, isDirectional: false)

When the exception was thrown, this was the stack
#0      TextEditingController.selection= 
package:flutter/…/widgets/editable_text.dart:193
#1      EditableTextState._handleSelectionChanged 
package:flutter/…/widgets/editable_text.dart:1507
#2      RenderEditable._handleSelectionChange 
package:flutter/…/rendering/editable.dart:417
#3      RenderEditable.selectPositionAt 
package:flutter/…/rendering/editable.dart:1568
#4      RenderEditable.selectPosition 
package:flutter/…/rendering/editable.dart:1539
...
Handler: "onTapUp"
Recognizer: _TransparentTapGestureRecognizer#49c3a
    debugOwner: _TextSelectionGestureDetectorState#0a503
    state: ready
    won arena
    finalPosition: Offset(313.6, 322.3)
    finalLocalPosition: Offset(293.6, 24.3)
    button: 1
    sent tap down
════════════════════════════════════════════════════════════════════════════════

关于此情况并大概就是在没有正常的取消输入框焦点的时候,就先清空输入框组件,整体渲染顺序是不正确的。

错误的做法:
我是直接调用controller取消输入框内容的方法,但是光标会聚集在此输入框,所以处理渲染生命周期是不可控制

TextEditingController _passwordController = new TextEditingController();

_passwordController.clear();

既然知道报错的大概方向,那么我们就控制build的生命周期插入指定时机才去运行方法即可

解决方法:

// 保证在组件build的第一帧时才去触发取消清空内容
WidgetsBinding.instance.addPostFrameCallback((_) => _passwordController.clear());

强制横/竖屏展示

在runApp()之前

// 强制横屏
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight
  ]);
  
  
   // 强制竖屏
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]);

附件预览的功能实现

在android上使用插件flutter_filereader: ^2.1.0
由于flutter_filereader这个插件基于腾讯的x5浏览器内核,所以ios是无法使用。
ios上需要使用原生插件WKWebview就行了。

数字正则


bool isNumber(value) {
    /// 不允许带+或者-的数字
    RegExp number = new RegExp(r"^\d+(\.\d+)?$|^$|^(\d+|\-){7,}$");
    /// 允许带+或者-的数字
    // RegExp number = new RegExp(r"^[+-]?\d+(\.\d+)?$|^$|^(\d+|\-){7,}$");
    return number.hasMatch(value);
  }

你可能感兴趣的:(flutter,android,前端)