Флаттер. Добавьте значение json .decode в строку, которую можно использовать в пользовательском интерфейсе. - PullRequest
1 голос
/ 16 января 2020

Может быть, это простой вопрос, но я не могу найти ответ на него. Мое приложение имеет 2 экрана. 1-й имеет одну кнопку

onPressed: () {
      fetchCurrentTitle();
      Navigator.push(context,
          MaterialPageRoute(builder: (context) => Screen2Widget()));
    },

Метод fetchCurrentTitle () извлекает данные из json и декодирует их. Я могу увидеть ответ, используя:

final streamFullTitle = json.decode(response.body)['data'][0]['title'];
print(streamFullTitle);

Я получаю желаемый ответ текущего заголовка в консоли.

На втором экране у меня есть жестко закодированный список. Где элементы имеют следующие значения:

class List {
  String id;
  String streamer;
  String logoUrl;
  String title;
}

Первые три атрибута в классе List не нужно менять, поэтому они жестко закодированы. Мне просто нужно присвоить значение заголовка от fetchCurrentTitle() до String title. в классе List. Посмотрите на один из элементов моего списка

Мой fetchCurrentTitle () работает как задумано

Future<String> fetchCurrentTitle() async {
  http.Response response = await http.get(...

Я хочу, чтобы пользователь нажал кнопку sh на первом экране на go на второй экран и покажите счетчик с заголовком «ищу заголовок», а затем получите новый заголовок вместо ожидания fetchCurrentTitle () для завершения только входа на второй экран.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 16 января 2020
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sample_project_for_api/Employee.dart';

void main() => runApp(MaterialApp(
      title: "App",
      home: MyApp(),
    ));

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text('home page'),
      ),
      body: Center(
          child: Padding(
        padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
        child: RaisedButton(
            onPressed: () {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => SecondScreen()));
            },
            child: const Text('First Page')),
      )),
    );
  }
}

class SecondScreen extends StatefulWidget {
  @override
  _SecondScreenState createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  bool _isLoading = false;
  Employee sampleData;
  @override
  void initState() {
    super.initState();
    getYouData();
  }

  Future<String> loadPersonFromAssets() async {
    return await rootBundle.loadString('json/parse.json');
  }

  getYouData() async {
    setState(() {
      _isLoading = true;
    });

    String jsonString = await loadPersonFromAssets();
    final data = employeeFromJson(jsonString);
    sampleData = data;

    // this is where you get the data from the network

    Future.delayed(const Duration(seconds: 5), () {
      // this is sample delay for you to know the delay.
      // you can say this is loading your data

      setState(() {
        _isLoading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
          body: SafeArea(
                      child: Center(
                        child: Container(

        child: _isLoading
                //here give your message getting the title
                ? CircularProgressIndicator()
                : Card(
                    child: Column(
                      children: <Widget>[
                        Text('your 1st hardcoded text'),
                        Text('your 2st hardcoded text'),
                        Text('your 3st hardcoded text'),
                        Text(
                            'This is your dynamic data after fetching :${sampleData.employeeName}')
                      ],
                    ),
                  ),
      ),
            ),
          ),
    );
  }
}

в этом примере вы дадите представление о том, что делать

1) при переходе с одной страницы на другую

2) при загрузке ваших данных, когда отображается счетчик

3) при получении данных обновляет пользовательский интерфейс.

сообщите мне об этом.

Спасибо.

0 голосов
/ 16 января 2020

Попробуйте,

import 'dart:convert';

import "package:flutter/material.dart";
import 'package:http/http.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Page1(),
    );
  }
}

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Page 1")),
      body: Center(
        child: RaisedButton(
          child: Text("Goto Page2"),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => Page2(),
              ),
            );
          },
        ),
      ),
    );
  }
}

class Page2 extends StatefulWidget {
  @override
  _Page2State createState() => _Page2State();
}

class _Page2State extends State<Page2> {
  Future<void> _initLoader;
  String _title;

  @override
  void initState() {
    _initLoader = _loadInitData();
    super.initState();
  }

  Future<void> _loadInitData() async {
    await Future.delayed(Duration(seconds: 2));
    //_title = await fetchCurrentTitle();
    _title = "This is the Loaded Title";
  }

  Future<String> fetchCurrentTitle() async {
    Response response = await get("...");
    return json.decode(response.body)['data'][0]['title'];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Page 2")),
      body: FutureBuilder(
        future: _initLoader,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting)
            return Center(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  CircularProgressIndicator(),
                  const SizedBox(height: 8.0),
                  Text("Looking for Title"),
                ],
              ),
            );
          else if (snapshot.hasError)
            return Center(
              child: Text("Error: ${snapshot.error}"),
            );
          else
            return Center(
              child: Text("$_title"),
            );
        },
      ),
    );
  }
}
0 голосов
/ 16 января 2020

Вы можете попробовать запустить fetchCurrentTitle() во втором экране на

void initState() {
  super.initState();
  fetchCurrentTitle()
  /// show or set visibility for loading spinner
}

После того, как вы получите значение заголовка, вы можете просто назначить новый заголовок с помощью

List existingList = new List(id,streamer,logoUrl,title);
existingList.id = titleValueFromApi
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...