Skip to content

Instantly share code, notes, and snippets.

@hardy716
Created January 31, 2024 21:25
Show Gist options
  • Save hardy716/dfc6f8bd09dfa34227e824caf99fd863 to your computer and use it in GitHub Desktop.
Save hardy716/dfc6f8bd09dfa34227e824caf99fd863 to your computer and use it in GitHub Desktop.
플러터챌린지 8일차 기본문제 - 신현호
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; // v1.1.0
void main() {
runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: HelloHttpScreen(),
),
);
}
class HelloHttpScreen extends StatefulWidget {
const HelloHttpScreen({super.key});
@override
State<HelloHttpScreen> createState() => _HelloHttpScreenState();
}
class _HelloHttpScreenState extends State<HelloHttpScreen> {
final TextEditingController _controller = TextEditingController();
List<Character> _characters = [];
bool _isSearching = false;
bool _isLoading = false;
bool _isError = false;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<void> searchCharacters(String value) async {
setState(() {
_isSearching = true;
_isLoading = true;
_isError = false;
});
try {
final response = await http.get(
Uri.parse('https://swapi.dev/api/people/?search=$value'),
);
if (response.statusCode == 200) {
final data = json.decode(response.body) as Map<String, dynamic>;
setState(() {
_characters = (data['results'] as List)
.map((characterData) => Character.fromJson(characterData))
.toList();
});
} else {
setState(() {
_isError = true;
});
}
} catch (error) {
setState(() {
_isError = true;
});
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
controller: _controller,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search, color: Theme.of(context).colorScheme.primary),
hintText: 'Enter the name of a Star Wars character here!',
suffix: ElevatedButton(
child: const Text('Search!'),
onPressed: () => searchCharacters(_controller.text),
),
),
),
),
body: SafeArea(
child: _isLoading
? const Center(child: Text('Loading...'))
: _isError
? const Center(child: Text('Error occurred!'))
: _characters.isEmpty
? Center(child: _isSearching
? const Text('No results found, please try again with a different search term!')
: null
)
: ListView.builder(
itemCount: _characters.length,
itemBuilder: (BuildContext context, int index) {
return _CharacterWidget(character: _characters[index]);
},
),
),
);
}
}
class _CharacterWidget extends StatelessWidget {
final Character character;
const _CharacterWidget({required this.character});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(width: 2, color: Colors.black),
color: Theme.of(context).colorScheme.primaryContainer,
),
child: Column(
children: [
Text(
character.name,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Colors.black),
),
const SizedBox(height: 5),
Text('${character.height}/${character.mass}',),
const SizedBox(height: 5),
Text('Hair Color: ${character.hairColor} | Skin Color: ${character.skinColor}'),
],
),
),
);
}
}
class Character {
final String name;
final String? height;
final String? mass;
final String? hairColor;
final String? skinColor;
final String? eyeColor;
final String? birthYear;
final String? gender;
final String? homeworld;
final List<String>? films;
final List<String>? vehicles;
final List<String>? starships;
final String? created;
final String? edited;
final String? url;
Character({
required this.name,
this.height,
this.mass,
this.hairColor,
this.skinColor,
this.eyeColor,
this.birthYear,
this.gender,
this.homeworld,
this.films,
this.vehicles,
this.starships,
this.created,
this.edited,
this.url,
});
factory Character.fromJson(Map<String, dynamic> json) => Character(
name: json['name'] ?? '',
height: json['height'],
mass: json['mass'],
hairColor: json['hair_color'],
skinColor: json['skin_color'],
eyeColor: json['eye_color'],
birthYear: json['birth_year'],
gender: json['gender'],
homeworld: json['homeworld'],
films: List<String>.from(json['films'] ?? []),
vehicles: List<String>.from(json['vehicles'] ?? []),
starships: List<String>.from(json['starships'] ?? []),
created: json['created'],
edited: json['edited'],
url: json['url'],
);
Map<String, dynamic> toJson() => {
'name': name,
'height': height,
'mass': mass,
'hair_color': hairColor,
'skin_color': skinColor,
'eye_color': eyeColor,
'birth_year': birthYear,
'gender': gender,
'homeworld': homeworld,
'films': films,
'vehicles': vehicles,
'starships': starships,
'created': created,
'edited': edited,
'url': url,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment