Flutter 网络请求类封装及搜索框实现

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

Flutter 中定时器的使用

Timer? _timer;
int _count = 0;

@override
  void initState() {
    super.initState();
    //创建定时器
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      //定时器回调
      _count ++;
    });
 }

@override
  void dispose() {
    if (null != _timer && (_timer?.isActive ?? false)) {
      //销毁定时器
      _timer?.cancel();
    }
    super.dispose();
    print('页面销毁了!');
  }

复制代码

Flutter 中定时器相对 iOS 来说比较好的一点就是定时器事件的执行不会受视图拖拽的影响,不涉及到模式。但是需要注意一点的是在页面离开的时候要对定时器进行销毁。

网络请求类封装

开始的时候我们是在页面中直接使用三方框架 http 进行网络的请求,这里不好的一点就是如果将来我们更换了网络请求框架的话,项目中涉及到网络的请求的地方都需要改动,对项目的影响会比较大。所以这里我们自己封装了一个网络请求类,定义自己的网络请求方法,即使将来更换三方框架的话,我们只需要在我们自己网络请求类里面更换就好,项目的其他地方不用改动。对网络请求进行封装,相信不管是 iOS 项目还是安卓项目肯定也都是这样做的。

enum HttpMethod {
  GET,
  POST
}

class HttpManager {
  //创建 Dio 单例对象
  static Dio? _dioInstance;
  static Dio? _getDioInstance() {
    if (null == _dioInstance) {
      _dioInstance = Dio();
    }
    return _dioInstance;
  }

  static Future<Response> get(String url, {Map<String, dynamic>? queryParameters}) async {
    return await _sendRequest(HttpMethod.GET, url, queryParameters: queryParameters);
  }

  static Future<Response> post(String url, {Map<String, dynamic>? queryParameters, dynamic data}) async {
    return await _sendRequest(HttpMethod.GET, url, queryParameters: queryParameters, data: data);
  }

  static Future _sendRequest(HttpMethod method, String url, {Map<String, dynamic>? queryParameters, dynamic data}) async {
    try {
      switch(method) {
        case HttpMethod.GET:
          return await HttpManager._getDioInstance()?.get(url, queryParameters: queryParameters);
        case HttpMethod.POST:
          return await HttpManager._getDioInstance()?.post(url, queryParameters: queryParameters, data: data);
        default:
          throw Exception('请求方式错误');
      }
    } on DioError catch(e) {
      print(e.message);
    } on Exception catch(e) {
      print(e.toString());
    }
    return null;
  }
}
复制代码

这里我们是基于 Dio 这个三方框架进行封装的,在 HttpManager 类中我们定义了 Dio 的单例对象 _dioInstance,通过单例方法 _getDioInstance 来获取单例对象。我们定义了 postget 两个静态方法,在这两个方法中我们都调用了私有方法 _sendRequest_sendRequest 方法中通过该传入的枚举参数 HttpMethod 来区分 Dio 单例对象是调用 get 还是 post 请求。这里需要注意的是方法中一定要使用 async,返回值前要加 await

聊天列表搜索框实现

image.png

class SearchCell extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: (){
        print('点击了搜索框');
      },
      child: Container(
        height: 45,
        color: CahtThemColor,
        padding: EdgeInsets.all(5),
        child: Stack(
          alignment: Alignment.center,
          children: [
            Container(
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(6.0),
              ),
            ), //白色底视图
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Image(image: AssetImage('images/放大镜b.png'), width: 15, color: Colors.grey,),
                Text('  搜索  ', style: TextStyle(fontSize: 15, color: Colors.grey),),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
复制代码

在聊天页面中我们可以看到顶部的搜索框,这个搜索框是跟列表一起滚动的,所以比较好的实现方式就是把搜索框定义为一个 cell。其实这个搜索框只有点击事件,点击之后跳转一个新的页面,所以我们只需要使用小部件来实现搜索框的展示就好。搜索框由白色底视图跟图片和文本组成,所以这里我们通过 Stack 部件来实现,children 的第一个元素为白色底视图,图片跟搜索文字用 Row 部件来实现,图片跟文字布局左右排列。

Guess you like

Origin juejin.im/post/7034533494135259144
Recommended