💡 import ‘package:flutter/rendering.dart’; 사용
스크롤 위치 파악
- 게시물목록 ListView에 ScrollController() 부착하기
- 스크롤위치 계속 감시해주는 리스너 부착하기
- 맨 밑까지 스크롤하면 서버에 게시물 더 달라고 GET요청하기
- 데이터 가져오면 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 |