flutter 에서 Globalkey 를 이용하여 위젯의 크기와 위치를 구하는 방법.

크기를 구할땐 LayoutBuilder 위젯도 있다. 여기선 GlobalKey 로 구하는 법

 

베이스 코드

// ...

GlobalKey _redBoxKey = GlobalKey();
GlobalKey _greenBoxKey = GlobalKey();
GlobalKey _blueBoxKey = GlobalKey();


@override
  Widget build(BuildContext context) {

    return Scaffold(
        body: SafeArea(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Center(
            child: Container(
              key: _redBoxKey,
              height: 40,
              width: 40,
              color: Colors.red,
            ),
          ),
          Center(
            child: Container(
              key: _greenBoxKey,
              height: 100,
              width: 40,
              color: Colors.green,
            ),
          ),
          Center(
            child: Container(
              key: _blueBoxKey,
              height: 40,
              width: 100,
              color: Colors.blue,
            ),
          ),
        ],
      ),
    ));
    
    
    //...

일단 GlobalKey 를 선언하여 widget 에 key 를 할당해준다. 그 후 진행

 

1. 크기

 

// ...

_getSize(GlobalKey key) {
    if (key.currentContext != null) {
      final RenderBox renderBox =
          key.currentContext!.findRenderObject() as RenderBox;
      Size size = renderBox.size;
      return size;
    }
  }
  
// ...

 

key 를 이용하여 RenderBox 를 구하면 RenderBox에서 size 를 구할 수 있다.

 

// ...

    final redBoxSize = _getSize(_redBoxKey);
    final greenBoxSize = _getSize(_greenBoxKey);
    final blueBoxSize = _getSize(_blueBoxKey);

    print('red box size : ${redBoxSize.width} ${redBoxSize.height}');
    print('green box size : ${greenBoxSize.width} ${greenBoxSize.height}');
    print('blue box size : ${blueBoxSize.width} ${blueBoxSize.height}');

// ...

//    I/flutter ( 5007): red box size : 40.0 40.0
//    I/flutter ( 5007): green box size : 40.0 100.0
//    I/flutter ( 5007): blue box size : 100.0 40.0

 

2. 위치

// ...

_getPosition(GlobalKey key) {
    if (key.currentContext != null) {
      final RenderBox renderBox =
          key.currentContext!.findRenderObject() as RenderBox;
      final position = renderBox.localToGlobal(Offset.zero);
      return position;
    }
  }
  
 // ...

 

크기와 비슷하다. renderBox 의 localToGlobal 함수를 이용한다. 

Offset.zero 즉. 위젯의 좌상단을 기준으로 global 포지션을 구하는 방식이다.

 

// ...

    final redBoxPosition = _getPosition(_redBoxKey);
    final greenBoxPosition = _getPosition(_greenBoxKey);
    final blueBoxPosition = _getPosition(_blueBoxKey);

    print('red box posiiton : ${redBoxPosition.dx} ${redBoxPosition.dy}');
    print('green box posiiton : ${greenBoxPosition.dx} ${greenBoxPosition.dy}');
    print('blue box posiiton : ${blueBoxPosition.dx} ${blueBoxPosition.dy}');
    
// ...

// I/flutter ( 5007): red box posiiton : 0.0 147.71428571428572 
// x축 확인을 위해 redbox 를 맨 왼쪽으로 붙인 상태이다
// I/flutter ( 5007): green box posiiton : 185.71428571428572 384.8571428571429
// I/flutter ( 5007): blue box posiiton : 155.71428571428572 682.0

 

flutter 개발 중 내부 서버와 http 통신을 하려고 했는데 발생한 에러.

https 서버도 열어놨었는데 내부 서버라 인증서 문제로 http 서버를 열어서 하는데 http 통신도 안되는거..

http 통신이라도 해결해보자

 

[root]\android\app\src\main 의

 

AndroidManifest.xml 파일을 수정

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yourapp">
   <application
        android:label="yourapp"
        android:usesCleartextTraffic="true" // <-- 이 부분
        android:icon="@mipmap/ic_launcher">
        <activity
        .
        .
        .
        .
        

 

이 부분 이라고 작성한 부분을 추가하면 된다

 

android:usesCleartextTraffic="true"

 

 

iOS의 경우는 테스트 안해봐서 모르겠으나 아래의 stackoverflow 에 나와있다.

 

참고

stackoverflow.com/questions/64197752/bad-state-insecure-http-is-not-allowed-by-platform

인풋을 위해 keyboard 가 나왔을 때 bottom overflowed 문제가 발생했다.

 

 

현재 내 코드와 상황.

    return Scaffold(
        appBar: AppBar(
          elevation: 0,
          leading: leadingIcon,
          backgroundColor: Colors.white,
          titleTextStyle: TextStyle(
            color: Colors.black,
          ),
          centerTitle: true,
          title: Text(
            'Welcome',
            style: TextStyle(color: Colors.black),
          ),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Container(
                height: 200,
                child: Container(),
              ),
              render,
            ],
          ),
        ));

 

 

Column 을 SingleChildScrollView 로 wrap해서 해결했다.

 

return Scaffold(
        appBar: AppBar(
          elevation: 0,
          leading: leadingIcon,
          backgroundColor: Colors.white,
          titleTextStyle: TextStyle(
            color: Colors.black,
          ),
          centerTitle: true,
          title: Text(
            'Welcome',
            style: TextStyle(color: Colors.black),
          ),
        ),
        body: Center(
            child: SingleChildScrollView( // 여기 추가
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Container(
                height: 200,
              ),
              render,
            ],
          ),
        ))) // SingleChildScrollView // Center // Scaffold;

 

 

어떻게 flutter를 개발하게 되어 코딩중인데 vscode 에서 80자만 넘어가도 자동으로 줄 바뀜이 일어나버린다..

 

https://dart.dev/guides/language/effective-dart/style

 

일단 코딩 가이드에선 80자 이상을 피하라고 한다.

그래도 일단 바꾸는 법

 

vscode 세팅을 들어가서 dart.line 을 검색하면 80으로 설정되어있다. 수정하면 된다.

 

 

80으로 설정된 숫자를 변경하면 된다.

 

 

80 제한
200 제한

아직 내가 dart 언어에 안 익숙해서 보기가 좀 불편해서 잠시 바꿨는데 다른 사람과 작업할때도 많을 것 이고 

이왕이면 코딩 가이드에 맞춰서 짜는걸 추천한다.

애니메이션 공부하면서 알게된 내용 정리

 

출처 : https://developers.google.com/web/fundamentals/performance/rendering/

웹 브라우저는 위의 이미지와 같은 로딩, 렌더링 순서를 거친다.

 

이 중 Layout, Paint, Composite 단계에 주목하자

 

3. Layout

브라우저에서 엘리먼트의 도형, 위치를 생성한다.

대표적인 속성값으로 width, height, margin, padding, left,top,rigth,bottom 등이 있다

 

4. Paint

각 엘리멘트의 픽셀을 채운다.

box-shadow, border-radius, color, background-color 등이 있다.

 

5. Composite

화면에 모든 레이어를 그리기 시작한다.

transform, opacity 가 있다.

 

여기서 만약 width, height 등의 값 (Layout 에 해당하는 속성 값)을 애니메이션으로 변경하게 된다면

Layout -> Paint -> Composite 단계를 다시 거쳐야한다.

이것을 Reflow 라고 한다

 

그럼 background-color 등을 변경하하면 

Paint -> Composite 를 걸치는데

이것을 Repaint 라고 한다

 

즉 애니메이션을 줄거면 최대한 Composite 단계에서 하는게 성능상으로 좋다.

 

참고

 

Smooth as Butter: Achieving 60 FPS Animations with CSS3

Animating elements in your mobile applications is easy.

medium.com

 

 

렌더링 성능  |  Web  |  Google Developers

사이트와 앱이 제대로 실행되지 않으면 사용자의 주의를 끌게 되므로 렌더링 성능 최적화는 중요합니다!

developers.google.com

 

+ Recent posts