NyState
Giriş
NyState, standart Flutter State sınıfının genişletilmiş bir versiyonudur. Sayfalarınızın ve widget'larınızın durumunu daha verimli bir şekilde yönetmenize yardımcı olmak için ek işlevsellik sağlar.
Durumla normal bir Flutter durumu gibi etkileşim kurabilirsiniz, ancak NyState'in ek avantajlarıyla birlikte.
NyState'in nasıl kullanılacağını inceleyelim.
NyState Nasıl Kullanılır
Bu sınıfı genişleterek kullanmaya başlayabilirsiniz.
Örnek
class _HomePageState extends NyState<HomePage> {
@override
get init => () async {
};
@override
view(BuildContext context) {
return Scaffold(
body: Text("The page loaded")
);
}
init metodu, sayfanın durumunu başlatmak için kullanılır. Bu metodu async ile veya async olmadan kullanabilirsiniz; arka planda async çağrıyı yönetecek ve bir yükleyici görüntüleyecektir.
view metodu, sayfa için arayüzü görüntülemek amacıyla kullanılır.
NyState ile yeni bir stateful widget oluşturma
Nylo Website'da yeni bir stateful widget oluşturmak için aşağıdaki komutu çalıştırabilirsiniz.
metro make:stateful_widget ProfileImage
Yükleme Stili
Sayfanız için yükleme stilini ayarlamak amacıyla loadingStyle özelliğini kullanabilirsiniz.
Örnek
class _ProfileImageState extends NyState<ProfileImage> {
@override
LoadingStyleType get loadingStyle => LoadingStyleType.normal();
@override
get init => () async {
await sleep(3); // simulate a network call for 3 seconds
};
Varsayılan loadingStyle, yükleme Widget'ınız (resources/widgets/loader_widget.dart) olacaktır.
Yükleme stilini güncellemek için loadingStyle'ı özelleştirebilirsiniz.
İşte kullanabileceğiniz farklı yükleme stillerinin tablosu: // normal, skeletonizer, none
| Stil | Açıklama |
|---|---|
| normal | Varsayılan yükleme stili |
| skeletonizer | İskelet yükleme stili |
| none | Yükleme stili yok |
Yükleme stilini şu şekilde değiştirebilirsiniz:
@override
LoadingStyle get loadingStyle => LoadingStyle.normal();
// or
@override
LoadingStyle get loadingStyle => LoadingStyle.skeletonizer();
Stillerden birindeki yükleme Widget'ını güncellemek istiyorsanız, LoadingStyle'a bir child geçirebilirsiniz.
@override
LoadingStyle get loadingStyle => LoadingStyle.normal(
child: Center(
child: Text("Loading..."),
),
);
// same for skeletonizer
@override
LoadingStyle get loadingStyle => LoadingStyle.skeletonizer(
child: Container(
child: PageLayoutForSkeletonizer(),
)
);
Şimdi, sekme yüklenirken "Loading..." metni görüntülenecektir.
Aşağıdaki örnek:
class _HomePageState extends NyState<HomePage> {
get init => () async {
await sleep(3); // simulate a network call for 3 seconds
};
@override
LoadingStyle get loadingStyle => LoadingStyle.normal(
child: Center(
child: Text("Loading..."),
),
);
@override
Widget view(BuildContext context) {
return Scaffold(
body: Text("The page loaded")
);
}
...
}
Durum Eylemleri
Nylo'da, Widget'larınızda diğer sınıflardan çağrılabilecek küçük eylemler tanımlayabilirsiniz. Bu, bir widget'ın durumunu başka bir sınıftan güncellemek istediğinizde kullanışlıdır.
Öncelikle, eylemlerinizi widget'ınızda tanımlamalısınız. Bu, NyState ve NyPage için çalışır.
class _MyWidgetState extends NyState<MyWidget> {
@override
get init => () async {
// handle how you want to initialize the state
};
@override
get stateActions => {
"hello_world_in_widget": () {
print('Hello world');
},
"update_user_name": (User user) async {
// Example with data
_userName = user.name;
setState(() {});
},
"show_toast": (String message) async {
showToastSuccess(description: message);
},
};
}
Ardından, stateAction metodunu kullanarak eylemi başka bir sınıftan çağırabilirsiniz.
stateAction('hello_world_in_widget', state: MyWidget.state);
// Another example with data
User user = User(name: "John Doe");
stateAction('update_user_name', state: MyWidget.state, data: user);
// Another example with data
stateAction('show_toast', state: MyWidget.state, data: "Hello world");
stateActions'ı bir NyPage ile kullanıyorsanız, sayfanın path'ini kullanmalısınız.
stateAction('hello_world_in_widget', state: ProfilePage.path);
// Another example with data
User user = User(name: "John Doe");
stateAction('update_user_name', state: ProfilePage.path, data: user);
// Another example with data
stateAction('show_toast', state: ProfilePage.path, data: "Hello world");
StateAction adında başka bir sınıf da vardır; widget'larınızın durumunu güncellemek için kullanabileceğiniz birkaç metodu bulunmaktadır.
refreshPage- Sayfayı yenile.pop- Sayfayı kaldır.showToastSorry- Üzgünüz toast bildirimi göster.showToastWarning- Uyarı toast bildirimi göster.showToastInfo- Bilgi toast bildirimi göster.showToastDanger- Tehlike toast bildirimi göster.showToastOops- Hata toast bildirimi göster.showToastSuccess- Başarı toast bildirimi göster.showToastCustom- Özel toast bildirimi göster.validate- Widget'ınızdaki verileri doğrula.changeLanguage- Uygulamadaki dili değiştir.confirmAction- Onay eylemi gerçekleştir.
Örnek
class _UpgradeButtonState extends NyState<UpgradeButton> {
view(BuildContext context) {
return Button.primary(
onPressed: () {
StateAction.showToastSuccess(UpgradePage.state,
description: "You have successfully upgraded your account",
);
},
text: "Upgrade",
);
}
}
Widget durum yönetimli olduğu sürece, uygulamanızdaki herhangi bir sayfa/widget'ın durumunu güncellemek için StateAction sınıfını kullanabilirsiniz.
Yardımcılar
Reboot
Bu metot, durumunuzdaki init metodunu yeniden çalıştıracaktır. Sayfadaki verileri yenilemek istediğinizde kullanışlıdır.
Örnek
class _HomePageState extends NyState<HomePage> {
List<User> users = [];
@override
get init => () async {
users = await api<ApiService>((request) => request.fetchUsers());
};
@override
Widget view(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Users"),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
reboot(); // refresh the data
},
)
],
),
body: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return Text(users[index].firstName);
}
),
);
}
}
Pop
pop - Mevcut sayfayı yığından kaldırır.
Örnek
class _HomePageState extends NyState<HomePage> {
popView() {
pop();
}
@override
Widget view(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: popView,
child: Text("Pop current view")
)
);
}
showToast
Bağlamda bir toast bildirimi gösterir.
Örnek
class _HomePageState extends NyState<HomePage> {
displayToast() {
showToast(
title: "Hello",
description: "World",
icon: Icons.account_circle,
duration: Duration(seconds: 2),
style: ToastNotificationStyleType.INFO // SUCCESS, INFO, DANGER, WARNING
);
}
@override
Widget view(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: displayToast,
child: Text("Display a toast")
)
);
}
validate
validate yardımcısı, veriler üzerinde bir doğrulama kontrolü gerçekleştirir.
Doğrulayıcı hakkında daha fazla bilgiyi buradan öğrenebilirsiniz.
Örnek
class _HomePageState extends NyState<HomePage> {
TextEditingController _textFieldControllerEmail = TextEditingController();
handleForm() {
String textEmail = _textFieldControllerEmail.text;
validate(rules: {
"email address": [textEmail, "email"]
}, onSuccess: () {
print('passed validation')
});
}
changeLanguage
Cihazda kullanılan json /lang dosyasını değiştirmek için changeLanguage'i çağırabilirsiniz.
Yerelleştirme hakkında daha fazla bilgiyi buradan öğrenebilirsiniz.
Örnek
class _HomePageState extends NyState<HomePage> {
changeLanguageES() {
await changeLanguage('es');
}
@override
Widget view(BuildContext context) {
return Scaffold(
body: InkWell(
onTap: changeLanguageES,
child: Text("Change Language".tr())
)
);
}
whenEnv
Uygulamanız belirli bir durumda olduğunda bir fonksiyon çalıştırmak için whenEnv'i kullanabilirsiniz.
Örneğin, .env dosyanızdaki APP_ENV değişkeni 'developing' olarak ayarlanmışsa, APP_ENV=developing.
Örnek
class _HomePageState extends NyState<HomePage> {
TextEditingController _textEditingController = TextEditingController();
@override
get init => () {
whenEnv('developing', perform: () {
_textEditingController.text = 'test-email@gmail.com';
});
};
lockRelease
Bu metot, bir fonksiyon çağrıldıktan sonra durumu kilitler; yalnızca metot tamamlandığında sonraki isteklere izin verilir. Bu metot ayrıca durumu günceller; kontrol etmek için isLocked kullanın.
lockRelease'i göstermek için en iyi örnek, kullanıcının 'Giriş Yap' düğmesine bastığı bir giriş ekranı hayal etmektir. Kullanıcıyı giriş yaptırmak için async bir çağrı gerçekleştirmek istiyoruz, ancak istenmeyen bir deneyim yaratabileceğinden metodun birden çok kez çağrılmasını istemiyoruz.
İşte aşağıdaki örnek.
class _LoginPageState extends NyState<LoginPage> {
_login() async {
await lockRelease('login_to_app', perform: () async {
await Future.delayed(Duration(seconds: 4), () {
print('Pretend to login...');
});
});
}
@override
Widget view(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isLocked('login_to_app'))
AppLoader(),
Center(
child: InkWell(
onTap: _login,
child: Text("Login"),
),
)
],
)
);
}
_login metoduna dokunduğunuzda, orijinal istek tamamlanana kadar sonraki istekleri engelleyecektir. isLocked('login_to_app') yardımcısı, düğmenin kilitli olup olmadığını kontrol etmek için kullanılır. Yukarıdaki örnekte, yükleme Widget'ımızı ne zaman görüntüleyeceğimizi belirlemek için bunu kullandığımızı görebilirsiniz.
isLocked
Bu metot, lockRelease yardımcısı kullanılarak durumun kilitli olup olmadığını kontrol eder.
Örnek
class _HomePageState extends NyState<HomePage> {
@override
Widget view(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (isLocked('login_to_app'))
AppLoader(),
],
)
);
}
view
view metodu, sayfa için arayüzü görüntülemek amacıyla kullanılır.
Örnek
class _HomePageState extends NyState<HomePage> {
@override
Widget view(BuildContext context) {
return Scaffold(
body: Center(
child: Text("My Page")
)
);
}
}
confirmAction
confirmAction metodu, bir eylemi onaylamak için kullanıcıya bir iletişim kutusu gösterecektir.
Bu metot, devam etmeden önce kullanıcının bir eylemi onaylamasını istediğinizde kullanışlıdır.
Örnek
_logout() {
confirmAction(() {
// logout();
}, title: "Logout of the app?");
}
showToastSuccess
showToastSuccess metodu, kullanıcıya bir başarı toast bildirimi gösterecektir.
Örnek
_login() {
...
showToastSuccess(
description: "You have successfully logged in"
);
}
showToastOops
showToastOops metodu, kullanıcıya bir hata toast bildirimi gösterecektir.
Örnek
_error() {
...
showToastOops(
description: "Something went wrong"
);
}
showToastDanger
showToastDanger metodu, kullanıcıya bir tehlike toast bildirimi gösterecektir.
Örnek
_error() {
...
showToastDanger(
description: "Something went wrong"
);
}
showToastInfo
showToastInfo metodu, kullanıcıya bir bilgi toast bildirimi gösterecektir.
Örnek
_info() {
...
showToastInfo(
description: "Your account has been updated"
);
}
showToastWarning
showToastWarning metodu, kullanıcıya bir uyarı toast bildirimi gösterecektir.
Örnek
_warning() {
...
showToastWarning(
description: "Your account is about to expire"
);
}
showToastSorry
showToastSorry metodu, kullanıcıya bir üzgünüz toast bildirimi gösterecektir.
Örnek
_sorry() {
...
showToastSorry(
description: "Your account has been suspended"
);
}
isLoading
isLoading metodu, durumun yüklenip yüklenmediğini kontrol eder.
Örnek
class _HomePageState extends NyState<HomePage> {
@override
Widget build(BuildContext context) {
if (isLoading()) {
return AppLoader();
}
return Scaffold(
body: Text("The page loaded", style: TextStyle(
color: colors().primaryContent
)
)
);
}
afterLoad
afterLoad metodu, durum 'yüklemeyi' bitirene kadar bir yükleyici görüntülemek için kullanılabilir.
Ayrıca loadingKey parametresini kullanarak diğer yükleme anahtarlarını kontrol edebilirsiniz: afterLoad(child: () {}, loadingKey: 'home_data').
Örnek
class _HomePageState extends NyState<HomePage> {
@override
get init => () {
awaitData(perform: () async {
await sleep(4);
print('4 seconds after...');
});
};
@override
Widget build(BuildContext context) {
return Scaffold(
body: afterLoad(child: () {
return Text("Loaded");
})
);
}
afterNotLocked
afterNotLocked metodu, durumun kilitli olup olmadığını kontrol eder.
Durum kilitliyse [loading] widget'ını görüntüler.
Örnek
class _HomePageState extends NyState<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: afterNotLocked('login', child: () {
return MaterialButton(
onPressed: () {
login();
},
child: Text("Login"),
);
}),
)
);
}
login() async {
await lockRelease('login', perform: () async {
await sleep(4);
print('4 seconds after...');
});
}
}
afterNotNull
Bir değişken ayarlanana kadar bir yükleme widget'ı göstermek için afterNotNull kullanabilirsiniz.
Bir Future çağrısı kullanarak bir veritabanından kullanıcı hesabı almanız gerektiğini hayal edin; bu 1-2 saniye sürebilir, verilere sahip olana kadar bu değer üzerinde afterNotNull kullanabilirsiniz.
Örnek
class _HomePageState extends NyState<HomePage> {
User? _user;
@override
get init => () async {
_user = await api<ApiService>((request) => request.fetchUser()); // example
setState(() {});
};
@override
Widget build(BuildContext context) {
return Scaffold(
body: afterNotNull(_user, child: () {
return Text(_user!.firstName);
})
);
}
setLoading
setLoading kullanarak 'yükleniyor' durumuna geçebilirsiniz.
İlk parametre yüklenip yüklenmediği için bir bool kabul eder, sonraki parametre yükleme durumu için bir ad belirlemenize olanak tanır, örneğin setLoading(true, name: 'refreshing_content');.
Örnek
class _HomePageState extends NyState<HomePage> {
@override
get init => () async {
setLoading(true, name: 'refreshing_content');
await sleep(4);
setLoading(false, name: 'refreshing_content');
};
@override
Widget build(BuildContext context) {
if (isLoading(name: 'refreshing_content')) {
return AppLoader();
}
return Scaffold(
body: Text("The page loaded")
);
}