我如何将数据保存在共享首选项中并将其接收到颤振中的另一个页面

How can i save data in shared Preferences and receive it to another page in flutter

我试图在共享首选项中保存数据。当我使用 id 输入 api 并传递它时,它会给我令牌和 id。我在 sharedPreferences 中保存了我的令牌,但无法保存 userId。

但我想将我的令牌和用户 ID 发送到另一个名为 'lists.dart' 的页面,并希望 使用 userId 的条件,如 snackbar 或 toast 等,因此 userId 和 token 必须需要保存在共享首选项中,并将在另一个页面中用于获取数据。怎么做?

这是api回复。

{token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5Nzc4NTI3LCJleHAiOjE2Mjk4NjQ5MjcsIm5iZiI6MTYyOTc3ODUyNywianRpIjoiM25Xbkl3UVFGNE1YSWZVVCJ9.Q9dxnu-WWHA2p8n0oSEamLXDOPqdzsemnrlHHfiuV7o, message: success, userId: 2899, passwordChanged: yes}

这是Api请求

Future<Album> createAlbum(String employee_custom_id, String password) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    final response = await http.post(
      Uri.parse('https://portal-api.jomakhata.com/api/auth/login'),
      headers: <String, String>{
        'Content-Type': 'application/json',
      },
      body: jsonEncode(<String, String>{
        'employee_custom_id': 1002899,
        'password': 000000,
      }),
    );

    final data = json.decode(response.body);
    if (response.statusCode == 200) {
      sharedPreferences.setString("token", data['token']);
      sharedPreferences.setInt("userId", data['userId']);

      log('$data');
      // print(id);

      return Album.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to create album.');
    }
}

这是完整代码

class _LoginPageState extends State<LoginPage> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  bool _validate = false;
  int charLength = 0;
  bool _status = false;

  _onChanged(String value) {
    setState(() {
      charLength = value.length;
    });

    if (charLength >= 4) {
      setState(() {
        _status = true;
      });
    } else {
      setState(() {
        _status = false;
      });
    }
  }

  Future<Album>? _futureAlbum;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery
        .of(context)
        .size;
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Portal',
      home: Scaffold(
        body: Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.all(8.0),
          child: buildColumn(),
        ),
      ),
    );
  }

  Column buildColumn() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[

        TextField(
          controller: _emailController,
          keyboardType: TextInputType.text,
          autofocus: true,
          onChanged: _onChanged,
          decoration: InputDecoration(
            hintText: 'Email or ID',
            hintStyle: TextStyle(color: Colors.grey),
            filled: true,
            fillColor: Colors.white70,
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(12.0)),
              borderSide: BorderSide(color: Colors.purpleAccent, width: 2),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
              borderSide: BorderSide(color: Colors.purpleAccent),
            ),

            prefixIcon: Icon(Icons.email),
          ),
        ),
        SizedBox(
          height: 20,
        ),
        TextField(
          controller: _passwordController,
          keyboardType: TextInputType.visiblePassword,
          autofocus: false,
          obscureText: false,
          decoration: InputDecoration(
            hintText: 'Password',
            hintStyle: TextStyle(color: Colors.grey),
            filled: true,
            fillColor: Colors.white70,
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(12.0)),
              borderSide: BorderSide(color: Colors.purpleAccent, width: 2),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
              borderSide: BorderSide(color: Colors.purpleAccent),
            ),
            prefixIcon: Icon(Icons.lock),
            suffixIcon: Icon(Icons.visibility_off),
          ),
        ),
        SizedBox(
          height: 20,
        ),
        Visibility(
          maintainSize: true,
          maintainAnimation: true,
          maintainState: true,
          visible: _status,
          child: Container(
              margin: EdgeInsets.only(top: 20),
              child: Center(
                child: RaisedButton(
                  child: Text('Login'),
                  onPressed: () {
                    setState(() {
                      // in this position i want to make snackbar by using if-else condition with checking userId
                 
                      _futureAlbum =
                          createAlbum(_emailController.text, _passwordController.text);
                    });
                  },
                  color: Colors.green,
                  textColor: Colors.white,
                  padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
                ),
              )
          ),
        )
      ],
    );
  }

  Future<Album> createAlbum(String employee_custom_id, String password) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    final response = await http.post(
      Uri.parse('https://portal-api.jomakhata.com/api/auth/login'),
      headers: <String, String>{
        'Content-Type': 'application/json',
      },
      body: jsonEncode(<String, String>{
        'employee_custom_id': employee_custom_id,  //1002899
        'password': password,  000000
      }),
    );


    final data = json.decode(response.body);
    if (response.statusCode == 200) {
      sharedPreferences.setString("token", data['token']);
      sharedPreferences.setInt("userId", data['userId']);


      log('$data');
      // print(id);

      return Album.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to create album.');
    }
  }
}

class Album {
  final int id;
  final String employee_custom_id;
  final String password;

  Album({required this.id,
    required this.employee_custom_id,
    required this.password});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'],
      employee_custom_id: json['title'],
      password: json['password'],
    );
  }
}

现在我想在我的 lists.dart 页面中收到 'token' 和 'userId'。

Future<List<ListAlbum>> listData() async {

  final token = // token that i want to receiv from login page here.
  String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    // sharedPreferences.setString("token", response.data['token']);

    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();

  } else {
    throw Exception('Failed!');
  }
}

sharedPreferences.setString()sharedPreferences.setInt() 是期货。由于您没有使用 await,函数正在执行,但您没有等待它完成。

试试这个:

await sharedPreferences.setString("token", data['token']);
await sharedPreferences.setInt("userId", data['userId']);

为 sharedprefrence

创建一个 Class
class SharedPrefrence {
  Future<bool> setToken(String token) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.setString("token", token);
  }

  Future<String> getToken() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString("token") ?? '';
  }
}

保存来自api

的令牌数据
extract api response and pass to setToken function

 Map<String, dynamic> value = json.decode(response.body);

 SharedPrefrence().setToken(value['token']);

要从另一个页面或函数访问令牌,请使用如下方式,您可以将变量创建为全局变量并在 initState 中调用 getToken 函数并将令牌变量用于 api 或在您的 [=26= 中使用 Future 代码]代码

String token;
@override
  void initState() {
    super.initState();

    Future auth_token = SharedPrefrence().getToken();
    auth_token.then((data) async {
      token = data;
      
    });
  }

在api代码中使用

Future<List<ListAlbum>> listData() async {
final token;
   Future auth_token = SharedPrefrence().getToken();
    auth_token.then((data) async {
      token = data;
      String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    // sharedPreferences.setString("token", response.data['token']);

    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();

  } else {
    throw Exception('Failed!');
  }
    });
  
}