어떤 기능에 대한 코드를 아주 많이 작성하는 경우도 있다.

이런 느낌으로?

 

이게 줄이 길어질수록 한눈에 딱딱 보기가 조금 어려워진다

예전에 유니티할땐 #region ~~ 으로 묶을수가 있었는데 flutter[dart] 에서는 그런기능이 없나? 찾아봤다

 

https://marketplace.visualstudio.com/items?itemName=maptz.regionfolder 

 

#region folding for VS Code - Visual Studio Marketplace

Extension for Visual Studio Code - Provides folding for text wrapped with #region comments in VS Code.

marketplace.visualstudio.com

 

vscode의 이 extension을 쓰면 되더라.

사용법은 간단하다

vscode 에서 해당 extension 을 설치하고 코드에 #region, #endregion 만 입력해주면 끝

 

 

//#region 과 설명을 적고

//#endregion 으로 어디까지 묶을것인가 적는다

 

그다음 #region 왼쪽의 화살표를 누르면

 

이렇게 #region ~ #endregion 까지 접힌다. 굿.

 

분명 안드로이드 스튜디오가 설치되어있는데 설치되지 않았단다.

 

flutter config --android-studio-dir="C:\Program Files\Android\Android Studio"

 

안드로이드 스튜디오의 경로를 지정해주자

 

 

 

안드로이드 스튜디오 문제는 해결됐다

그런데 이제 갑자기 Android toolchaing 에서 경고가 뜬다.

 

flutter doctor --android-licenses

 

이게 제대로 라이센스 동의하는 문구가 나올수도 있고 

이런 에러가 나올 수도 있다.

(Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema)

 

라이센스 동의하는 문구가 나오면 y 입력으로 그냥 넘어가면 되고 

이 에러가 뜰 경우 안드로이드 스튜디오 세팅으로 넘어가자

 

Android SDK Command-line Tools 를 체크하고 OK

 

 

이제야 다 됐다.

 

 

listview 를 사용중인데 item 에 image 가 들어간다. 문제는 이 이미지가 network 에서 받아와서 이미지의 높이를 받아오기전까지 모른다는거...

 

그래서 이미지를 받아와서 container height 를 설정해주고 있다

 

문제는 리스트뷰를 쫙~ 내리고 다시 올라올때 listview 특성상 기존 아이템들을 잠시 제거했다가 화면에 보일때 다시 렌더링한다는거... 

 

기존 아이템이 제거돼서 높이가 0이 됐다가 다시 화면에 보여 렌더링되면서 높이가 100? 200? 정도 로 설정되면서 스크롤이 갑자기 한움큼 내려가버리는 문제 발생.

 

그래서 listview 나 pageview 같은 곳에서 기존 아이템들을 살릴 수 있는 방법을 찾아봤다.

 

import 'package:flutter/material.dart';

class TestItem extends StatefulWidget {
  @override
  _TestItemState createState() => _TestItemState();
}

class _TestItemState extends State<TestItem>
    with AutomaticKeepAliveClientMixin { // <-----
  @override
  bool get wantKeepAlive => true; // <-------

  @override
  Widget build(BuildContext context) {
    super.build(context); // <------
    return Container();
  }
}

 

방법은 하위 아이템에 AutomaticKeepAliveClientMixin 을 with 해주고,

get 으로 wantKeepAlive true 로 반환하는 코드를 오버라이딩 해주면 된다.

 

이 방법은 tabbar, listview 등등 적용된다

참조 https://stackoverflow.com/questions/52541172/flutter-listview-keepalive-after-some-scroll

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

+ Recent posts