일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- RouteObserver
- jszip
- REST API
- uint8array
- Babel standalone
- code editor
- KakaoMap
- Prism.js
- node
- babel
- identifierForVender
- FirebaseAnalytics
- web track
- react
- Image Resize typescript
- androidId
- Completer
- uint16array
- userevent_tracker
- Game js
- typescript
- Three-fiber
- webrtc
- Three js
- Redux
- Flutter
- Excel
- Raycasting
- methodChannel
- swagger-typescript-api
- Today
- Total
Never give up
Flutter - How to use exntension with getting widget position 본문
extension메소드의 공식문서를 보니
자주 사용하는 코드들을 구현해놓고 필요할 때 사용하면 편하겠다 라는 느낌을 받았습니다
(공식문서 : dart.dev/guides/language/extension-methods)
그래서 이번에는 Icon Button 클릭시 위젯의 위치값을
snackbar로 출력하는 예제를 만들어봤습니다
사용할 extension
extension PositionExtension on GlobalKey {
Rect get getPosition {
final RenderObject renderObject = currentContext?.findRenderObject();
var translation = renderObject?.getTransformTo(null)?.getTranslation();
if (translation != null && renderObject.paintBounds != null) {
return renderObject.paintBounds
.shift(Offset(translation.x, translation.y));
} else {
return null;
}
}
}
extension SnackBarExtension on GlobalKey<ScaffoldState> {
ScaffoldFeatureController snackBar(String text) =>
currentState.showSnackBar(SnackBar(content: Text(text)));
}
Main
class WidgetPosition extends StatelessWidget {
final GlobalKey _buttonKey1 = GlobalKey();
final GlobalKey _buttonKey2 = GlobalKey();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text('Extension example')),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
IconButton(
key: _buttonKey1,
icon: Icon(Icons.looks_one),
onPressed: () {
Rect rect = _buttonKey1.getPosition;
_scaffoldKey.snackBar('rect : $rect');
}),
IconButton(
key: _buttonKey2,
icon: Icon(Icons.looks_two),
onPressed: () {
Rect rect = _buttonKey2.getPosition;
_scaffoldKey.snackBar('rect : $rect');
})
]));
}
}
(사실 이 예제에서는 scaffoldKey를 사용해야될 이유는 없지만 자주 사용하는 방식이기 때문에 한번 만들어봤습니다)
먼저 위젯의 위치를 찾는 방법으로 context.findRenderObject()를 사용하고
matrix값을 가져오기 위해 translation값을 사용합니다
getTransformTo 문서를 잠시 살펴보면
If `ancestor` is null, this method returns a matrix that maps from the local paint coordinate system to the coordinate system of the [PipelineOwner.rootNode]
ancestor값(필자가 넣은 null값)이 null일 때 matrix값을 반환해준다 정도로 축약해볼 수 있고
이 값에 getTranslation을 사용하면 Vector3값(x, y, z)을 얻을 수 있습니다
renderObject의 paintsBounds 문서를 살펴보면
These are also the bounds used by [showOnScreen] to make a [RenderObject] visible on screen.
이 경계는 showOnScreen으로 RenderObject를 화면에 보여주기 위해 사용된다 정도로 해석할 수 있습니다
이 값을 shift메소드를 사용하면 넣어준 Offset값에 따라 위치를 Rect값으로 반환해줍니다
rect값을 출력해보면 Rect.fromLTRB(0.0, 304.0, 411.4, 352.0)이런식으로
Left, Top, Right, Bottom좌표가 나와서 이 상태로 사용해도 되고 다른 값으로 변환해서 사용할 수 있습니다
여기 까지가 첫번째 extension에 대한 설명이었습니다..
두번째 extension은 우리가 자주(?) 사용하는 scaffoldKey를 이용한 snackbar를 extension으로
구현해 필요할 때 text만 넣어주면 되는식으로 구현을 해봤습니다
IconButton에 key.snackbar(string값)만 쓰면 되니 훨씬 더 간단해보이는 효과도 있고
여러군데에서 사용할 때 import해서 전역으로 사용하는것도 괜찮을거 같습니다
이 외에도 데이터 기본형으로도 extension을 사용해도 무방합니다
예를들어 간단한 사칙연산같은경우 이런식으로 표현해 볼 수 있습니다
extension Calculation on int {
int addNum(int num1, int num2) => num1 + num2;
int subNum(int num1, int num2) => num1 - num2;
int multiNum(int num1, int num2) => num1 * num2;
int divNum(int num1, int num2) => (num1 / num2).ceil();
}
//사용법은 아래와 같은식으로 사용하면 됩니다
//int result;
//result.addNum(1,2);
(아무도 사용하지 않겠지만요..)
요번 포스트는 아래 UI(Overlay entry)를 구현중에 생각나서 써본건데
문제가 조금 있어서 아래 위젯 소스는 공유하지 않기로 결정했습니다..
'Flutter' 카테고리의 다른 글
Flutter - 비동기처리의 이해 (0) | 2021.03.02 |
---|---|
Flutter - Bloc todo example (0) | 2021.02.28 |
Flutter - update previous screen with Navigator callback (0) | 2021.01.05 |
Flutter - PageView with TabBar and Indicator (0) | 2021.01.03 |
Flutter - Provider Selector with tuple (3) | 2020.12.31 |