일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- identifierForVender
- KakaoMap
- Excel
- web track
- Three-fiber
- uint8array
- node
- Redux
- babel
- Raycasting
- three.js
- Three js
- webrtc
- typescript
- Flutter
- Prism.js
- REST API
- Game js
- RouteObserver
- androidId
- userevent_tracker
- uint16array
- react
- Babel standalone
- Image Resize typescript
- code editor
- jszip
- Completer
- swagger-typescript-api
- methodChannel
- Today
- Total
Never give up
Flutter - how to get item index in Listview 본문
ListView를 다룰 때 List의 index에 따라 위젯을 변경 시켜주거나
아이템을 눌렀을 때 해당 index로 이동해야되는 위젯이 있을때
처리를 어떻게 해야될지 알아보겠습니다
먼저 사용한 패키지는 다음과 같습니다
pub.dev/packages/scrollable_positioned_list
class _UIExampleState extends State<UIExample> {
List<String> _list = List.generate(20, (index) => 'Item - $index');
StreamController<int> _streamController;
ItemScrollController _itemScrollController = ItemScrollController();
ItemPositionsListener _itemPositionsListener = ItemPositionsListener.create();
int temp, itemIndex;
@override
void initState() {
super.initState();
_streamController = StreamController<int>()..add(1);
_itemPositionsListener.itemPositions.addListener(listener);
}
void listener() {
ItemPosition position = _itemPositionsListener.itemPositions.value
.firstWhere((element) => element.itemLeadingEdge <= 0);
itemIndex = position.index;
if (temp != itemIndex) {
_streamController.add(itemIndex + 1);
temp = itemIndex;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(title: Text('UI Example')),
body: Stack(
children: [
Container(
margin: EdgeInsets.only(left: 100, top: 200, bottom: 390),
width: 100,
color: Colors.green),
Container(
margin: EdgeInsets.only(top: 200),
height: 100,
child: Listener(
onPointerUp: (value) {
_itemScrollController.scrollTo(
index: itemIndex,
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut);
},
child: ScrollablePositionedList.builder(
itemScrollController: _itemScrollController,
itemPositionsListener: _itemPositionsListener,
scrollDirection: Axis.horizontal,
itemCount: _list.length,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(4),
color: Colors.grey,
height: 80,
width: 92,
child: Center(
child: ListTile(
title: Text(
_list[index],
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
onTap: () => _itemScrollController.scrollTo(
index: index - 1,
duration: Duration(milliseconds: 500),
curve: Curves.easeInOutSine)),
));
}),
),
),
SizedBox(height: 20),
Align(
child: StreamBuilder<int>(
stream: _streamController.stream,
builder: (context, snapshot) {
return Text('Current item - ${snapshot.data}');
}))
],
),
);
}
}
먼저 ItemScrollController와 ItemPositionsListener를 ScrollablePositionedList에 정의를 해주면
ListView의 스크롤이 이동함에 따른 위치 정보를 받아올 수 있습니다
controller는 ListTile의 onTap event와 Listener에서 onPointerUp event에 따라
scrollTo 메소드를 이용해서 아이템의 index에 해당하는 위치로 이동하게 됩니다
여기서 onPointerUp을 이용한 이유는 드래그가 끝나는 시점에서
한 index와 다른 index의 사이에 있을때 어떤 위젯을 가리키고 있는지 확실하지 않게 되는데
이 부분에서 itemIndex값이 가리키는곳, 즉 Listener가 가리키는 위치로
자동으로 이동하도록 만들어 놓기 위해 사용했습니다
그리고 listener는 이 예제에서 필요한 아이템의 index값과
위치값 등을 계산 및 처리를 하기위해 사용하는데
필자가 사용한 조건은
ItemPosition position = _itemPositionsListener.itemPositions.value
.firstWhere((element) => element.itemLeadingEdge <= 0);
으로 화면에 보이는 첫번째 List item의 위치값이 0이될 때를 확인하기 위함인데
예를들어 화면에 2 3 4라는 위젯이 있으면 2번이 출력되게 하기위해 사용했습니다
(다른 형태의 UI를 만들때에는 조건의 변화가 필요합니다)
그리고 temp값과 itemIdex값을 비교하여 값이 변경될때만 StreamController를 통해
위젯의 값을 바꿔주는데 이 부분은 현재 가벼운 UI를 변화시키기 때문에 setState를 써도 문제없으나
조금 더 많은 UI를 다룰때에는 꼭 필요하기 때문에 일단 넣어봤습니다
(해당 예제에서는 굳이.. 그래도 좋은 습관을 들이기 위해..)
(참고로 필자가 만든 페르소나4 UI는 이런 방법보다 훨씬 더 간단한 방법으로 만들었습니다)
'Flutter' 카테고리의 다른 글
Flutter - Search item in List and how to keep TextField from keyboard (0) | 2020.10.05 |
---|---|
Flutter - Json serialize (0) | 2020.10.01 |
Flutter - Webview with searchBar (0) | 2020.09.25 |
Flutter - how to use Icon Picker(save, load) (0) | 2020.09.18 |
Flutter - Map get key by value (0) | 2020.09.04 |