전체 코드
클릭하면 전체 코드를 볼 수 있습니다.
import 'package:flutter/material.dart';
/// Flutter code sample for [TabBar].
void main() => runApp(const TabBarApp());
class TabBarApp extends StatelessWidget {
const TabBarApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(useMaterial3: true),
home: const TabBarExample(),
);
}
}
class TabBarExample extends StatelessWidget {
const TabBarExample({super.key});
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double gridBoxHeight = width / 3;
int count = 30;
double tabbarHeight = 50;
double tabControllerHeight = tabbarHeight +
(gridBoxHeight * ((count / 3) + (count % 3 > 0 ? 1 : 0)));
return Scaffold(
endDrawer: Container(
width: 200,
color: Colors.yellow,
),
appBar: AppBar(
leading: Icon(Icons.arrow_back_ios),
title: Text("Profile"),
centerTitle: true,
),
body: ListView(
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: 100,
height: 100,
child: CircleAvatar(
backgroundImage: AssetImage("assets/avatar.png"),
),
),
Padding(
padding: const EdgeInsets.only(left: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"GetinThere",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w700,
),
),
Text(
"프로그래머/작가/강사",
style: TextStyle(fontSize: 20),
),
Text(
"데어 프로그래밍",
style: TextStyle(fontSize: 15),
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TagWidget("50", "Posts"),
BlueLine(),
TagWidget("10", "Likes"),
BlueLine(),
TagWidget("3", "Share"),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
//ElevatedButton(onPressed: () {}, child: Text("버튼1")),
TextButton(
onPressed: () {},
child: Text("Follow"),
style: TextButton.styleFrom(
backgroundColor: Colors.blueAccent,
foregroundColor: Colors.white,
minimumSize: Size(200, 40),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)),
),
OutlinedButton(
onPressed: () {},
child: Text("Message"),
style: TextButton.styleFrom(
foregroundColor: Colors.black,
minimumSize: Size(200, 40),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)),
),
],
),
SizedBox(
height: tabControllerHeight,
child: DefaultTabController(
initialIndex: 0, // 시작 인덱스 0
length: 2,
child: Column(
children: [
const TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.directions_car_sharp),
),
Tab(
icon: Icon(Icons.directions_subway),
),
],
),
Expanded(
child: TabBarView(
children: <Widget>[
GridView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: count,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (context, index) {
return Image.network(
"https://picsum.photos/id/${151 + index}/100/100",
fit: BoxFit.cover,
);
},
),
Center(
child: Text("It's sunny here"),
),
],
),
),
],
),
),
),
],
),
);
}
}
class BlueLine extends StatelessWidget {
const BlueLine({
super.key,
});
@override
Widget build(BuildContext context) {
return Container(
width: 2,
height: 60,
color: Colors.blue,
);
}
}
class TagWidget extends StatelessWidget {
final text1;
final text2;
TagWidget(this.text1, this.text2);
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("${text1}", style: TextStyle(fontSize: 15)),
Text("${text2}", style: TextStyle(fontSize: 15))
],
);
}
}
참고사항 : dart 파일은 /로 나누면 정수가 아닌 소수점까지 나오기 때문에 기존 자바처럼 /를 이용하려면 ~/를 적어야 합니다.
debugShowCheckedModeBanner: false
MaterialApp
의 설정 중 하나로, 디버그 모드에서 오른쪽 상단에 표시되는 "DEBUG" 배너를 숨기기 위해 사용됩니다.
- 용도: 디버그 배너를 숨김으로써 UI를 깔끔하게 유지합니다.
theme: ThemeData(useMaterial3: true)
- 앱의 전체적인 테마를 설정하는 옵션입니다.
useMaterial3: true
는 Material Design 3을 사용하도록 설정합니다.
- 용도: 앱의 스타일과 디자인을 최신 Material Design 가이드라인에 맞게 설정합니다.
double width = MediaQuery.of(context).size.width
- 현재 화면의 너비를 가져와 변수
width
에 저장합니다.
- 용도: 화면 크기에 맞춰 동적인 레이아웃을 설정할 때 사용됩니다.
CircleAvatar
- 원형 아바타를 표시하는 위젯입니다.
backgroundImage
속성을 사용하여 이미지를 설정할 수 있습니다.
- 용도: 사용자 프로필 사진이나 아이콘을 원형으로 표시할 때 사용됩니다.
styleFrom
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))
)
-
TextButton
의 스타일을 지정하는 속성입니다.shape
속성을 사용하여 버튼의 모서리 반경을 설정합니다.
- 용도:
TextButton
의 모서리를 둥글게 만들어 더 세련된 디자인을 구현합니다.BorderRadius.circular(10)
을 사용하여 모서리 반경을 10으로 설정합니다.
버튼을 디자인 할 때는 styleFrom 을 이용하여 스타일을 지정하는 것이 좋습니다.
GridView.builder
GridView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: count,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 1,
mainAxisSpacing: 1,
),
itemBuilder: (context, index) {
return Image.network(
"https://picsum.photos/id/${151 + index}/100/100",
fit: BoxFit.cover,
);
},
);
- 위 예제는 스크롤이 비활성화된 상태에서 가로로 3개의 항목을 가지는 그리드 레이아웃을 생성합니다. 각 항목은
Image.network
를 사용하여 네트워크에서 이미지를 불러와 표시합니다.
- 주요 속성:
physics: NeverScrollableScrollPhysics()
: 그리드가 스크롤되지 않도록 설정합니다.itemCount: count
: 그리드 항목의 총 개수를 설정합니다.gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3)
: 가로에 3개의 항목이 있는 고정된 그리드 레이아웃을 설정합니다.itemBuilder
: 각 항목을 그리드에 추가하는 빌더 함수입니다.
완성된 출력 이미지

Tip. 코드 자동 완성 추가하기

- Live Templates - Flutter를 선택한 후 +버튼을 통해 Live Template 클릭

- 하단 Change 버튼 - Dart 체크

- 샘플 코드를 빨간 네모 안에 삽입 후 ok
Share article