Я создаю пустяковую игру с API opentdb. Но когда я получаю данные из API, между словами, такими как "" "или" # 039 ", появляются случайные символы. Я не знаю, почему они есть, и даже если я введу ссылку в браузере, странные символы Теперь я хотел бы знать, что я делаю что-то не так или есть проблема с API opentdb. Это ссылка на opentdb, которую я использую: https://opentdb.com/api.php?amount=20
Это это сценарий, который я использую для сортировки данных:
class Quiz {
int responseCode;
List<Results> results;
Quiz({this.responseCode, this.results});
Quiz.fromJson(Map<String, dynamic> json) {
responseCode = json['response_code'];
if (json['results'] != null) {
results = new List<Results>();
json['results'].forEach((v) {
results.add(new Results.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['response_code'] = this.responseCode;
if (this.results != null) {
data['results'] = this.results.map((v) => v.toJson()).toList();
}
return data;
}
}
class Results {
String category;
String type;
String difficulty;
String question;
String correctAnswer;
List<String> allAnswers;
Results(
{this.category,
this.type,
this.difficulty,
this.question,
this.correctAnswer,
this.allAnswers});
Results.fromJson(Map<String, dynamic> json) {
category = json['category'];
type = json['type'];
difficulty = json['difficulty'];
question = json['question'];
correctAnswer = json['correct_answer'];
allAnswers = json['incorrect_answers'].cast<String>();
allAnswers.add(correctAnswer);
allAnswers.shuffle();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['category'] = this.category;
data['type'] = this.type;
data['difficulty'] = this.difficulty;
data['question'] = this.question;
data['correct_answer'] = this.correctAnswer;
data['incorrect_answers'] = this.allAnswers;
return data;
}
}
И это мой основной сценарий:
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:trivia_test/quiz.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Colors.white),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Quiz quiz;
List<Results> results;
Future<void> fetchQuestions()async{
var res = await http.get("https://opentdb.com/api.php?amount=20");
var decRes = json.decode(res.body);
print(decRes);
quiz = Quiz.fromJson(decRes);
results = quiz.results;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("Quiz App", style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold, fontFamily: 'product_sans'),),
elevation: 0.0,
),
body: RefreshIndicator(
onRefresh: fetchQuestions,
child: FutureBuilder(
future: fetchQuestions(),
builder: (BuildContext context, AsyncSnapshot snapshot){
switch(snapshot.connectionState){
case ConnectionState.none:
return Text("Press button to start.");
case ConnectionState.active:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.done:
if(snapshot.hasError) return errorData(snapshot);
return questionList();
}
return null;
},
),
),
);
}
Padding errorData(AsyncSnapshot snapshot){
return Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Error: ${snapshot.error}",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'product_sans',
fontSize: 16.0,
fontWeight: FontWeight.w400,
),
),
SizedBox(height: 20.0,),
RaisedButton(
onPressed: () {
fetchQuestions();
setState(() {});
},
child: Text(
"Try Again",
style: TextStyle(
fontFamily: 'product_sans',
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
)
],
),
);
}
ListView questionList(){
return ListView.builder(
itemCount: results.length,
itemBuilder: (context, index) => Card(
color: Colors.white,
elevation: 0.0,
child: ExpansionTile(
title: Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
results[index].question,
style: TextStyle(
fontSize: 18.0,
fontFamily: 'product_sans',
fontWeight: FontWeight.bold,
),
),
FittedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FilterChip(
backgroundColor: Colors.grey[100],
label: Text(results[index].category),
onSelected: (b) {},
),
SizedBox(
width: 10.0,
),
FilterChip(
backgroundColor: Colors.grey[100],
label: Text(results[index].difficulty),
onSelected: (b) {},
),
],
),
)
],
),
),
leading: CircleAvatar(
backgroundColor: Colors.grey[100],
child: Text(results[index].type.startsWith("m") ? "M" : "B"),
),
children: results[index].allAnswers.map((m){
return AnswerWidget(results, index, m);
}).toList(),
),
),
);
}
}
class AnswerWidget extends StatefulWidget {
final List<Results> results;
final int index;
final String m;
AnswerWidget(this.results, this.index, this.m);
@override
_AnswerWidgetState createState() => _AnswerWidgetState();
}
class _AnswerWidgetState extends State<AnswerWidget> {
Color c = Colors.black;
@override
Widget build(BuildContext context) {
return ListTile(
onTap: () {
setState(() {
if(widget.m == widget.results[widget.index].correctAnswer){
c = Colors.green;
}
else{
c = Colors.red;
}
});
},
title: Text(
widget.m,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'product_sans',
color: c,
fontWeight: FontWeight.bold,
),
),
);
}
}
Это пример вывода, который я получаю, когда ввожу ссылку в Firefox:
response_code 0
results
0
category "Science: Mathematics"
type "multiple"
difficulty "easy"
question "How is the number 9 represented as a binary number?"
correct_answer "1001"
incorrect_answers
0 "1000"
1 "1110"
2 "1010"
1
category "Entertainment: Music"
type "boolean"
difficulty "medium"
question "Rapper Snoop Dogg's real name is 'Cordozar Calvin Broadus, Jr.'."
correct_answer "True"
incorrect_answers
0 "False"
2
category "Entertainment: Video Games"
type "multiple"
difficulty "easy"
question "What is the protagonist's title given by the demons in DOOM (2016)?"
correct_answer "Doom Slayer"
incorrect_answers
0 "Doom Guy"
1 "Doom Marine"
2 "Doom Reaper"
3
category "Science: Computers"
type "boolean"
difficulty "hard"
question "DHCP stands for Dynamic Host Configuration Port."
correct_answer "False"
incorrect_answers
0 "True"
4
category "Entertainment: Board Games"
type "multiple"
difficulty "hard"
question "In standard Monopoly, what's the rent if you land on Park Place with no houses?"
correct_answer "$35"
incorrect_answers
0 "$30"
1 "$50"
2 "$45"
5
category "General Knowledge"
type "multiple"
difficulty "medium"
question "When was Nintendo founded?"
correct_answer "September 23rd, 1889"
incorrect_answers
0 "October 19th, 1891"
1 "March 4th, 1887"
2 "December 27th, 1894"
6
category "General Knowledge"
type "multiple"
difficulty "medium"
question "Which iconic Disneyland attraction was closed in 2017 to be remodeled as a "Guardians of the Galaxy" themed ride?"
correct_answer "Twilight Zone Tower of Terror"
incorrect_answers
0 "The Haunted Mansion"
1 "Pirates of the Caribbean"
2 "Peter Pan's Flight"
7
category "Entertainment: Video Games"
type "multiple"
difficulty "medium"
question "What was the #1 selling game on Steam by revenue in 2016?"
correct_answer "Sid Meier's Civilization VI"
incorrect_answers
0 "Grand Theft Auto V"
1 "Counter Strike: Global Offensive"
2 "Dark Souls III"
8
category "Entertainment: Video Games"
type "multiple"
difficulty "easy"
question "In "Call Of Duty: Zombies", what is the name of the machine that upgrades weapons?"
correct_answer "Pack-A-Punch"
incorrect_answers
0 "Wunderfizz"
1 "Gersch Device"
2 "Mule Kick"
9
category "General Knowledge"
type "multiple"
difficulty "medium"
question "Earl Grey tea is black tea flavoured with what?"
correct_answer "Bergamot oil"
incorrect_answers
0 "Lavender"
1 "Vanilla"
2 "Honey"