[Flutter] 스크롤 위치 파악하기

2023. 9. 22. 22:34·Web & Android/Flutter

💡 import ‘package:flutter/rendering.dart’; 사용

 

스크롤 위치 파악

  1. 게시물목록 ListView에 ScrollController() 부착하기
  2. 스크롤위치 계속 감시해주는 리스너 부착하기
  3. 맨 밑까지 스크롤하면 서버에 게시물 더 달라고 GET요청하기
  4. 데이터 가져오면 data라는 state에 추가해주기

→ 스크롤 위치를 파악하고 싶으면 해당 위젯을 StatefulWidget으로 변경해야 함

→ 부모가 보낸 state를 등록할 때는 위 class에 등록하고 사용은 아래 class에서 함

→ 아래 class에서 위 class에 있는 변수를 사용할 때는 widget.변수명 사용

ScrollController

  • 스크롤바 위치 기록해줌
  • ListView를 사용하면 controller: 라는 파라미터 사용 가능
  • 변수를 넣으면 스크롤 위치에 대한 정보들을 변수에 기록해줌
    • 변수 처음 생성 시 ScrollController() 넣어서 만들어주기
  • 유저가 스크롤 할 때마다 매번 실행하고 싶다면 addListener 사용
class _HomeState extends State<Home> {
  var scroll = ScrollController();

  @override
  Widget build(BuildContext context) {
  if (widget.data.isNotEmpty){
    return ListView.builder(itemCount: 3, controller: scroll, (생략)

 

addListener

  • initState 안에서 사용
  • 스크롤 될 때마다 실행
class _HomeState extends State<Home> {
  var scroll = ScrollController();

  @override
  void initState() {
    super.initState();
    scroll.addListener( () {
      print('스크롤위치 변화함')
    });
  }

  @override
  Widget build(BuildContext context) {
  if (widget.data.isNotEmpty){
    return ListView.builder(itemCount: 3, controller: scroll, (생략)
  • scroll.position.pixels → 유저가 위에서부터 얼마나 스크롤 내렸는지 확인
  • scroll.position.maxScrollExtent → 최대 스크롤 내릴 수 있는 높이
  • scroll.position.userScrollDirection → 스크롤 방향이 위인지 아래인지 확인

⇒ 유저가 맨 밑까지 스크롤 했는지 확인하는 코드

@override
  void initState() {
    super.initState();
    scroll.addListener(() {
      if (scroll.position.pixels == scroll.position.maxScrollExtent){
        print('맨 밑까지 스크롤함')
      }
    });
  }

예제

  • 유저가 맨 밑까지 스크롤바 내리면 서버에서 게시물 가져와서 하단에 보여주기
import 'package:flutter/material.dart';
import './style.dart' as style;
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter/rendering.dart';

void main() {
  runApp(
      MaterialApp(
      theme: style.theme,
      home: MyApp()
  ));
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var tab = 0;  // 1. 현재 상태 저장
  var list = [1, 2, 3];
  var map = {'name':'john', 'age':20};
  var data = [];

  addData(a) {
    setState(() {
      data.add(a);
    });
  }

  getData() async {
    var result = await http.get(Uri.parse('https://codingapple1.github.io/app/data.json'));

    var result2 = jsonDecode(result.body);
    setState(() {
        data = result2;
    });

  }

  @override
  void initState() {
    super.initState();
    getData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text('Instagram'),
          actions: [
            IconButton(
              icon: Icon(Icons.add_box_outlined),
              onPressed: () {},
              iconSize: 30,
            )
          ]),
      body: [Home(data : data, addData : addData), Text('샵페이지')][tab],  // 2. state에 따라 tab 보이는 상태 변경
      bottomNavigationBar: BottomNavigationBar(
        showSelectedLabels: false,
        showUnselectedLabels: false,
        onTap: (i){
          setState(() {
            tab = i;
          });
        },
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: '홈'),
          BottomNavigationBarItem(icon: Icon(Icons.shopping_bag_outlined), label: '샵')
        ],
      ),
    );
  }
}

class Home extends StatefulWidget {
  const Home({Key? key, this.data, this.addData}) : super(key: key);
  final data, addData;

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {

  var scroll = ScrollController();

  getMore() async {
    var result = await http.get(Uri.parse('https://codingapple1.github.io/app/more1.json'));
    var result2 = jsonDecode(result.body);

    widget.addData(result2);
  }

  @override
  void initState() {
    super.initState();
    scroll.addListener(() {   // 스크롤바 높이 측정 코드
      if(scroll.position.pixels == scroll.position.maxScrollExtent) {
        getMore();
      }
    });
  }

  @override
  Widget build(BuildContext context) {

    if (widget.data.isNotEmpty) {
      return ListView.builder(
          itemCount: widget.data.length,
          controller: scroll,
          itemBuilder: (c, i) {
            return Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Image.network(widget.data[i]['image']),
                Container(
                  constraints: BoxConstraints(maxWidth: 600),
                  padding: EdgeInsets.all(20),
                  width: double.infinity,
                  child: Column(
                    children: [
                      Text('좋아요 ${widget.data[i]['likes'].toString()}'),
                      Text(widget.data[i]['date']),
                      Text(widget.data[i]['content'])
                    ],
                  ),
                )
              ],
            );
          }
      );
    } else {
      return Text('로딩중임');
    }
  }
}
저작자표시 비영리 변경금지 (새창열림)

'Web & Android > Flutter' 카테고리의 다른 글

[Flutter] 페이지 나누기 - Navigator  (0) 2023.09.22
[Flutter] 페이지 나누기 - Tab  (0) 2023.09.22
[Flutter] http 패키지로 GET 요청  (0) 2023.09.22
[Flutter] 파일 분리하기  (0) 2023.09.22
[Flutter] ThemeData()  (0) 2023.09.22
'Web & Android/Flutter' 카테고리의 다른 글
  • [Flutter] 페이지 나누기 - Navigator
  • [Flutter] 페이지 나누기 - Tab
  • [Flutter] http 패키지로 GET 요청
  • [Flutter] 파일 분리하기
woojin._.
woojin._.
여러가지 개발을 해보며 발생하는 이야기들에 대한 블로그입니다:)
  • woojin._.
    Jin's Dev Story
    woojin._.
  • 전체
    오늘
    어제
    • 분류 전체보기 (829)
      • Tools (25)
        • eGovFrame (3)
        • GeoServer (3)
        • QGIS (2)
        • LabelImg (2)
        • Git (6)
        • GitHub (1)
        • Eclipse (7)
        • Visual Studio (1)
      • Web & Android (121)
        • SpringBoot (37)
        • Three.js (2)
        • Spring Data JPA (9)
        • 스프링 부트 쇼핑몰 프로젝트 with JPA (25)
        • Thymeleaf (4)
        • Spring Security (15)
        • Flutter (29)
      • Programming Language (61)
        • JAVA (27)
        • JavaScript (14)
        • Dart (2)
        • Python (15)
        • PHP (3)
      • Database (43)
        • PostgreSQL (32)
        • MYSQL (7)
        • Oracle (3)
        • MSSQL (1)
      • SERVER (17)
        • TCP_IP (3)
        • 리눅스 (7)
        • AWS (7)
      • Coding Test (445)
        • 백준[JAVA] (108)
        • 프로그래머스[JAVA] (260)
        • 알고리즘 고득점 Kit[JAVA] (3)
        • SQL 고득점 Kit[ORACLE] (74)
      • CS 지식 (49)
        • [자료구조] (14)
        • [네트워크] (12)
        • [데이터베이스] (10)
        • [알고리즘] (9)
        • [운영체제] (4)
      • 기타 (6)
      • 자격증 & 공부 (62)
        • 정보처리기사 (2)
        • SQLD (6)
        • 네트워크관리사 2급 (5)
        • 리눅스마스터 1급 (44)
        • 리눅스마스터 2급 (1)
        • ISTQB (3)
        • 시스템보안 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 태그

    스프링 부트 쇼핑몰 프로젝트 with JPA
    리눅스마스터
    DB
    프로그래머스
    pcce 기출문제
    리눅스마스터 1급
    데이터
    programmers
    스프링
    Flutter
    자바
    baekjoon
    백준
    spring
    springboot
    Oracle
    backjoon
    JPA
    데이터베이스
    스프링부트
    Linux
    Java
    postgresql
    CS
    시큐리티
    CS지식
    python
    플러터
    Spring Security
    리눅스
  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
woojin._.
[Flutter] 스크롤 위치 파악하기
상단으로

티스토리툴바