에러 관련
[플러터] 에러 발생 및 해결
1. Gradle build failed to produce an .apk file...import 'package:flutter/material.dart';void main() { runApp( MaterialApp( // 머터리얼 디자인 위젯 home: Scaffold( // Scaffold 위젯 body: Center( // 가운데 정렬 child: Text( // Text 위젯 'He
puppy-foot-it.tistory.com
◆ 깃허브 업로드 관련
[플러터] 대용량 파일 깃허브 업로드하기 (안드로이드 스튜디오)
대용량 파일 깃허브 업로드(안드로이드 스튜디오) 플러터 공부를 하다가 만들어둔 작업물들을 깃허브에 올리려고 하는데, 파일 용량이 크고, 파일 갯수도 많아서 GUI로 업로드가 안 된다. 이전에
puppy-foot-it.tistory.com
플러터
https://flutter.dev/multi-platform
플러터는 구글(Google)에서 개발한 UI 툴킷으로, 한 번의 코드 작성으로 여러 플랫폼에서 애플리케이션을 개발할 수 있도록 도와준다.
플러터는 하나의 소스 코드로 여러 플랫폼(안드로이드, IOS, 웹 앱, 윈도우, macOS, Linux 등)에 출시할 수 있는 크로스 플랫폼이다.
※ 크로스 플랫폼(cross-platform)
크로스 플랫폼은 동일한 코드베이스를 사용하여 여러 플랫폼을 위한 애플레케이션을 개발하는 방법이다.
◆ 안드로이드 스튜디오로 플러터 시작하기
안드로이드 스튜디오를 설치한 뒤,
[Android] Android Studio 다운 받기
자바 안드로이드란? 자바(Java)는 안드로이드 애플리케이션 개발에 가장 널리 사용되는 프로그래밍 언어 중 하나이다. 자바를 사용하여 안드로이드 앱을 개발함으로써, 많은 개발자들이 안정적
puppy-foot-it.tistory.com
실행하면 초기 화면에서 [Plugins] 를 누르면 Flutter 가 보이는데 install 을 눌러 설치
설치 후 안드로이드 스튜디오를 재시작
안드로이드 스튜디오가 재시작하면 'New Flutter Project'가 나타나는 것을 확인할 수 있다.
웹 앱
앞서 말했듯, 플러터는 크로스 플랫폼으로 모바일이 지원되는 웹 사이트를 비교적 간단하게 웹 앱으로 만들 수 있다.
웹 앱(Web Application)은 웹 브라우저를 통해 사용자에게 제공되는 소프트웨어 애플리케이션으로, 일반적으로 웹 앱은 인터넷에 연결된 장치에서 실행되며, 사용자는 별도의 설치 과정 없이 웹 브라우저를 통해 접근할 수 있다.
[웹 앱 특징]
- 브라우저 기반:
웹 앱은 웹 브라우저에서 작동하므로, 사용자는 다양한 운영 체제(Windows, macOS, Linux 등)와 디바이스(데스크탑, 태블릿, 스마트폰)에서 접근할 수 있다. - 플랫폼 독립성:
한 번 개발된 웹 앱은 다양한 플랫폼에서 작동할 수 있어 특별한 환경에 구애받지 않고 애플리케이션을 사용할 수 있다. - 자동 업데이트:
웹 앱은 서버 측에서 구동되므로, 사용자는 별도의 업데이트 과정을 거치지 않아도 최신 버전의 소프트웨어를 사용할 수 있다. - 데이터 저장 및 처리:
웹 앱은 서버에서 데이터베이스와 연동하여 사용자 데이터를 저장하고 처리할 수 있다. 이를 통해 사용자는 로그인 기능, 데이터 분석, 파일 업로드와 같은 여러 기능을 사용할 수 있다.
▶ 따라서, 접근성이 좋고 비용과 실감을 절약할 수 있으며, 유지보수가 용이하다.
단, 속도가 조금 느리고 애니메이션이 부자연스럽다는 단점이 있다.
웹 앱 구현
[웹 앱 구현 관련 중요 개념]
웹 앱을 구현하기 위해서는 웹뷰와 앱바, 콜백 함수에 대해서 알아두면 좋다.
- 웹뷰: 프레임워크에 내장된 브라우저를 앱의 네이티브 컴포넌트에 임베딩 하는 기능으로, 웹사이트의 URL을 입력하면 해당 웹사이트를 화면에 보여주는 역할 수행.
※ 웹뷰 구현 때 사용할 위젯들은 controller 파라미터에 WebViewController 객체를 입력해줘야 하는데, 웹뷰 컨트롤러는 웹뷰 위젯을 제어하는데 필요한 기능들을 제공해 준다.
- 앱바: 머티리얼 디자인 요소로, 앱 맨 위에 페이지 이름이나 앱 이름 같은 형태의 UI를 그려주는 위젯.
- 콜백 함수: 정의해두면 특정 조건이 성립될 때 실행되는 함수.
★ 네이티브 컴포넌트, 임베딩
- 네이티브 컴포넌트: 특정 플랫폼에서 직접 실행되는 애플리케이션의 구성 요소로, 높은 성능과 사용자 경험 제공.
- 임베딩: 하나의 시스템 내에 다른 요소를 포함시키는 과정. ex) 웹 콘텐츠를 네이티브 앱에 통합.
◆ 웹 앱 구현하기
플러터 홈페이지를 웹 앱으로 구현해 본다.
또한, 홈버튼 / 뒤로 가기 / 앞으로 가기 버튼을 추가하여 해당 버튼이 눌렸을 때 특정 페이지로 이동하는 기능도 추가한다.
[초기 설정]
1. pubspec.yaml 파일: Flutter 프로젝트 관련 설정
프로젝트에서 사용할 이미지 및 폰트를 지정하거나 사용할 오픈 소스 프로젝트를 명시할 때 사용하는 파일로, 여기서는 웹뷰를 사용해야 하기 때문에 webview_flutter 플러그인을 추가해 준다.
webview_flutter: ^4.10.0
2. android/app/src/main/AndroidManifest.xml: 권한 및 네이티브 설정
웹뷰를 사용하기 위해서 몇 가지 설정이 필요하다.
- 인터넷 사용 권한 추가
<uses-permission android:name="android.permission.INTERNET" />
- https, http 프로토콜 이용할 수 있게 설정
// <application 가장 아래에
android:usesCleartextTraffic="true" >
★ 안드로이드 권한 관련
<uses-permission android:name="android.permission.권한 코드" />
권한 코드 | 설명 | 필요한 상황 예시 |
INTERNET | 인터넷에 접근할 수 있는 권한을 앱에 부여. | 웹뷰(WebView), API 호출, Firebase 등 외부 서버와 통신할 때 |
VIBARATE | 진동을 일으킬 수 있는 권한. | 알람이나 기타 설정 시 진동이 필요할 때 |
ACCESS_NETWORK_STATE | 현재 네트워크 상태(와이파이, 모바일 데이터 등)를 확인. | 네트워크 연결 상태에 따라 다른 동작을 하도록 할 때 (예: "인터넷 연결이 필요합니다") |
CAMERA | 카메라를 사용할 수 있는 권한. | 사진 촬영, 스캔 기능 등 |
RECORD_AUDIO | 마이크를 사용할 수 있는 권한. | 음성 녹음, 음성 채팅 기능 등 |
BILLING | 인앱 결제 가능 권한. | 앱에 결제 기능이 필요할 때 |
CALL_PHONE | 전화기 앱을 사용치 않고 전화를 할 수 있는 권한. | 앱에 전화 기능이 필요할 때 |
READ_EXTERNAL_STORAGE | 외부 저장소(사진, 파일 등)를 읽을 수 있는 권한. | 갤러리에서 이미지 불러오기 |
WRITE_EXTERNAL_STORAGE | 외부 저장소에 데이터를 쓸 수 있는 권한. | 파일 다운로드 및 저장 기능 |
ACCESS_FINE_LOCATION | GPS를 통해 정확한 위치를 확인할 수 있는 권한. | 지도 앱, 위치 기반 서비스 |
ACCESS_COARSE_LOCATION | Wi-Fi 또는 셀룰러 네트워크로 대략적인 위치 확인. | 배터리 절약 모드의 위치 확인 등 |
ACCESS_BACKGROUND_LOCATION | 앱이 배경에 있을 때 위치 정보를 얻을 수 있는 권한. | 지도 앱, 위치 기반 서비스 |
※ Android 6.0 (API 23) 이상에서는 일부 권한(예: 카메라, 위치, 오디오 등)은 실행 중 사용자에게 직접 요청해야 하며, (INTERNET은 자동 허용) 권한을 추가하지 않으면 관련 기능이 작동하지 않거나 앱이 크래시 날 수 있다.
[최종 디렉터리 경로]
- lib 디렉터리: Flutter 애플리케이션의 핵심 코드와 기능이 위치하는 곳으로, 소스 코드의 구조화, 모듈화 및 프로젝트 유지보수에 중요한 역할
- screen 디렉터리: 화면 구성과 관련된 모든 위젯이 모여지는 디렉터리
- home_screen.dart: 홈 화면 구성 (위젯, 기능 등)
- main.dart: 애플리케이션이 시작되는 진입점(Entry Point)
* main.dart
import 'package:flutter/material.dart';
import 'package:wep_app/screen/home_screen.dart';
void main() {
// 플러터 프레임워크가 앱을 실행할 준비가 될 때까지 대기
WidgetsFlutterBinding.ensureInitialized();
runApp(
MaterialApp(
home: HomeScreen(),
),
);
- 코드 설명 -
구문 | 설명 |
WidgetsFlutterBinding.ensureInitialized(); | Flutter 엔진과의 연결 보장. 예를 들어 WebView 같은 비동기 초기화가 필요한 경우 필수. |
runApp(...) | Flutter 앱 실행. 전체 UI의 시작점. |
MaterialApp(...) | 구글 머티리얼 디자인 스타일의 앱 생성. 테마, 라우팅, 네비게이션 등을 관리. |
home: HomeScreen() | 앱 실행 시 가장 먼저 보여줄 화면(위젯)을 HomeScreen으로 설정. |
* home_screen.dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart'; // 웹뷰 플러그인
class HomeScreen extends StatelessWidget {
//WebViewController 선언
WebViewController webViewController = WebViewController()
// WebViewController의 loadRequest() 함수 실행
..loadRequest(Uri.parse('https://flutter.dev'))
// Javascript 가 제한 없이 실행될 수 있도록 설정
..setJavaScriptMode(JavaScriptMode.unrestricted);
HomeScreen({Key? key}): super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar( // 앱바 위젯 추가
backgroundColor: Colors.greenAccent, // 배경색 지정
title: Text('Recordian'), // 앱 타이틀 설정
centerTitle: true, // 가운데 정렬
// AppBar에 액션 버튼 추가
actions: [
IconButton(
onPressed: () { // 아이콘 눌렀을 때 실행할 콜백 함수
// 웹뷰 위젯에서 사이트 전환
webViewController.loadRequest(Uri.parse('https://flutter.dev'));
},
// 홈 버튼 아이콘
icon: Icon(
Icons.home,
),
),
],
),
body: Column(
children: [
Expanded(
child: WebViewWidget(controller: webViewController),
),
Container(
color: Colors.grey[100],
padding: EdgeInsets.symmetric(vertical: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
tooltip: 'Back',
icon: Icon(Icons.arrow_back),
onPressed: () async {
if (await webViewController.canGoBack()) {
webViewController.goBack();
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('더 이상 뒤로 갈 수 없습니다.')),
);
}
},
),
IconButton(
tooltip: 'Forward',
icon: Icon(Icons.arrow_forward),
onPressed: () async {
if (await webViewController.canGoForward()) {
webViewController.goForward();
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('더 이상 앞으로 갈 수 없습니다.')),
);
}
},
),
],
)
)
]
),
);
}
}
- 코드 설명 -
구문 | 설명 |
WebViewController | 웹뷰를 제어하기 위한 컨트롤러. 웹 페이지를 로드하거나 이동 가능. |
..loadRequest(...) | 처음 앱이 실행되면 보여줄 웹 페이지 URL 설정. (flutter.dev) |
..setJavaScriptMode(JavaScriptMode.unrestricted) | 자바스크립트 사용 허용. (unrestricted는 제한 없이 실행 가능) |
AppBar | 앱 상단의 타이틀 바. 타이틀과 홈 버튼 포함되어 있음. |
WebViewWidget | 웹 페이지를 보여주는 위젯. |
Expanded | 화면의 나머지 영역을 웹뷰가 차지하도록 설정. |
IconButton (뒤로 가기) | webViewController.canGoBack()으로 가능한 경우, 이전 페이지로 이동. |
IconButton (앞으로 가기) | webViewController.canGoForward()로 가능한 경우, 다음 페이지로 이동. |
SnackBar | 더 이상 이동할 수 없을 때 사용자에게 알림을 띄움. |
- AppBar 위젯
- AppBar 위젯은 Scaffold 위젯의 appBar 매개변수로 넣음.
- backgroundColor: Colors.색상: AppBar의 배경색 지정.
- title: Text('제목'): AppBar 중간에 넣을 텍스트 (제목) 설정.
- centerTitle: true : 제목을 가운데 정렬.
- AppBar 위젯: 홈버튼 관련
- actions: [ IconButton( : AppBar에 액션 버튼 추가
- onPressed: () { : 해당 아이콘 눌렀을 때 실행할 콜백 함수
- icon: Icon( Icons.home, : 홈 버튼 아이콘 설정
- 웹뷰 위젯
웹뷰 위젯은 화면에 웹뷰를 렌더링하여 사이트의 화면 출력
controller: webViewController: 웹뷰 위젯을 제어할 수 있는 컨트롤러 파라미터 입력 받음
- 웹뷰 컨트롤러
- 웹뷰 위젯을 제어하는 역할
- 웹뷰 컨트롤러의 함수를 실행하여 웹뷰 위젯을 제어 가능
- loadRequest(): Uri 객체를 매개변수로 입력받아 지정한 사이트로 이동
- Uri.parse(): 괄호 안에 이동하고 싶은 사이트의 URL 입력
- 뒤로 가기, 앞으로 가기 버튼
- goBack() : 뒤로 가기
- goForward() : 앞으로 가기
- canGoBack(), canGoForward() : 뒤/앞으로 가능한지 확인
- SnackBar : 버튼을 눌렀을 때 이동이 불가능한 경우를 대비해서 SnackBar를 띄워 사용자에게 알려줌.
[웹앱 레이아웃]
-------------------------
| AppBar |
| [Recordian] [Home] |
-------------------------
| |
| WebView 화면 |
| (https://flutter.dev) |
| |
|-----------------------|
| ◀ Back ▶ Forward |
-------------------------
[실행 화면]
[참고]
코드팩토리의 플러터 프로그래밍
다음 내용
[플러터] 이미지 롤링 기능 구현하기
이전 내용 [플러터] 웹 앱 만들어보기에러 관련 [플러터] 에러 발생 및 해결1. Gradle build failed to produce an .apk file...import 'package:flutter/material.dart';void main() { runApp( MaterialApp( // 머터리얼 디자인 위젯 h
puppy-foot-it.tistory.com
'[앱개발] > Flutter, Dart, Figma' 카테고리의 다른 글
[플러터] 안드로이드 스튜디오로 플러터 시작하기 (0) | 2025.05.23 |
---|---|
[플러터] D-Day 앱 만들기 (feat. 폰트 반영하기, Cupertino 위젯) (0) | 2025.05.23 |
[플러터] 이미지 롤링 기능 구현하기(feat. 위젯 생명주기) (0) | 2025.05.22 |
[플러터] pub 명령어 (0) | 2025.05.22 |
[플러터] 에러 발생 및 해결 (1) | 2025.05.21 |