아미(아름다운미소)

flutter API 무한스크롤 본문

랭귀지/Flutter(플러터)

flutter API 무한스크롤

유키공 2024. 9. 26. 12:56
lib/
├── main.dart
├── home/
│   ├── home_screen.dart
│   └── home_screen_state.dart
├── services/
│   └── api_service.dart
└── models/
    └── data_model.dart

main.dart

import 'package:flutter/material.dart';
import 'home/home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

home/home_screen.dart

import 'package:flutter/material.dart';
import '../services/api_service.dart';
import '../models/data_model.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

home/home_screen_state.dart

import 'package:flutter/material.dart';
import '../services/api_service.dart';
import '../models/data_model.dart';

class _HomeScreenState extends State<HomeScreen> {
  final ApiService apiService = ApiService();
  List<DataModel> data = [];
  int skip = 0;
  final int limit = 10;
  bool isLoading = false;
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    fetchData();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        fetchData();
      }
    });
  }

  void fetchData() async {
    if (isLoading) return;

    setState(() {
      isLoading = true;
    });

    try {
      final result = await apiService.fetchData('userid', 'search_word_example', 'str_kind_example', skip, limit);
      setState(() {
        data.addAll(result.map((item) => DataModel.fromJson(item)).toList());
        skip += limit;
      });
    } catch (e) {
      print(e);
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('API Data'),
      ),
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              controller: _scrollController,
              itemCount: data.length + 1,
              itemBuilder: (context, index) {
                if (index == data.length) {
                  return isLoading ? Center(child: CircularProgressIndicator()) : SizedBox.shrink();
                }
                return ListTile(
                  title: Text(data[index].name),
                  subtitle: Text(data[index].companySummary),
                );
              },
            ),
          ),
          if (isLoading)
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: CircularProgressIndicator(),
            ),
        ],
      ),
    );
  }
}

services/api_service.dart

import 'package:http/http.dart' as http;
import 'dart:convert';

class ApiService {
  final String baseUrl = 'YOUR_API_BASE_URL';

  Future<List<dynamic>> fetchData(String userid, String searchWord, String strKind, int skip, int limit) async {
    final response = await http.get(
      Uri.parse('$baseUrl?userid=$userid&search_word=$searchWord&str_kind=$strKind&skip=$skip&limit=$limit'),
    );

    if (response.statusCode == 200) {
      return json.decode(response.body);
    } else {
      throw Exception('Failed to load data');
    }
  }
}

models/data_model.dart

class DataModel {
  final String name;
  final String companySummary;

  DataModel({required this.name, required this.companySummary});

  factory DataModel.fromJson(Map<String, dynamic> json) {
    return DataModel(
      name: json['name'],
      companySummary: json['companysummary'],
    );
  }
}
Comments