[플러터] stateless 위젯에서 controller 사용하기

Computer 비관심/Flutter|2021. 4. 10. 21:54
반응형

stateful widget을 사용하면 편하긴 한데 stateless widget을 사용하여 컨트롤러를 등록하고 스코를의 위치를 얻어내려고 하였다. 보통은 공식문서에서도 적혀있듯 stateful widget을 사용한다.

 

class MyStockScreen extends StatelessWidget {
  final MyStocksCtr controller = Get.put(MyStocksCtr());
  final ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    scrollController.addListener(() => print(scrollController.position.pixels));

    return Scaffold(
    ....

 

 

build 함수 안에 컨트롤러리스너를 등록한다.

dispose가 없는데 문제가 없는지 모르겠다.

stateless라 state자체가 없기 때문에 문제가 없다는거 같은데..

어째튼 작동은 한다.

댓글()

플러터에서 자식 위젯의 메서드 부모에서 호출하기

Computer 비관심/Flutter|2021. 4. 10. 01:12
반응형

플러터는 위젯으로 구성되어 있다. 그렇기 때문에 위젯간의 소통을 할 수 있는 방법을 아는 것이 중요하다. 위젯간의 소통 방법들을 공부하지 않으면 분리되지 않은 거대 위젯으로 앱이 구성이 될 것이다.

 

 

부모의 버튼을 눌렀을때 자식 스크롤 위젯이 자동으로 맨 밑까지 내려오게 하는 기능을 구현해야 했다.

위젯이 나누어지지 않았을 때는 문제가 없었지만 위젯이 부모와 자식으로 나누어 지면서 버튼과 리스트가 분리 되었다.

 

 

이때 부모가 자식의 메서드를 호출해서 그 메서드가 자식을 움직이게 만드려면 어떻게 해야 할까?

StackOverflow에서 두가지 방법을 찾을 수 있었다.

 

 

첫번째는 메서드를 초기화한 클레스의 인스턴트를 전달하는 방법

1. 클레스에 메서드를 초기화 해서 자식 위젯에 인스턴트를 전달한다.

2. 자식위젯에서 구현한 메서드를 전달받은 인스턴트의 메서드에 넣는다.

3. 부모에서 구현한 메서드를 호출한다.

(그러면 자식에서 구현한 메서드가 실행됨)

 

class HomePageController {
  void Function() methodA;
}

class MyApp extends StatelessWidget {

  final HomePageController myController = HomePageController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
              myController.methodA();
            },
          ),// IconButton
        ),// AppBar
        body: HomePage(
          controller: myController,
        ),// HomePage
      ),
    );
  }
}

class HomePage extends StatefulWidget {

  final HomePageController controller;

  HomePage({ this.controller });

  @override
  _HomePageState createState() => _HomePageState(controller);
}

class _HomePageState extends State<HomePage> {

  _HomePageState(HomePageController _controller) {
    _controller.methodA = methodA;
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }

  void methodA() {}
}

 

 

 

두번째는 자식위젯에 글로벌키 넣어 접근하는 방법

1. 자식 위젯이 키를 전달 받을 수 있도록 만든다.

2. 자식 위젯에 글로벌 키를 만든뒤 자식에게 전달.

3. 만들어진 글로벌 키로 자식 메서드 접근

 

GlobalKey<_HomePageState> globalKey = GlobalKey();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
             globalKey.currentState.methodA();
            },
          ),
        ),
        body: HomePage(key: globalKey),
      ),
    );
  }
}
class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  void methodA() {}
}

여기서 중요한건 위젯을 파일로 나누었을때 GlobalKey<_HomePageState> globalKey=GlobalKey()에서

_ (언더바) 를 사용하면 참조를 못 한다는 것이다. 

 

코드출처: stackoverflow.com/questions/53692798/flutter-calling-child-class-function-from-parent-class

댓글()

firebase SDK 없이 flutter에서 firestore에 post요청 보내기

Computer 비관심/Flutter|2020. 11. 26. 00:29
반응형

실시간 기능도 필요 없어서 SDK를 사용하고 싶지 않았다. 

그냥 간단하게 요청하여 필요한 데이터를 json현태로 받고 싶었다. 그런데 flutter 자료가 아직 많지 않아서 해맷다.

 

 

1. 일단 http 요청을 하기위해서 http모듈을 임포트 하였다.

import 'package:http/http.dart' as http;

 

2. 아래와 같이 GET 요청을 보내게 되면 모든 documents를 불러오게 된다. 

https://firestore.googleapis.com/v1/projects/프로젝트명/databases/(default)/documents

 

다큐먼트를 모두 불러온 뒤 클라이언트에서 필터링하면 시간도 엄청나게 걸릴 뿐더러 차후 과금에 문제가 생긴다.

 

3. 파이어베이스의 structuredQuery를 사용하면 데이터를 반환받는 조건을 만들어서 보낼 수 있다.

cloud.google.com/firestore/docs/reference/rest/v1/StructuredQuery

 

아래는 이름을 검색해서 그 검색한 이름과 동일한 다큐먼트를 반환 하는 스트럭쳐드쿼리 예제이다.

1) projectID는 firestore의 프로젝트 이름

2) col은 colection이름

3) fielVal은 내가 찾을 값 (name 필드에서 value가 찾을 내용과 같은 다큐먼트를 필터해서 리턴)

4) body에 json.encode를 해야함.

dynamic response = await http.post(
  'https://firestore.googleapis.com/v1/projects/' +
  	projectID +'/databases/(default)/documents:runQuery',
  headers: {'Content-Type': 'application/json'},
  body: json.encode({
  	'structuredQuery': {
  		'where': {
  			'fieldFilter': {
  				'field': {'fieldPath': 'name'},
  				'op': 'EQUAL',
  				'value': {'stringValue': '${fielVal}'}
 				}
              },
              'from': {'collectionId': '${col}'}
              }
}));

 

 

댓글()

플러터에서 firebase_auth와 flask 서버 같이 사용하기.

Computer 비관심/Flutter|2020. 11. 7. 00:33
반응형

이렇게 사용하면 아래와 같은 장점이 있을 것 같다.

1. 사용자 개인정보를 직접 저장하고 있지 않아도 된다.

 - 개인정보의 보안이나 관리가 어렵다. 

2. 서버에서 구현하기 귀찮은 모바일확인, 페이스북&구글로그인 등을 쉽게 구현 가능하다.

3. firestore의 단점인 과금 문제를 보완 가능. - 정말 필요한 채팅서비스에서만 firestore를 사용하면 될듯. 나머지는 flask SQL서버에 저장.

4. 파이썬을 서버로 사용하기 때문에 데이터처리에도 유용하지 않을까.....?

 

플러터에서 

1. firebaseAuth로 로그인을 함

2. firebaseAuth로 아이디 토큰을 받음

3. http post로 토큰을 서버로 보냄.

 

서버에서

1. post로 온 토큰을 firebase의 

    decoded_token = auth.verify_id_token(id_token)

    uid = decoded_token['uid'] 사용해서 유저를 확인한다.

 

 

로컬호스트에서 진행 했기 때문에 실제 서비스를 하면

어떤 문제가 생기는지는 모르겠다. 

모바일 기기에서 http post를 보낼때 localhost라고 적으면 모바일이 ip를 알지 못하니

ipconfig에 들어가서 실제 로컬호스트 아이디를 입력해줘야 한다.

 

 

댓글()

파이어베이스 로그인

Computer 비관심/Flutter|2020. 11. 6. 01:58
반응형

 

 

firebase_auth 를 사용하려던중 문제 발생

stackoverflow.com/questions/63492211/no-firebase-app-default-has-been-created-call-firebase-initializeapp-in

 

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

위와 같은 방법으로 문제 해결

댓글()

플러터 스트럭처 만들기 작성중

Computer 비관심/Flutter|2020. 11. 3. 23:35
반응형

github.com/infocentre/flutternewproject

 

lib안에 폴더는 

core

 /models

 /services

 /viewmodels - changeNotifier

   .base_model = viewmodel에서 중복되는 boilerplate를 옮김

ui

 /shared - 공유하는 사용자 정의의 디자인 속성을 사용하기 위해

 /views

 /widget

 .router

 

 

MVVM관련 폴더와 ui폴더로 나눈다.

 

provider

댓글()

2. 깃허브에 플러터 올리기

Computer 비관심/Flutter|2020. 11. 3. 22:18
반응형

1. 깃이 설치되어있는지 확인

git --version

깃 버전이 너무 낮아서 다시 설치 해야할 것 같다.

 

 

2. 깃 설정 보기 (로그인이 되있는지도 확인 할 수 있음)

git config --list

아래 화면 처럼 user.email에 보면 로그인이 되어있는 것을 확인 할 수 있다.

3. 깃 레포지터리 초기화하기

git init

4. 현재 폴더에 있는 파일 추가하기

git add .

5. 커밋하기

git commit -m"first commit"

 

6. main branch로 이름을 바꿔줌

git branch -M main

 

1. 깃허브에서 새로운 레포지토리 만들기

2. 만들어진 깃허브레포지토리의 url복사

3. 리모트 오리진에 추가

git remote add origin https://github.com/infocentre/flutternewproject

4. 리모트 오리진 메인 브랜치에 푸시 (-u를 사용해서 로컬브랜치와 리모트브랜치를 연결)

git push -u origin main

 

'Computer 비관심 > Flutter' 카테고리의 다른 글

파이어베이스 로그인  (0) 2020.11.06
플러터 스트럭처 만들기 작성중  (0) 2020.11.03
1. 플러터 설치하기  (0) 2020.11.03
flutter sqflite 사용하기  (0) 2020.05.02
appBar 수정하기  (0) 2020.04.06

댓글()

1. 플러터 설치하기

Computer 비관심/Flutter|2020. 11. 3. 21:28
반응형

vscode의 상단 view에 commend palette에 들어가면 새로운 플러터 프로젝트를 만들 수 있다.

폴더구조는 다음과 같다.

 

/.dart_tool

/.idea

/android

/ios

/lib

/test

/web

.gitignore

.metadata

.packages

pubspec.lock

pubspeck.lock

pubspec.yaml

readme.md

temp.iml

 

[다음] 깃에 플러터 올리기

'Computer 비관심 > Flutter' 카테고리의 다른 글

파이어베이스 로그인  (0) 2020.11.06
플러터 스트럭처 만들기 작성중  (0) 2020.11.03
2. 깃허브에 플러터 올리기  (0) 2020.11.03
flutter sqflite 사용하기  (0) 2020.05.02
appBar 수정하기  (0) 2020.04.06

댓글()