Ниже представлен базовый каркас мобильного приложения для работы с Osclass через REST API на Flutter/Dart. Это приложение будет отображать объявления и категории из вашей Osclass системы.
- Основные файлы приложения
- 1. main.dart — Главный файл приложения
- 2. api_service.dart — Сервис для работы с API Osclass
- 3. models/item_model.dart — Модель данных объявления
- 4. screens/home_screen.dart — Главный экран приложения
- 5. widgets/item_card.dart — Виджет карточки объявления
- Настройка проекта
- Дополнительные возможности для реализации
Основные файлы приложения
1. main.dart
— Главный файл приложения
import 'package:flutter/material.dart';
import 'package:osclass_app/screens/home_screen.dart';
import 'package:osclass_app/services/api_service.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Osclass App',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const HomeScreen(),
debugShowCheckedModeBanner: false,
);
}
}
2. api_service.dart
— Сервис для работы с API Osclass
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
static const String _baseUrl = 'https://your-osclass-site.com/api';
static const String _apiKey = 'YOUR_API_KEY';
Future<List<dynamic>> getLatestItems() async {
final response = await http.get(
Uri.parse('$_baseUrl/items/search?limit=20'),
headers: {'Authorization': 'Bearer $_apiKey'},
);
if (response.statusCode == 200) {
return json.decode(response.body)['items'];
} else {
throw Exception('Failed to load items');
}
}
Future<List<dynamic>> getCategories() async {
final response = await http.get(
Uri.parse('$_baseUrl/categories'),
headers: {'Authorization': 'Bearer $_apiKey'},
);
if (response.statusCode == 200) {
return json.decode(response.body)['categories'];
} else {
throw Exception('Failed to load categories');
}
}
Future<dynamic> getItemDetails(int itemId) async {
final response = await http.get(
Uri.parse('$_baseUrl/items/$itemId'),
headers: {'Authorization': 'Bearer $_apiKey'},
);
if (response.statusCode == 200) {
return json.decode(response.body);
} else {
throw Exception('Failed to load item details');
}
}
}
3. models/item_model.dart
— Модель данных объявления
class Item {
final int id;
final String title;
final String description;
final double price;
final String? imageUrl;
final String category;
final String location;
final DateTime date;
Item({
required this.id,
required this.title,
required this.description,
required this.price,
this.imageUrl,
required this.category,
required this.location,
required this.date,
});
factory Item.fromJson(Map<String, dynamic> json) {
return Item(
id: json['id'],
title: json['title'],
description: json['description'],
price: double.tryParse(json['price']?.toString() ?? '0') ?? 0,
imageUrl: json['images']?.isNotEmpty == true ? json['images'][0] : null,
category: json['category_name'] ?? 'Unknown',
location: json['city_name'] ?? 'Unknown location',
date: DateTime.parse(json['dt_pub_date']),
);
}
}
4. screens/home_screen.dart
— Главный экран приложения
import 'package:flutter/material.dart';
import 'package:osclass_app/models/item_model.dart';
import 'package:osclass_app/services/api_service.dart';
import 'package:osclass_app/widgets/item_card.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final ApiService _apiService = ApiService();
List<Item> _items = [];
bool _isLoading = true;
void initState() {
super.initState();
_loadItems();
}
Future<void> _loadItems() async {
try {
final items = await _apiService.getLatestItems();
setState(() {
_items = items.map((json) => Item.fromJson(json)).toList();
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error loading items: ${e.toString()}')),
);
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Osclass App'),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// Реализация поиска
},
),
],
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ItemCard(item: _items[index]);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Переход к экрану добавления объявления
},
child: const Icon(Icons.add),
),
);
}
}
5. widgets/item_card.dart
— Виджет карточки объявления
import 'package:flutter/material.dart';
import 'package:osclass_app/models/item_model.dart';
class ItemCard extends StatelessWidget {
final Item item;
const ItemCard({super.key, required this.item});
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
// Переход к деталям объявления
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (item.imageUrl != null)
Image.network(
item.imageUrl!,
height: 150,
width: double.infinity,
fit: BoxFit.cover,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'\$${item.price.toStringAsFixed(2)}',
style: const TextStyle(
fontSize: 16,
color: Colors.green,
),
),
const SizedBox(height: 4),
Row(
children: [
const Icon(Icons.location_on, size: 16),
const SizedBox(width: 4),
Text(item.location),
],
),
Row(
children: [
const Icon(Icons.category, size: 16),
const SizedBox(width: 4),
Text(item.category),
],
),
],
),
),
],
),
),
);
}
}
Настройка проекта
-
Добавьте необходимые зависимости в
pubspec.yaml
:
dependencies:
flutter:
sdk: flutter
http: ^0.13.5
intl: ^0.18.1
cached_network_image: ^3.2.3
-
Для работы с API Osclass вам нужно:
-
Установить и настроить REST API плагин для Osclass
-
Получить API ключ
-
Обновить
_baseUrl
и_apiKey
вapi_service.dart
-
Дополнительные возможности для реализации
-
Экран деталей объявления
-
Поиск по объявлениям
-
Фильтрация по категориям
-
Система авторизации
-
Создание новых объявлений
-
Избранные объявления
-
Кэширование данных
Это базовый каркас приложения, который можно расширять в зависимости от ваших требований. Для работы с изображениями рекомендуется использовать пакет cached_network_image
, а для навигации между экранами — go_router
или стандартный Navigator
.