Widget의 크기를 얻어오고싶다면?

  • GlobalKey를 생성
  • 위치를 알고싶은 Widget에 key 할당
  • GlobalKey를 이용해 findRenderObject() 얻어온 후 RenderBox로 Type Casting을 해주면 얻을 수 있다.

Code:

final _widgetKey = GlobalKey();


void initState() {
  super.initState();

  WidgetsBinding.instance.addPostFrameCallback((_) {
    final widgetHeight = (_widgetKey.currentContext!
            .findRenderObject() as RenderBox)
        .size
        .height;
		print('widgetHeight: $widgetHeight');
  });
}


Widget build(BuildContext context) {
	...
	CustomWidget(
		key: _widgetKey,
		child: ...,
	),
	...
}

Result:

widgetHeight: 76.0

But, 이게 SliverWidget이라면?

Code:

final _widgetKey = GlobalKey();


void initState() {
  super.initState();

  WidgetsBinding.instance.addPostFrameCallback((_) {
    final appBarHeight = (_widgetKey.currentContext!
            .findRenderObject() as RenderBox)
        .size
        .height;
    print('appBarHeight: $appBarHeight');
  });
}


Widget build(BuildContext context) {
	...
	CustomScrollView(
    controller: _controller,
    slivers: [
			SliverCustomWidget(
				key: _widgetKey,
				child: ...,
			),
			...
		],
	);
}

Result:

_TypeError (type '_RenderSliverPinnedPersistentHeaderForWidgets' is not a subtype of type 'RenderBox' in type cast)

Casting 에러가 난다..


Cause:
참고: [stack overflow] type 'RenderSliverList' is not a subtype of type 'RenderBox' in type cast - Flutter

Sliver 위젯은 RenderBox가 아니라 RenderSliver였다.

  • 그러니 RenderSliver로 타입 변환(Casting)이 필요했다.
  • Size를 얻어올 수 있는게 getAbsoluteSize()getAbsoluteSizeRelativeToOrigin가 있었다.
  • getAbsoluteSize: 슬리버(Sliver)의 절대(absolute) 크기를 반환한다. 그리고 레이아웃이 완료 된 후에만 호출 가능
  • getAbsoluteSizeRelativeToOrigin: 슬리버(Sliver)의 왼쪽 가장자리를 기준으로 치수가 포함된 크기 반환한다. 이도 똑같이 레이아웃 완료 된 후 호출 가능하다.

Solution

Widget과 똑같은 내용

  • GlobalKey를 생성
  • 위치를 알고싶은 Widget에 key 할당
  • GlobalKey를 이용해 findRenderObject() 얻어온다

Sliver 특정 내용

  • RenderSliver로 Type Casting을 한다.
  • Sliver의 절대크기를 얻고싶다면 getAbsoluteSize()를 이용한다.

code:

WidgetsBinding.instance.addPostFrameCallback((_) {
  final appBarHeight =
      (_appBarKey.currentContext!.findRenderObject() as RenderSliver)
          .getAbsoluteSize()
          .height;
  print('appBarHeight: $appBarHeight');
});

Result:

appBarHeight: 76.0

full code:

final _widgetKey = GlobalKey();


void initState() {
  super.initState();

	WidgetsBinding.instance.addPostFrameCallback((_) {
	  final appBarHeight =
	      (_appBarKey.currentContext!.findRenderObject() as RenderSliver)
	          .getAbsoluteSize()
	          .height;
	  print('appBarHeight: $appBarHeight');
	});
}


Widget build(BuildContext context) {
	...
	CustomScrollView(
    controller: _controller,
    slivers: [
			SliverAppBar(
				key: _widgetKey,
				child: ...,
			),
			...
		],
	);
}
profile
𝙸 𝚊𝚖 𝚊 𝚌𝚞𝚛𝚒𝚘𝚞𝚜 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚠𝚑𝚘 𝚎𝚗𝚓𝚘𝚢𝚜 𝚍𝚎𝚏𝚒𝚗𝚒𝚗𝚐 𝚊 𝚙𝚛𝚘𝚋𝚕𝚎𝚖. 🇰🇷👩🏻‍💻

0개의 댓글

관련 채용 정보