Flutter网络请求前的页面展示

本文介绍了在Flutter中处理异步请求时遇到的问题,如网络延迟导致的数据延迟加载。通过模拟服务端延迟响应,展示了客户端如何在数据未返回时显示“登录中”状态,以及如何通过返回特定User对象来判断登录失败。在客户端,当接收到User对象后,根据用户名和密码判断登录成功或失败,并相应地更新UI。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、问题的提出

Flutter在进行异步请求的时候,很多时候因为网络阻塞等问题,会导致我们的数据可能几秒后才能获取到,但这几秒时间内,我们的页面怎么展示???

2、问题的解决

2.1、服务端的编写

我们使用SpringBoot搭建一个简易的请求

在这里插入图片描述

可以看到,故意将线程阻塞了2秒,用于模拟网络请求拥堵情况。

package com.example.login.controller;
import com.example.login.entity.User;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/login/{username}/{password}")
    public User Login(@PathVariable("username")String username,@PathVariable("password")String password){
        try {
            //睡2秒
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("username = " + username + ", password = " + password);
        if("qykhhr".equals(username) && "123456".equals(password)){
            //如果用户名和密码正确,返回一个User对象
            User user = new User(username, password);
            return user;
        }
        //如果用户名和密码错误,返回null
        return null;
    }
}

2.2、客户端的编写

import 'dart:convert';

import 'package:async_wait_test/User.dart';
import 'package:async_wait_test/test.dart';
import 'package:async_wait_test/test/widget/loading.dart';
import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  String username = "";
  String password = "";

  User user;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text("异步请求测试"),
      ),
      body: Center(
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                hintText: "请输入用户名",
                hintMaxLines: 1,
                labelText: "用户名",
              ),
              onChanged: (value){
                setState(() {
                  username = value;
                  print("usernmae = $username");
                });
              },
            ),
            TextField(
              decoration: InputDecoration(
                hintText: "请输入密码",
                hintMaxLines: 1,
                labelText: "密码",
              ),
              onChanged: (value){
                setState(() {
                  password = value;
                  print("password = $password");
                });
              },
            ),
            RaisedButton(
                child: Text("登录"),
                onPressed: () {
                  Navigator.of(context).push(
                    //跳转页面,传入数据
                      MaterialPageRoute(builder: (context)=>test(username,password))
                  );
            })
          ],
        ),
      )
    );
  }
}

test.dart

import 'dart:convert';

import 'package:async_wait_test/User.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class test extends StatefulWidget {
  String username;
  String password;
  test(this.username,this.password);
  @override
  _testState createState() => _testState();
}

class _testState extends State<test> {

  User user;

  //initState : 初始化widget的时候调用,只会调用一次。
 @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _getUser();
  }
  _getUser() async{
    var response = await http.post("http://192.168.63.1:8080/login/${widget.username}/${widget.password}");
    if(response.statusCode == 200){
      var body = response.body;
      var decode = json.decode(body);
      // user = User(decode['username'], decode['password']);
      setState(() {
        user = User(decode['username'], decode['password']);
      });
    }

  }

  //build : 初始化之后开始绘制界面,当setState触发的时候会再次被调用
  @override
  Widget build(BuildContext context) {
    // print("user = ${widget.user.username}");

    if(this.user == null){
      return Scaffold(
        appBar: AppBar(
          title: Text("登录中"),
        ),
        body: Center(
          child: CircularProgressIndicator(),
          // child: CupertinoActivityIndicator(),
        ),
      );
    }
    print("user = ${this.user.username}");
    print("user = ${this.user.password}");
    return Scaffold(
      appBar: AppBar(
        title: Text("登录成功"),
      ),
      body: Center(
        child: Column(
            children: [
              Text("${this.user.username}"),
              Text("${this.user.password}"),
            ]
        ),
      ),
    );

  }
}

先对user对象进行判断,由于网络阻塞,刚开始的user是空值,所以页面显示登录中,当setState被调用的时候,user已经被赋值了,并且重新加载build,由于user不为空所以显示数据。

在这里插入图片描述

3、出现问题

但是有一个问题,因为我们这是一个登录功能,如何判断用户登录失败呢???

我采用的方法是:

如果用户名和密码不对,就返回一个User("error","error")对象,它的用户名和密码都是error。

@PostMapping("/login/{username}/{password}")
public User Login(@PathVariable("username")String username,@PathVariable("password")String password){
    try {
        //睡2秒
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("username = " + username + ", password = " + password);
    if("qykhhr".equals(username) && "123456".equals(password)){
        //如果用户名和密码正确,返回一个User对象
        User user = new User(username, password);
        return user;
    }
    //如果用户名和密码错误,返回null
    return new User("error","error");
}

在Flutter判断用户名和密码是否都是"error",如果是那就是登录失败,否则就是登录成功。

if(this.user == null){
  return Scaffold(
    appBar: AppBar(
      title: Text("登录中"),
    ),
    body: LoadingWidget()
  );
}else if(this.user.password == "error" && this.user.username == "error"){
  return Scaffold(
    appBar: AppBar(
      title: Text("登录失败"),
    ),
    body: RaisedButton(
      child: Text("登录失败/(ㄒoㄒ)/~~,点击返回"),
      onPressed: (){
        Navigator.of(context).pop();
      },
    ),
  );
}else{
  print("user = ${this.user.username}");
  print("user = ${this.user.password}");
  return Scaffold(
    appBar: AppBar(
      title: Text("登录成功"),
    ),
    body: Center(
      child: Column(
          children: [
            Text("${this.user.username}"),
            Text("${this.user.password}"),
          ]
      ),
    ),
  );

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值