🎉 Nylo v7 jest tutaj! Zobacz co nowego →

Flutter
Micro-framework
Dla nowoczesnych aplikacji

Solidna podstawa do tworzenia aplikacji Flutter. Routing, zarządzanie stanem, sieć i więcej — wszystko w jednym eleganckim pakiecie.

Rozpocznij
Odkrywaj
Metro CLI

Twórz wszystko z poziomu terminala

Metro to narzędzie CLI Nylo, które pomaga tworzyć szkielety stron, modeli, kontrolerów, widgetów i więcej za pomocą jednego polecenia.

Dowiedz się więcej o Metro
metro make:page HomePage
# Creates a new page called HomePage

metro make:api_service User
# Creates a new API Service called UserApiService

metro make:model User
# Creates a new model called User

metro make:stateful_widget FavouriteWidget
# Creates a new stateful widget called FavouriteWidget
class ApiService extends NyApiService {
  @override
  String get baseUrl => "https://api.example.com/v1";

  Future<List<Post>> posts() async {
    return await network(
      request: (request) => request.get("/posts"),
    );
  }
}

// Usage in your page
final posts = await api<ApiService>((request) => request.posts());
Sieć

Bezproblemowa integracja z API

Pisz czyste, łatwe w utrzymaniu serwisy API z automatycznym parsowaniem JSON, obsługą błędów i interceptorami zapytań.

Dowiedz się więcej o sieci
Odkrywaj

Potężne narzędzia do tworzenia

Wszystko, czego potrzebujesz do zbudowania kolejnej aplikacji Flutter

routes/router.dart
appRouter() => nyRoutes((router) {
    router.add(HomePage.path).initialRoute();

    router.add(DiscoverPage.path);

    router.add(LoginPage.path, 
        transitionType: TransitionType.bottomToTop());

    router.add(ProfilePage.path,
        routeGuard: [
            AuthGuard()
        ]
    );
});

Twórz złożone trasy, interfejsy i strony UI dla swojej aplikacji Flutter.

Dowiedz się więcej
Krok 1

Uwierzytelnij użytkownika

String userToken = "eyJhbG123...";

await Auth.authenticate(data: {"token": userToken});
Krok 2

Teraz, gdy użytkownik otworzy aplikację, będzie uwierzytelniony.

final userData = Auth.data();
// {"token": "eyJhbG123..."}

bool isAuthenticated = await Auth.isAuthenticated();
// true
Krok 3

Jeśli ustawiłeś authenticatedRoute w swoim routerze, ta strona zostanie wyświetlona, gdy użytkownik ponownie otworzy aplikację.

routes/router.dart
appRouter() => nyRoutes((router) {
    ...
    router.add(LandingPage.path).initialRoute();

    router.add(DashboardPage.path).authenticatedRoute();
    // overrides the initial route when a user is authenticated

Wyloguj użytkownika

await Auth.logout();

Uwierzytelniaj użytkowników w swojej aplikacji Flutter.

Dowiedz się więcej
Krok 1

Utwórz formularz

terminal
metro make:form RegisterForm
Krok 2

Zmodyfikuj formularz

app/forms/register_form.dart
class RegisterForm extends NyFormWidget {

    RegisterForm({super.key, super.submitButton, super.onSubmit, super.onFailure});

    // Add your fields here
    @override
    fields() => [
        Field.capitalizeWords("name",
            label: "Name",
            validator: FormValidator.notEmpty(),
        ),
        Field.email("email_address",
            label: "Email",
            validator: FormValidator.email()
        ),
        Field.password("password",
            label: "Password",
            validator: FormValidator.password(),
        ),
    ];

    static NyFormActions get actions => const NyFormActions("RegisterForm");
}
Krok 3

Użyj formularza w widgecie

register_page.dart
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: RegisterForm(
      submitButton: Button.primary(text: "Submit"),
      onSubmit: (data) {
        printInfo(data);
      },
    ),
  );
}

Zarządzaj, waliduj i wysyłaj dane w jednym miejscu dzięki formularzom Nylo.

Dowiedz się więcej
Krok 1

Utwórz widget z zarządzaniem stanem

terminal
metro make:stateful_widget CartIcon
resources/cart_icon_widget.dart
class _CartIconState extends NyState<CartIcon> {
  ...

  @override
  Map<String, Function> get stateActions => {
    "clear_cart": () {
      _items = 0;
    },
    ...
  };

  @override
  Widget view(BuildContext context) {
    return Container(child: Text("Items in cart: ${_items}"));
  }
}
Krok 2

Use CartIcon.action("clear_cart")

another widget
Button.primary(text: "Add to cart",
    onPressed: () {
      CartIcon.action("clear_cart");
    }
)

Zaawansowane zarządzanie stanem widgetów w Twojej aplikacji Flutter.

Dowiedz się więcej
Krok 1

Utwórz zdarzenie

terminal
metro make:event Logout
app/events/logout_event.dart
class LogoutEvent implements NyEvent {
    @override
    final listeners = {
        DefaultListener: DefaultListener(),
    };
}

class DefaultListener extends NyListener {
    @override
    handle(dynamic event) async {

        // logout user
        await Auth.logout();

        // redirect to home page
        routeTo(HomePage.path,
            navigationType: NavigationType.pushAndForgetAll
        );
    }
}
Krok 2

Wyślij zdarzenie

MaterialButton(child: Text("Logout"),
    onPressed: () {
        event<LogoutEvent>();
    },
)

Wysyłaj zdarzenia i nasłuchuj ich w swojej aplikacji.

Dowiedz się więcej

Zaplanuj jednorazowe uruchomienie zadania

Nylo.scheduleOnce("onboarding_info", () {
    print("Perform code here to run once");
});

Zaplanuj jednorazowe uruchomienie zadania po określonej dacie

Nylo.scheduleOnceAfterDate("app_review_rating", () {
    print("Perform code to run once after DateTime(2025, 04, 10)");
}, date: DateTime(2025, 04, 10));

Zaplanuj codzienne uruchomienie zadania

Nylo.scheduleOnceDaily("free_daily_coins", () {
    print("Perform code to run once daily");
});

Planuj jednorazowe lub codzienne uruchomienie zadań w swojej aplikacji Flutter.

Dowiedz się więcej
Krok 1

Utwórz serwis API

terminal
metro make:api_service User
app/networking/user_api_service.dart
class UserApiService extends NyApiService {
    @override
    String get baseUrl => getEnv("API_BASE_URL");

    Future<User?> fetchUser(int id) async {
        return await get<User>(
            "/users/$id",
            queryParameters: {"include": "profile"},
        );
    }

    Future<User?> createUser(Map<String, dynamic> data) async {
        return await post<User>("/users", data: data);
    }
}
Krok 2

Wywołaj API ze swojej strony

User? user = await api<UserApiService>(
    (request) => request.fetchUser(1),
);

Eleganckie serwisy API z automatycznym parsowaniem JSON, buforowaniem i interceptorami.

Dowiedz się więcej
Krok 1

Bezpiecznie zapisuj dane

saving_data.dart
// Save values to secure storage
await NyStorage.save("coins", 100);
await NyStorage.save("username", "Anthony");
await NyStorage.save("isPremium", true);

// Save with TTL (auto-expires)
await NyStorage.save("session", "abc123",
    expiry: Duration(hours: 1),
);
Krok 2

Odczytuj z rzutowaniem typów

// Automatic type casting
String? username = await NyStorage.read("username");
int? coins = await NyStorage.read<int>("coins");
bool? isPremium = await NyStorage.read<bool>("isPremium");

// Delete a value
await NyStorage.delete("coins");

Bezpieczne lokalne przechowywanie danych z rzutowaniem typów, wygasaniem TTL i kolekcjami.

Dowiedz się więcej
Krok 1

Dodaj pliki językowe

lang/en.json
{
    "welcome": "Welcome",
    "greeting": "Hello {{name}}",
    "navigation": {
        "home": "Home",
        "profile": "Profile"
    }
}
Krok 2

Tłumacz tekst w swoich widgetach

// Simple translation
Text("welcome".tr())  // "Welcome"

// With arguments
Text("greeting".tr(arguments: {"name": "Anthony"}))
// "Hello Anthony"

// Nested keys
Text("navigation.home".tr())  // "Home"

Obsługa wielu języków za pomocą plików JSON, argumentów i RTL.

Dowiedz się więcej
Krok 1

Utwórz centrum nawigacji

terminal
metro make:navigation_hub base
resources/pages/base_navigation_hub.dart
class _BaseNavigationHubState extends NavigationHub<BaseNavigationHub> {

    NavigationHubLayout? layout = NavigationHubLayout.bottomNav();

    @override
    bool get maintainState => true;

    _BaseNavigationHubState() : super(() async {
        return {
            0: NavigationTab(
                title: "Home",
                page: HomeTab(),
                icon: Icon(Icons.home),
            ),
            1: NavigationTab(
                title: "Settings",
                page: SettingsTab(),
                icon: Icon(Icons.settings),
            ),
        };
    });
}
Krok 2

Łatwo zmieniaj układy

// Bottom navigation
NavigationHubLayout.bottomNav()

// Top navigation
NavigationHubLayout.topNav()

// Journey / wizard flow
NavigationHubLayout.journey()

Twórz dolną nawigację, górną nawigację lub przepływy z zachowaniem stanu.

Dowiedz się więcej

Uwielbiane przez społeczność

Co deweloperzy mówią o Nylo Website

Dołącz do dyskusji

I'm new to Dart and new to your framework (which I love)

Peter Senior Director of Heroku Global

I wanted to thank you guys for the great job you are doing.

@youssefKadaouiAbbassi

Just to say that I am in love with @nylo_dev's website!! Definitely gonna explore it!

@esfoliante_txt

Really love the concept of this framework

@Chrisvidal

Nylo is the best framework for flutter, which makes developing easy

@higakijin

This is incredible. Very well done!

FireflyDaniel

Very nice Framework! Thank you so much!

@ChaoChao2509

I just discovered this framework and I'm very impressed. Thank you

@lepresk

Great work on Nylo

@dylandamsma

This is by far the best framework out there. Amazing quality and features. Thanks so much.

@2kulfi

It's interesting and very amazing. It makes the work more easier and less time consuming. Great work. Thank you

darkreader01

Salut. Je viens juste de découvrir votre outils et je le trouve vraiment super. Une belle découverte pour moi 👌🤌

ojean-01