Dans mon projet de flutter, je fais des appels d'API pour récupérer des données par demande d'obtenir. Après l'analyse de l'objet JSON Object De la réponse, je viens d'afficher la valeur dans le Texte widget. Bien que les données prennent du temps à charger, mes widgets de texte montrent que NULL.
Pour la section appelle à l'API, j'ai le code suivant-
class Webservice {
Future<T> load<T>(Resource<T> resource) async {
var jwt = await LocalStore().getJWT();
print(jwt);
final response = await http.get(resource.url,
headers: {
'Content-Type': 'application/json',
'token': '${Constants.TOKEN}',
'jwt': '$jwt',
}
);
if(response.statusCode == 200) {
print('${response.body}');
return resource.parse(response);
} else {
throw Exception('Failed to load data!');
}
}
}
J'ai fait un classe de modèle pour analyse JSON-
class Category {
int catNote;
int catTodo;
int catRem;
int catTag;
int catUrgent;
int catWork;
int catOffice;
int catPersonal;
Category(
{this.catNote,
this.catTodo,
this.catRem,
this.catTag,
this.catUrgent,
this.catWork,
this.catOffice,
this.catPersonal});
Category.fromJson(Map<String, dynamic> json) {
catNote = json['cat_note'];
catTodo = json['cat_todo'];
catRem = json['cat_rem'];
catTag = json['cat_tag'];
catUrgent = json['cat_urgent'];
catWork = json['cat_work'];
catOffice = json['cat_office'];
catPersonal = json['cat_personal'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['cat_note'] = this.catNote;
data['cat_todo'] = this.catTodo;
data['cat_rem'] = this.catRem;
data['cat_tag'] = this.catTag;
data['cat_urgent'] = this.catUrgent;
data['cat_work'] = this.catWork;
data['cat_office'] = this.catOffice;
data['cat_personal'] = this.catPersonal;
return data;
}
static Resource<Category> get allCategory {
return Resource(
url: '${Constants.BASE_URL}category',
parse: (response) {
print('my result ${response.body}');
final result = json.decode(response.body);
Category category = Category.fromJson(result) ;
return category;
}
);
}
}
Maintenant, dans ma classe principale, j'ai créé une seule fonction comme ci-dessous.
void _getAllCategories() {
Webservice().load(Category.allCategory).then((newsArticles) => {
setState(() => {
_category = newsArticles
})
});
}
Après cela, j'ai appelé la fonction à l'intérieur de la fonction InitiState et enregistré la valeur dans l'objet _category.
Ensuite, à l'intérieur du Construction du widget (Contexte de BuildContext) Fonction pour le widget de texte J'ai utilisé la valeur de _ catégorie objet comme ci-dessous à l'aide d'un opérateur ternaire pour vérifier si l'objet est nul ou pas. Si c'est NULL, il devrait indiquer 0 et s'il n'est pas null, il devrait indiquer la valeur d'origine.
child: _category ==null?
Text('0',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
):
Text('${_category.catToDo}',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
)
Mais il ressort toujours des morceaux nul prenant peu de secondes pour le chargement de données et les spectacles comme ci-dessous.
Donc, j'ai besoin d'une solution pour afficher une boîte de dialogue de progrès ou montrer simplement la valeur par défaut comme 0 pendant que les données prennent du temps à charger. Ce serait très bien si quelqu'un m'aide avec ce code.
Utiliser un futurbuilder pour contrôler le rendu pendant la période de charge;
final categories = Webservice().load(Category.allCategory);
Widget build(BuildContext context) {
return FutureBuilder(
future: categories,
builder: (ctx, snapshot) {
var value = (snapshot.connectionState == ConnectionState.done) ? '${_category.catToDo}' : '0';
return Text(
value,
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
);
}
);
}
Ou si vous souhaitez afficher une animation de chargement:
final categories = Webservice().load(Category.allCategory);
Widget build(BuildContext context) {
return FutureBuilder(
future: categories,
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Text(
'${_category.catToDo}',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
);
}
else {
return CircularProgressIndicator();
}
}
);
}
Vous pouvez vérifier Ceci Package pour afficher une rotation de chargement avec différents styles.
Après cela, vous devez utiliser Future Builder widget
Voici un exemple de la façon de l'utiliser avec le spinkit
FutureBuilder(
future: myAwesomeFutureMethod(), // you should put here your method that call your web service
builder:
(BuildContext context, AsyncSnapshot<List<BillResponse>> snapshot) {
/// The snapshot data type have to be same of the result of your web service method
if (snapshot.hasData) {
/// When the result of the future call respond and has data show that data
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: bodyData(snapshot.data),
);
}
/// While is no data show this
return Center(
child: SpinKitDualRing(
color: Colors.blue,
),
);
},
),
J'espère que cela pourrait aider. Acclamations.
Vous devez utiliser la classe FutureBuilder
pour le faire.
Cet exemple montre un FutureBuilder
qui affiche une fileuse de chargement pendant qu'elle charge des données. Il affiche une icône de succès et un texte si le futur complète avec un résultat, ou une icône d'erreur et un texte si le futur complète avec une erreur. Supposer le _calculation
Le champ est défini en appuyant sur un bouton ailleurs dans l'interface utilisateur.
Voici un exemple
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
Future<String> _calculation = Future<String>.delayed(
Duration(seconds: 2),
() => 'Data Loaded',
);
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.headline2,
textAlign: TextAlign.center,
child: FutureBuilder<String>(
future: _calculation, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
List<Widget> children;
if (snapshot.hasData) {
children = <Widget>[
Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Result: ${snapshot.data}'),
)
];
} else if (snapshot.hasError) {
children = <Widget>[
Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
)
];
} else {
children = <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
const Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
},
),
);
}
}