종류
- MaterialPageRoute()
- CupertinoPageRoute()
- 슬라이드 전환
- import 'package:flutter/cupertino.dart' 상단에 추가해야함
- PageRouteBuilder()
1. 전체 커스터마이징
MaterialPageRoute()
- 페이지 전환 애니메이션
GestureDetector(
child: Text(widget.data[i]['user']),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (c) => Profile())
);
},
),
CupertinoPageRoute()
- 오른쪽에서 왼쪽으로 보이는 애니메이션
GestureDetector(
child: Text(widget.data[i]['user']),
onTap: () {
Navigator.push(context,
CupertinoPageRoute(builder: (c) => Profile())
);
},
),
PageRouteBuilder()
- 오른쪽에서 왼쪽으로 서서히 보이는 애니메이션
Navigator.push(context,
PageRouteBuilder(
pageBuilder: (c, a1, a2) => Upload(),
transitionsBuilder: (c, a1, a2, child) => FadeTransition(opacity: a1, child: child),
transitionDuration: Duration(milliseconds : 500),
),
)
- pageBuilder: 에는 보여줄 페이지를 return
- transitionsBuilder: 는 파라미터 4개를 입력하고 애니메이션을 return
- 첫째는 context (쓸데없음)
- 둘째는 0에서 1로 증가하는 애니메이션 숫자 (새로운 페이지에 씀)
- 셋째는 0에서 1로 증가하는 애니메이션 숫자 (기존에 보이던 페이지에 씀)
- 넷째는 현재 보여주는 위젯
- FadeTransition()
- opacity: 애니메이션 숫자
- child: 보여줄 위젯
- 이렇게 작성하면 특정 위젯을 서서히 opacity를 0에서 1로 보여줄 수 있음
- transitionDuration : Duration(milliseconds : 500) 이걸로 몇초간 동작할지 설정 가능
- FadeTransition 말고 SlideTransition 써도 됨
SlideTransition( position: Tween( begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0), ).animate(a1), child: child, )
- 위젯 위치 변경하려면 PositionedTransition()
- 위젯 사이즈를 변경하려면 ScaleTransition()
- 위젯을 가렸다가 보여주려면 SizeTransition()
- 위젯을 회전시키려면 RotationTransition()
Hero()
- 두 페이지 간에 똑같은 위젯이 있을 때 그걸 유지하면서 페이지 전환하고 싶은 경우 사용
전체 코드
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import './style.dart' as style;
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter/rendering.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
void main() {
runApp(
MaterialApp(
theme: style.theme,
home: MyApp()
));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var tab = 0; // 1. 현재 상태 저장
var list = [1, 2, 3];
var map = {'name':'john', 'age':20};
var data = [];
var userImage; // 유저가 삽입한 이미지 저장 공간
var userContent; // 유저가 입력한 글 저장 공간
saveData() async {
var storage = await SharedPreferences.getInstance();
var map = {'age' : 20};
storage.setString('map', jsonEncode(map));
var result = storage.getString('map') ?? '업는데요';
print(jsonDecode(result)['age']);
}
addMyData() {
var myData = {
'id': data.length,
'image': userImage,
'likes': 5,
'date': 'July 25',
'content': userContent,
'liked': false,
'user': 'John Kim'
};
setState(() {
data.insert(0, myData);
});
}
setUserContent(a) {
setState(() {
userContent = a;
});
}
addData(a) {
setState(() {
data.add(a);
});
}
getData() async {
var result = await http.get(Uri.parse('https://codingapple1.github.io/app/data.json'));
var result2 = jsonDecode(result.body);
setState(() {
data = result2;
});
}
@override
void initState() {
super.initState();
saveData();
getData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Instagram'),
actions: [
IconButton(
icon: Icon(Icons.add_box_outlined),
onPressed: () async {
var picker = ImagePicker();
var image = await picker.pickImage(source: ImageSource.gallery);
if(image != null) {
setState(() {
userImage = File(image.path);
});
}
Navigator.push(context,
MaterialPageRoute(builder: (c) => Upload( userImage : userImage, setUserContent : setUserContent, addMyData : addMyData) )
);
},
iconSize: 30,
)
]),
body: [Home(data : data, addData : addData), Text('샵페이지')][tab], // 2. state에 따라 tab 보이는 상태 변경
bottomNavigationBar: BottomNavigationBar(
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: (i){
setState(() {
tab = i;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: '홈'),
BottomNavigationBarItem(icon: Icon(Icons.shopping_bag_outlined), label: '샵')
],
),
);
}
}
class Home extends StatefulWidget {
const Home({Key? key, this.data, this.addData}) : super(key: key);
final data, addData;
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
var scroll = ScrollController();
getMore() async {
var result = await http.get(Uri.parse('https://codingapple1.github.io/app/more1.json'));
var result2 = jsonDecode(result.body);
widget.addData(result2);
}
@override
void initState() {
super.initState();
scroll.addListener(() { // 스크롤바 높이 측정 코드
if(scroll.position.pixels == scroll.position.maxScrollExtent) {
getMore();
}
});
}
@override
Widget build(BuildContext context) {
if (widget.data.isNotEmpty) {
return ListView.builder(
itemCount: widget.data.length,
controller: scroll,
itemBuilder: (c, i) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.data[i]['image'].runtimeType == String ? Image.network(widget.data[i]['image']) : Image.file(widget.data[i]['image']),
Container(
constraints: BoxConstraints(maxWidth: 600),
padding: EdgeInsets.all(20),
width: double.infinity,
child: Column(
children: [
GestureDetector(
child: Text(widget.data[i]['user']),
onTap: () {
Navigator.push(context,
PageRouteBuilder(pageBuilder: (c, a1, a2) => Profile(),
transitionsBuilder: (c, a1, a2, child) =>
FadeTransition(opacity: a1, child: child)
)
);
},
),
Text('좋아요 ${widget.data[i]['likes'].toString()}'),
Text(widget.data[i]['date']),
Text(widget.data[i]['content'])
],
),
)
],
);
}
);
} else {
return Text('로딩중임');
}
}
}
class Upload extends StatelessWidget {
const Upload({Key? key, this.userImage, this.setUserContent, this.addMyData}) : super(key: key);
final userImage, setUserContent, addMyData;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(actions: [
IconButton(onPressed: () {
addMyData();
}, icon: Icon(Icons.send))
],),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton(
onPressed: (){
Navigator.pop(context);
},
icon: Icon(Icons.close)
),
Image.file(userImage),
Text('이미지업로드화면'),
TextField(onChanged: (text) { // text는 유저가 입력한 글
setUserContent(text); // TextField()에 입력값 변할 때마다 onChanged 안의 함수가 실행됨
},),
],
)
);
}
}
class Profile extends StatelessWidget {
const Profile({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Text('프로필페이지')
);
}
}
'Web & Android > Flutter' 카테고리의 다른 글
[Flutter] 친구 팔로우 하기 (1) | 2023.09.23 |
---|---|
[Flutter] Provider : 3-step 다른 방법 (0) | 2023.09.23 |
[Flutter] 위젯 클릭 - GestureDetector (0) | 2023.09.22 |
[Flutter] DB 없이 데이터 저장하기 - Shared preferences (0) | 2023.09.22 |
[Flutter] 폰에 저장된 이미지 가져오기 (0) | 2023.09.22 |