搜尋套件、儲存庫與 APP 分類

套件詳情v1.1.3+1

fittor

一個用於響應式 UI 和狀態管理的 Flutter 套件。可適應螢幕尺寸和方向。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
94
喜歡數
9
Pub 分數
160

安裝套件

flutter pub add fittor

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

Fittor 是一個 Flutter 套件,旨在簡化響應式使用者介面與狀態管理。它能自動適應不同的螢幕尺寸與方向,確保跨裝置的一致性 UI。透過利用內建的響應式工具,Fittor 減少重複程式碼,並簡化多平台應用的開發流程。非常適合尋求高效、可擴展解決方案且無需複雜設定的開發者。此套件支援所有主要平台,包含行動裝置、Web 與桌面,讓其成為現代應用開發的多功能選擇。

適用情境

  • 為多設備應用建構響應式版面
  • 簡化 Flutter 專案中的狀態管理
  • 為不同螢幕尺寸建立適應性使用者介面
  • 使用一致的設計開發跨平台應用程式
  • 根據方向自動調整佈局
  • 減少手動媒體查詢處理

主要特色

  • 跨螢幕尺寸的自動響應性
  • 內建的狀態管理工具
  • 支援所有 Flutter 平台
  • 面向方向的佈局自適應
  • 最小化樣板程式碼
  • 透過 pub add 輕鬆整合

適合對象

  • 面向多平台的 Flutter 開發人員
  • 注重響應式UI設計的團隊
  • 需要最少設定即可實現自適應版面的專案
  • 尋求輕量級狀態管理的開發者
  • 需要在各類裝置上維持一致使用者體驗的應用
  • 使用響應式元件快速原型設計

使用建議

  • 可能需要學習新的響應式設計模式
  • 與完整的自定義解決方案相比,客製化功能有限
  • 依賴於 Flutter 的渲染管道
  • 不適合高度複雜的狀態流程
  • 最適合中到大型的響應式應用
  • 需要理解 Flutter 的 widget 樹

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

Fittor Logo

pub package pub points License: MIT GitHub issues GitHub stars

A comprehensive Flutter package for responsive UI design and network connectivity management. A lightweight, intuitive state management solution for Flutter applications.

Table of Contents

Features

  • 📱 Responsive UI: Easily create responsive layouts that adapt to different screen sizes and orientations
  • 📦 Custom Sized Box: Convenient extensions for creating SizedBox widgets
  • 🌐 Internet Connectivity: Built-in connectivity monitoring with customizable no-internet UI
  • 💱 Currency Converter: Live exchange rates and currency conversion utilities
  • 📦 Package Management: Manage dependencies with ease

Installation

dependencies:
  fittor: ^latest_version
flutter pub add fittor

Then run:

flutter pub get

Usage

Responsive

Fittor provides a responsive design system through mixins and extensions. Here's how to use it:

Basic Setup

Add the FittorAppMixin to your app:

class MyApp extends StatelessWidget with FittorAppMixin {
  const MyApp({super.key});

  @override
  Widget responsive(BuildContext context) {
    return MaterialApp(
      title: 'Responsive Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HomeScreen(),
    );
  }
}
Using in Widgets

Access responsive values through context extensions:

Container(
  width: context.wp(50),          // 50% of screen width
  height: context.hp(25),         // 25% of screen height
  padding: EdgeInsets.all(context.p16), // Adaptive padding
  child: Text(
    'Responsive Text',
    style: TextStyle(fontSize: context.fs18), // Adaptive font size
  ),
)
Responsive Mixins

Use the FittorMixin in your StatefulWidget:

class _MyWidgetState extends State<MyWidget> with FittorMixin {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: wp(50),    // 50% of screen width
      padding: EdgeInsets.all(p16), // Predefined padding
      child: Text(
        'Hello World',
        style: TextStyle(fontSize: fs(18)), // Responsive font size
      ),
    );
  }
}
Custom Sized Box

Create SizedBox widgets with simple extensions:

// Width SizedBox
20.w  // SizedBox with width 20

// Height SizedBox
16.h  // SizedBox with height 16

// Square SizedBox
24.s  // SizedBox with width and height both 24
Internet Connectivity

Fittor includes built-in internet connectivity monitoring without any external packages.

Using ConnectivityWrapper
class MyApp extends StatelessWidget with FittorAppMixin {
  const MyApp({super.key});
  @override
  Widget responsive(BuildContext context) {
    return MaterialApp(
      home: ConnectivityWrapper(
        ignoreOfflineState: true,
        onConnectivityChanged: (status) {
          debugPrint('Connectivity status: $status');
        },
        child: const HomeScreen(),
      ),
    );
  }
}

Wrap your widget with ConnectivityWrapper to automatically show a no-internet screen when connectivity is lost:

ConnectivityWrapper(
  child: YourWidget(),
  // Optional customizations:
  offlineWidget: YourCustomOfflineWidget(),
  onConnectivityChanged: (status) {
    print('Connectivity status: $status');
  },
)

The ignoreOfflineState parameter (default: false) controls whether the wrapper automatically shows the no-internet screen:

ConnectivityWrapper(
  ignoreOfflineState: true,  // Don't show no-internet screen automatically
  onConnectivityChanged: (status) {
    // Handle connectivity changes yourself
  },
  child: YourWidget(),
)

When ignoreOfflineState is set to true, the ConnectivityWrapper will not automatically show the no-internet screen when connectivity is lost. Instead, it will continue showing your child widget and notify you of connectivity changes through the onConnectivityChanged callback. This is useful when you want to handle connectivity UI yourself, such as showing snackbars or banners instead of full-screen notifications.

Using ConnectivityMixin

For more fine-grained control, use the ConnectivityMixin in your StatefulWidget:

class _MyScreenState extends State<MyScreen> with ConnectivityMixin {
  @override
  void onConnectivityChanged(ConnectivityStatus status) {
    if (status == ConnectivityStatus.online) {
      // Handle online state
    } else {
      // Handle offline state
    }
  }
  
  @override
  Widget build(BuildContext context) {
    // Access connectivity status with:
    if (isOnline) {
      return OnlineContent();
    } else {
      return OfflineContent();
    }
  }
}
Currency Converter

Fittor provides a currency converter utility with live exchange rates.

Basic Conversion
// Convert 100 INR to USD
double usdAmount = await context.convertCurrency(
  from: 'INR',
  to: 'USD',
  amount: 100.0,
);

print('100 INR = $usdAmount USD');
Convert and Format
// Convert and format with currency symbol
String formattedAmount = await context.convertAndFormat(
  from: 'INR',
  to: 'USD',
  amount: 100.0,
);

print('100 INR = $formattedAmount'); // Outputs: 100 INR = $1.17
Format with Custom Symbols
// Format a currency amount with proper symbol
String formatted = context.formatCurrency(1234.56, 'USD');
print(formatted); // Outputs: $1,234.56
Live Exchange Rates
// Get the current exchange rate between two currencies
double rate = await context.getExchangeRate('INR', 'USD');
print('1 INR = $rate USD'); 
Advanced Usage
Direct Access to CurrencyConverter
final converter = CurrencyConverter();

// Manually get latest rates for a base currency
Map<String, dynamic> rates = await converter.getLatestRates('EUR');

// Check cache status
Map<String, dynamic> cacheInfo = converter.getCacheInfo();
print('Last updated: ${cacheInfo['lastUpdated']}');
FittorCurrency Utilities
final currencyUtils = FittorCurrency();

// Create a currency text widget
Widget priceText = currencyUtils.currencyText(
  '\$1,234.56',
  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
);

State Management

Overview

Fittor is a pragmatic state management library designed to make Flutter development more efficient with minimal boilerplate. It offers a controller-based approach, more focused API.

Features
  • Controller-based state management: Create reactive UIs with minimal code
  • Dependency injection: Easily register and find controllers throughout your app
  • Reactive value wrappers: Optimized UI updates with fine-grained reactivity
  • Bindings system: Organize dependencies by route or feature
  • Extension methods: Access controllers directly from BuildContext
  • Auto-disposal: Controllers are automatically managed in the widget lifecycle
Getting Started
1. Initialize Fittor

Initialize Fittor at the root of your application:

void main() {
  runApp(
    FitInitializer(
      child: MyApp(),
      initialBindings: [AppBindings()],
    ),
  );
}
2. Create a Controller

Controllers manage your application state and business logic:

class CounterController extends FitController {
  int count = 0;
  
  void increment() {
    count++;
    fittor(); // Notify listeners to rebuild
  }
  
  @override
  void onDelete() {
    // Clean up resources when controller is removed
    super.onDelete();
  }
}
3. Using Reactive Values

For more granular updates, use the FitValue class:

class UserController extends FitController {
  final username = "".fit; // Creates a FitValue<String>
  final isLoggedIn = false.fit; // Creates a FitValue<bool>
  
  void login(String name) {
    username.val = name; // This will automatically update listeners
    isLoggedIn.val = true;
  }
}
4. Register Controllers with Bindings

Create a bindings class to organize your dependencies:

class AppBindings extends FitBindings {
  @override
  void dependencies() {
    lazyPut(() => CounterController());
    lazyPut(() => UserController());
  }
}
5. Using Controllers in Widgets

Access your controllers in the UI using FitBuilder:

FitBuilder<CounterController>(
  controller: Fit.find<CounterController>(),
  builder: (context, controller) {
    return Text('Count: ${controller.count}');
  },
)

For reactive values:

FitValueBuilder<String>(
  fitValue: userController.username,
  builder: (context, username) {
    return Text('Hello, $username');
  },
)
6. Access Controllers via BuildContext Extension
final controller = context.find<CounterController>();
controller.increment();
Core Concepts
Controllers

Controllers are the heart of your application logic. Extend FitController to create a controller:

class ThemeController extends FitController {
  bool isDarkMode = false;
  
  void toggleTheme() {
    isDarkMode = !isDarkMode;
    fittor(); // Notify all listeners (will rebuild UI)
  }
  
  // To update specific widgets only
  void updateSpecificWidgets() {
    fittor('theme-tag'); // Only rebuilds widgets with 'theme-tag'
  }
}
Dependency Injection

Fittor provides several methods to register and find controllers:

  • Fit.lazyPut<T>() : Registers a controller for lazy initialization
  • Fit.put<T>() : Registers an already initialized controller
  • Fit.find<T>() : Finds a registered controller
  • Fit.delete<T>() : Removes a controller and calls its onDelete method
Advanced Usage Controller
Tagging Controllers

Register multiple instances of the same controller type:

// Registration
Fit.put<ApiClient>(ProductApiClient(), tag: 'product');
Fit.put<ApiClient>(UserApiClient(), tag: 'user');

// Usage
final productApi = Fit.find<ApiClient>(tag: 'product');
final userApi = Fit.find<ApiClient>(tag: 'user');
Auto-registration with FitBuilder

Controllers can be automatically registered with FitBuilder:

FitBuilder<DashboardController>(
  controller: DashboardController(),
  autoRegister: true,
  builder: (context, controller) {
    return DashboardView(controller: controller);
  },
)
Initialization and Disposal

Controllers are automatically disposed when their widgets are removed from the tree. You can also manually dispose controllers:

FitBuilder<VideoController>(
  controller: Fit.find<VideoController>(),
  init: (controller) => controller.initialize(),
  dispose: (controller) => controller.cleanup(),
  builder: (context, controller) {
    return VideoPlayer(controller);
  },
)

Fittor Blur Ash

You can now use the FittorBlurAsh widget to add a blur effect to a widget.


// Usage

FittorBlurAsh FittorBlurAsh({
  Key? key,
  required String hash,
  double? width,
  double? height,
  BoxFit fit = BoxFit.cover,
  Color? color,
  Widget? child,
  Widget? loadingWidget,
  Widget? errorWidget,
  int resolution = 32,
})
Usage Example Using Cache Network Image

CachedNetworkImage(
  imageUrl: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb',
  placeholder: (context, url) {
    return  FittorBlurAsh(
      hash: 'UbCP*BWYWWof~qWraykC_3WYjZof?bflaxoL',
      width: 300,
      height: 200,
    );
  },
  errorWidget: (context, url, error) {
    return FittorBlurAsh(
      hash: 'UbCP*BWYWWof~qWraykC_3WYjZof?bflaxoL',
      width: 300,
      height: 200,
    );
  },
  width: 300,
  height: 200,
  fit: BoxFit.cover,
),

Read more

Features

  • ✅ Trim by length or lines: Choose between character count or line-based trimming
  • ✅ Rich text support: Use FitReadMore.rich() for complex text formatting
  • ✅ Text annotations: Support for URLs, hashtags, mentions, and custom patterns
  • ✅ Customizable styling: Full control over colors, fonts, and text styles
  • ✅ External control: Control expand/collapse state externally
  • ✅ Callbacks: Get notified when text is expanded or collapsed
  • ✅ Accessibility: Full support for text selection and screen readers
  • ✅ Pre/post text: Add content before and after the main text
FitReadMore(
  'Your very long text content goes here...',
  trimLength: 150,
  trimCollapsedText: 'Read more',
  trimExpandedText: 'Show less',
  colorClickableText: Colors.blue,
)
FitReadMore(
  'Check out https://example.com and follow @username #flutter',
  trimLength: 100,
  annotations: [
    // URL annotation
    FitAnnotation(
      regExp: RegExp(r'https?://[^\s]+'),
      spanBuilder: ({required text, required textStyle}) => TextSpan(
        text: text,
        style: textStyle.copyWith(
          color: Colors.blue,
          decoration: TextDecoration.underline,
        ),
      ),
    ),
    // Hashtag annotation
    FitAnnotation(
      regExp: RegExp(r'#\w+'),
      spanBuilder: ({required text, required textStyle}) => TextSpan(
        text: text,
        style: textStyle.copyWith(
          color: Colors.blue,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),
    // Mention annotation
    FitAnnotation(
      regExp: RegExp(r'@\w+'),
      spanBuilder: ({required text, required textStyle}) => TextSpan(
        text: text,
        style: textStyle.copyWith(
          color: Colors.purple,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),
  ],
)

Extension

Responsive Features
Extension Description Example
num.w Creates SizedBox with width 20.w creates SizedBox(width: 20)
num.h Creates SizedBox with height 16.h creates SizedBox(height: 16)
num.s Creates square SizedBox 24.s creates SizedBox.square(dimension: 24)
context.wp(%) Percentage of screen width context.wp(80) gives 80% of screen width
context.hp(%) Percentage of screen height context.hp(50) gives 50% of screen height
context.p* Adaptive padding context.p16 gives adaptive 16 padding
context.fs* Adaptive font size context.fs16 returns responsive font size 16
Connectivity Features
Feature Description Example
ConnectivityWrapper Wraps UI with connectivity monitoring ConnectivityWrapper(child: MyApp())
ConnectivityMixin Mixin for StatefulWidgets class _MyState extends State<MyWidget> with ConnectivityMixin
isOnline property Check online status with mixin if (isOnline) { /* do network request */ }
checkConnectivity() Manual connectivity check await checkConnectivity()
onConnectivityChanged Handle status changes onConnectivityChanged(status) { /* handle change */ }
Currency Features
Feature Description Example
convertCurrency() Convert currency double usdAmount = await context.convertCurrency(from: 'INR', to: 'USD', amount: 100.0);
convertAndFormat() Convert and format String formatted = await context.convertAndFormat(from: 'INR', to: 'USD', amount: 100.0);
formatCurrency() Format currency String formatted = context.formatCurrency(1234.56, 'USD');
getExchange Rate() Get exchange rate double rate = await context.getExchangeRate('INR', 'USD');

🐞 Troubleshooting

  • Ensure the package is correctly imported
  • Check that you're using the latest version
  • Verify flutter and dart SDK compatibility
  • Check for any conflicts with other packages

📞 Contact & Support

Author: Mushthak VP

🌐 Connect With Me
💡 Collaboration

Have a project or need custom Flutter development? Feel free to reach out! I'm always open to interesting projects, collaborations, and opportunities.

🤝 Contributing

Contributions are welcome! Whether you're reporting bugs, suggesting improvements, or want to collaborate, don't hesitate to connect.

License

MIT - Copyright © 2025 Mushthak VP

🆘 Support

For any questions, issues, or custom development needs, please contact me directly via email or social media channels.

所屬分類

依賴

依賴清單 1 項

原始碼儲存庫

使用此套件的專案

暫無相關資料。