整理Flutter App开发过程中遇到的问题及解决方法

整理Flutter App开发过程中遇到的问题及解决方法

最近使用flutter开发一款app,因为是第一次接触flutter,在开发过程中遇到一些问题或常用的功能点,在此记录一下(持续更新…)

(1)禁止横屏

  • 在开发过程中,如果手机设置了自动旋转,手机横屏会使你当前开发的app也横向展示。有时候app横向展示的时候页面会出现布局错乱。此时我们可以禁止横屏展示。代码截图如下:
    禁止横屏

  • 在main.dart中添加如下代码:

        // An highlighted block
        //import   services.dart
        import 'package:flutter/services.dart';
        
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitUp, //只能纵向
          DeviceOrientation.portraitDown, //只能纵向
        ]);
    

(2)粘贴复制中文化

  • flutter 中复制粘贴显示出来默认的是英文(paste),修改为中文需要引入flutter_localizations,代码截图如下:

    复制粘贴等中文化

  • 在main.dart中添加如下代码

        // An highlighted block
        //import   flutter_localizations.dart
        import 'package:flutter_localizations/flutter_localizations.dart';
        
        localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            GlobalCupertinoLocalizations.delegate,
       ],
       supportedLocales: [
            const Locale('zh', 'CN'),
           const Locale('en', 'US'),
       ],
    

(3)修改状态栏的颜色

flutter app修改状态栏的颜色分为带有appbar和不带appbar2种情况。

  • 不带appbar的情况代码如下

        // An highlighted block
        return AnnotatedRegion <SystemUiOverlayStyle>(
          child: Scaffold(
            backgroundColor: Colors.white,
            body:Container()
          ),
          value: SystemUiOverlayStyle(
            //值可以根据需要修改
            statusBarColor: Colors.transparent
          ),
        )
    
  • 带有appbar的情况,需在appBar中添加 brightness: Brightness.light(值可以根据需要修改),代码如下:

      // An highlighted block
      return AnnotatedRegion <SystemUiOverlayStyle>(
        child: Scaffold(
          backgroundColor: Colors.white,
          appBar: AppBar(
            backgroundColor: Colors.white,
            brightness: Brightness.light,
            elevation: 0,  //去掉阴影
            centerTitle: true,
          ),
          body:Container()
        ),
        value: SystemUiOverlayStyle(
          //值可以根据需要修改
          statusBarColor: Colors.transparent
        ),
      )
    

(4)下拉刷新

下拉刷新的情况我们可以使用RefreshIndicator来实现,实现代码如下:

  	// An highlighted block
  	return Scaffold(
  	    backgroundColor: Colors.black,
  	    body:RefreshIndicator(
  	          //圆圈进度颜色
  	          color: Colors.blue,
  	          //下拉停止的距离
  	          displacement: 44.0,
  	          //背景颜色
  	          backgroundColor: Colors.grey[200],
  	          onRefresh: () async{
    
    
  	                //模拟网络请求
  	            await Future.delayed(Duration(milliseconds: 2000), () {
    
    
  	                  //TODO:具体的实现方法
  	            });
  	            //结束刷新
  	            return Future.value(true);
  	         }
  	    )
  	);

(5)setState更新数据,子控件数据不更新

  • 关于这个问题,我们拿上面的问题来举例,我的父组件中是遍历pageview的(仿抖音刷视频),当我下拉刷新时,我将数据倒序排列,发现,数据改变了,但是第一个页面的视频没有刷新,这时我们需要在子组件中添加didUpdateWidget来刷新当前页面,代码如下:
    在父组件中,我们在onRefresh方法中更新了_videoList 数组。我们的子组件是VideoPlayerMaskWidget
  	// An highlighted block
  	return Scaffold(
    backgroundColor: Colors.black,
    body: RefreshIndicator(
      //圆圈进度颜色
      color: Colors.blue,
      //下拉停止的距离
      displacement: 44.0,
      //背景颜色
      backgroundColor: Colors.grey[200],
      onRefresh: () async {
    
    
        //模拟网络请求
        await Future.delayed(Duration(milliseconds: 2000), () {
    
    
          //TODO:具体的实现方法
          //_videoList[0]['player'].pause();
          List _list = [];
          _list.addAll(_videoList.reversed);
          if (_list.isNotEmpty) {
    
    
            //我们更新了_videoList
            setState(() {
    
    
              _videoList = _list;
            });
          }
        });
        //结束刷新
        return Future.value(true);
      },
      child: _videoList.isNotEmpty
          ? PageView.builder(
              scrollDirection: Axis.vertical,
              controller: _pageController,
              itemBuilder: (context, index) {
    
    
                Widget _player = Container(
                  child: FijkView(
                    width: ScreenAdapter.setWidth(750),
                    height: ScreenAdapter.setHeight(1200),
                    player: _videoList[index]['player'],
                    fit: FijkFit(
                      sizeFactor: -0.1,
                      aspectRatio: 0.55,
                      alignment: Alignment.center,
                    ),
                    color: Colors.black,
                  ),
                );
                return VideoPlayerMaskWidget(
                  player: _player, //播放器
                  videoModel: _videoList[index],
                );
              },
              itemCount: _videoList.length,
              onPageChanged: (index) {
    
    
                //TODO:pageview  翻页
              },
            )
          : Container(),
    ),
  );
此时在我们的子组件中视频的地址虽然更新了,但是界面播放的还是原来的视频,这时,在我们的子组件(VideoPlayerMaskWidget)中需要添加didUpdateWidget来进行刷新子组件的值。代码如下:
 	// An highlighted block
 	@override
 	didUpdateWidget(VideoPlayerMaskWidget oldWidget){
    
    
 	      //给 _videoModel 重新赋值
 	       _videoModel = widget.videoModel;
 	}

(6)瀑布流布局的实现

现在很多的app都趋向于瀑布流式的布局,下面我们介绍利用flutter_staggered_grid_view组件来实现瀑布流布局。组件详细的api可以在https://pub.flutter-io.cn/packages/flutter_staggered_grid_view中查看。

  • 首先在pubspec.yaml文件中引入组件
  // An highlighted block
  flutter_staggered_grid_view: ^0.6.1

在需要使用的页面import 组件,代码如下:

  // An highlighted block
 import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
@override
Widget build(BuildContext context) {
    
    
  var cardWidth = (screenwidth - ScreenAdapter.setWidth(30)) / 2;
  return StaggeredGrid.count(
    crossAxisCount: 2,  //总共多少列
    mainAxisSpacing: 10,//主轴间距
    crossAxisSpacing: 10,//纵轴间距
    //_list是你需要展示的数据
    children: _list.map((item) {
    
    
      return InkWell(
        onTap: () {
    
    
          //TODO:点击事件
        },
        child: Container(),
      );
    }).toList(),
  );
}
}

(7)倒计时

flutter中实现倒计时代码如下:

  int _countDown = 5;
  Timer? _countDownTimer = null;
  int _seconds = 5;
  
  // 页面销毁
  
  dispose() {
    
    
    super.dispose();
    _countDownTimer?.cancel();
    _countDownTimer = null;
  }

  //倒计时
  void _setCountDown() {
    
    
    setState(() {
    
    
      if (_countDownTimer != null) {
    
    
        return;
      }
      _seconds = _countDown;
      _countDownTimer = Timer.periodic(Duration(seconds: 1), (timer) {
    
    
        setState(() {
    
    
          if (_countDown > 0) {
    
    
            _seconds = _countDown--;
          } else {
    
    
           //TODO:业务代码
            _countDownTimer!.cancel();
            _countDownTimer = null;
          }
        });
      });
    });
  }

猜你喜欢

转载自blog.csdn.net/yuwenwenwenwenyu/article/details/123903416