Aplikacija ima 4 stranice. Na stranici ‘Users’ podaci se ucitavaju sa ove lokacije: https://fake-json-api.mock.beeceptor.com/users
Na datoj lokaciji nalazi se primjer API response-a.
Na stranici info podaci se ucitavaju sa ove lokacije:
https://mladen.free.beeceptor.com/info
Ova lokacija takodje sadrzi primjer API response-a.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Multi-Page App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScaffold(),
);
}
}
class MainScaffold extends StatefulWidget {
@override
_MainScaffoldState createState() => _MainScaffoldState();
}
class _MainScaffoldState extends State<MainScaffold> {
int _selectedIndex = 0;
final List<Widget> _pages = [
HomePage(),
AboutPage(),
UsersPage(),
InfoPage(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.info),
label: 'About',
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: 'Users',
),
BottomNavigationBarItem(
icon: Icon(Icons.info_outline),
label: 'Info',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
onTap: _onItemTapped,
),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Welcome to Our App',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
Text(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16),
),
],
),
),
),
);
}
}
class AboutPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About Page'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'About Us',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
Text(
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16),
),
],
),
),
),
);
}
}
class UsersPage extends StatefulWidget {
@override
_UsersPageState createState() => _UsersPageState();
}
class _UsersPageState extends State<UsersPage> {
List<dynamic> _users = [];
bool _isLoading = true;
String _errorMessage = '';
@override
void initState() {
super.initState();
_fetchUsers();
}
Future<void> _fetchUsers() async {
try {
final response = await http.get(
Uri.parse('https://fake-json-api.mock.beeceptor.com/users'),
);
if (response.statusCode == 200) {
setState(() {
_users = json.decode(response.body);
_isLoading = false;
});
} else {
setState(() {
_isLoading = false;
_errorMessage = 'Failed to load users (${response.statusCode})';
});
}
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error: ${e.toString()}';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Users'),
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: _errorMessage.isNotEmpty
? Center(
child: Text(
_errorMessage,
style: TextStyle(color: Colors.red),
),
)
: ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
final user = _users[index];
return ListTile(
title: Text(user['name'] ?? 'Unknown'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Company: ${user['company'] ?? 'N/A'}'),
Text('Country: ${user['country'] ?? 'N/A'}'),
],
),
);
},
),
);
}
}
class InfoPage extends StatefulWidget {
@override
_InfoPageState createState() => _InfoPageState();
}
class _InfoPageState extends State<InfoPage> {
Map<String, dynamic> _infoData = {};
bool _isLoading = true;
String _errorMessage = '';
@override
void initState() {
super.initState();
_fetchInfoData();
}
Future<void> _fetchInfoData() async {
try {
final response = await http.get(
Uri.parse('https://mladen.free.beeceptor.com/info'),
);
if (response.statusCode == 200) {
setState(() {
_infoData = json.decode(response.body);
_isLoading = false;
});
} else {
setState(() {
_isLoading = false;
_errorMessage = 'Failed to load info (${response.statusCode})';
});
}
} catch (e) {
setState(() {
_isLoading = false;
_errorMessage = 'Error: ${e.toString()}';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Information Page'),
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: _errorMessage.isNotEmpty
? Center(
child: Text(
_errorMessage,
style: TextStyle(color: Colors.red),
),
)
: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Information Details',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 20),
Text(
'Name: ${_infoData['name'] ?? 'No data'}',
style: TextStyle(fontSize: 18),
),
SizedBox(height: 10),
Text(
'Places: ${_infoData['places'] ?? 'No data'}',
style: TextStyle(fontSize: 18),
),
],
),
),
);
}
}