레이아웃용 위젯들이 너무 길어진다면 커스텀 위젯(Custom Widget)을 이용하면 된다.
<커스텀 위젯 만드는 순서>
stless
+ Enter(Tab)class
작명return
오른쪽에 축약할 레이아웃 넣기- 원하는 위치에 위젯명() 추가하면 끝
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Widget_name(),
)
);
}
}
// 커스텀 위젯
class Widget_name extends StatelessWidget {
const Widget_name({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return SizedBox (
child: Text('안녕하세오 커스텀위젯이에오'),
);
}
}
<커스텀 위젯 문법 정리>
line1
class
: 위젯은 class로 만듦
extends
: 오른쪽 클래스를 복사하는 코드(복사해서 쓰면 코드 쓰기 간편해지니까)
line3
@override
: extends
코드로 기존 클래스를 복붙해서 위젯을 만들다보면 기존 클래스와 중복되는 부분이 생기는데 이 때 “내꺼 먼저 써주세요”라고 요청하는 코드
line4
build
: build라는 함수를 만듦(build라는 함수가 있어야 위젯으로 인정해줌)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: a,
)
);
}
}
var a = SizedBox (
child: Text('안녕하세오 커스텀위젯이에오'),
);
위 방법처럼 커스텀 위젯을 정의하지 않고 그냥 변수 a에 담아서 코드를 작성하는 방법도 있다.
변하지 않는 UI(로고, 상단바, 하단바 등)들은 변수에 담아서 써도 상관이 없다.
그러나 변하는 UI(좋아요 개수와 같이 반응형 개체)들은 성능 이슈 위험이 있다.
앱에 보여줄 항목이 너무 많아지면 하나하나 개체를 만들어주기 힘들어진다.
또한 항목이 많아진다고 해서 스크롤바가 저절로 생기지 않는다.
이 때 사용하는 위젯이 ListView
- 스크롤바가 생긴다.
- 스크롤 위치 감시가 편해진다.
- 메모리 절약이 가능하다 (화면에 나타나지 않는 부분들은 메모리에서 삭제할 수 있음)
ListView
를 사용해서 아래와 같은 연락처 목록을 만들어보려고 한다.
우선 ListTile을 이용해서 항목 하나를 구성해준다.
ListTile _tile(String title, String subtitle) => ListTile(
title: Text(title),
subtitle: Text(subtitle),
leading: Image.network("https://randomuser.me/api/portraits/women/10.jpg")
);
ListTile
오른쪽에는 클래스 이름을 설정해준다(_tile
)
클래스 이름 오른쪽에는 사용할 데이터를 데이터 타입과 함께 정의해준다. 위에서는 title
과 subtitle
두가지 데이터를 넣어 사용할 것이다.
화살표(=>
)를 이용해 ListTile
클래스로 연결시켜주고 여기서도 데이터를 한 줄 한 줄 정의해준다.
마지막 줄에 leading
은 항목 왼쪽에 해당 개체를 넣을 것임을 의미한다.
Image.network
는 이미지 주소를 이용해서 이미지 개체를 추가할 때 쓰인다.
(이미지는 Random User Generator | Home 링크에서 복붙해왔다)
여기까지 하면 다음과 같은 항목 하나가 만들어진다.
(title
은 ‘안녕하세요’, subtitle
은 ‘반가워요’로 설정된 상태)
위와 같이 항목을 만들었으면 이를 화면에 보여주어야 한다.
이때 Widget을 만들어서 화면에 보여주면 코드가 깔끔해진다.
Widget _buildList() => ListView(
children: [
_tile("안녕하세요", "반가워요"),
],
);
Widget 오른쪽에는 위젯 이름을 설정해준다.
화살표(=>)로 ListView
로 연결시켜준다음 children
아래에 위에서 만든 ListTile
항목(_tile
)을 연결시켜주면 끝
이제 위 항목을 여러개 붙여넣으면 다음과 같이 연락처 목록 완성
Widget _buildList() => ListView(
children: [
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
],
);
ClipRRect
를 이용하면 이미지를 둥글게 만들 수 있다.
ClipRRect _userImage(String url) => ClipRRect(
borderRadius: BorderRadius.circular(100),
child:Image.network(url)
);
ListTile을 정의할 때 처럼 ClipRRect
오른쪽에는 클래스 이름과 데이터를 정의해준다.
borderRadius
를 이용해서 이미지를 둥글게 만들어준다.
child
아래에는 Image.network(url)
코드로 이미지를 넣는다. url 부분에는 이미지 주소 데이터가 입력된다.
그리고 처음 사진처럼 여러개의 이미지를 랜덤으로 뿌려주기 위해서는 final
코드를 이용한다.
final images = [
"https://randomuser.me/api/portraits/women/10.jpg",
"https://randomuser.me/api/portraits/women/11.jpg",
"https://randomuser.me/api/portraits/women/14.jpg",
"https://randomuser.me/api/portraits/women/13.jpg",
"https://randomuser.me/api/portraits/women/24.jpg",
"https://randomuser.me/api/portraits/men/14.jpg",
"https://randomuser.me/api/portraits/men/13.jpg",
"https://randomuser.me/api/portraits/men/24.jpg",
"https://randomuser.me/api/portraits/men/25.jpg",
"https://randomuser.me/api/portraits/men/12.jpg",
];
final
오른쪽에 배열 이름을 정의하고 배열에 여러 이미지 주소들을 넣어주면 된다.
그리고 위에서 써준 ListTile
부분을 다음과 같이 수정해준다.
ListTile _tile(String title, String subtitle) => ListTile(
title: Text(title),
subtitle: Text(subtitle),
// leading: _userImage(images[Random().nextInt(images.length)]),
leading: _userImage(images[Random().nextInt(images.length)]),
);
수정된 부분 : leading: _userImage(images[Random().nextInt(images.length)]),
이미지를 보여줄 때 images
요소에서 랜덤으로 항목을 가져와 이미지로 보여주겠다는 의미이다.
단, Random 함수를 쓰기 위해서는 코드 맨 위에 import 'dart:math';
를 만드시 써줘야함!
즉, images.length에 해당하는 갯수의 요소에서 랜덤으로 요소를 가져와 _userImage 함수안에 넣어 사용하겠다는 의미
이렇게 하면 다음과 같이 연락처 목록이 완성된다.
전체 코드
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("연락처"),),
body: Center(child: _buildList()),
bottomNavigationBar: BottomAppBar(),
),
);
}
}
Widget _buildList() => ListView(
children: [
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
_tile("안녕하세요", "반가워요"),
],
);
ListTile _tile(String title, String subtitle) => ListTile(
title: Text(title),
subtitle: Text(subtitle),
// leading: _userImage(images[Random().nextInt(images.length)]),
leading: _userImage(images[Random().nextInt(images.length)]),
);
ClipRRect _userImage(String url) => ClipRRect(
borderRadius: BorderRadius.circular(100),
child:Image.network(url)
);
final images = [
"https://randomuser.me/api/portraits/women/10.jpg",
"https://randomuser.me/api/portraits/women/11.jpg",
"https://randomuser.me/api/portraits/women/14.jpg",
"https://randomuser.me/api/portraits/women/13.jpg",
"https://randomuser.me/api/portraits/women/24.jpg",
"https://randomuser.me/api/portraits/men/14.jpg",
"https://randomuser.me/api/portraits/men/13.jpg",
"https://randomuser.me/api/portraits/men/24.jpg",
"https://randomuser.me/api/portraits/men/25.jpg",
"https://randomuser.me/api/portraits/men/12.jpg",
];
<참조>
개발하는 정대리 플러터 앱만들기 강좌 리스트뷰 - Flutter fundamental Tutorial (2021) - ListView
코딩애플 쉬운 플러터 6강 : 중요한 커스텀 위젯 문법