패키지, 저장소 및 앱 카테고리 검색

패키지 상세v1.1.3+1

fittor

반응형 UI 및 상태 관리를 위한 플러터 패키지입니다. 화면 크기와 방향에 맞춰 적응합니다.

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
94
좋아요
9
Pub 점수
160

패키지 설치

flutter pub add fittor

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Fittor는 반응형 사용자 인터페이스 및 상태 관리를 간소화하기 위해 설계된 Flutter 패키지입니다. 다양한 화면 크기와 방향에 자동으로 레이아웃을 적응시켜 장치 간 일관된 UI를 보장합니다. 내장된 반응형 유틸리티를 활용하여 반복 코드를 줄이고 다중 플랫폼 앱 개발을 간편하게 만듭니다. 복잡한 설정 없이 효율적이고 확장 가능한 솔루션을 원하는 개발자에게 이상적입니다. 이 패키지는 모바일, 웹, 데스크톱을 포함한 모든 주요 플랫폼을 지원하여 현대 앱 개발에 유연하게 대응할 수 있습니다.

사용 사례

  • 다중 장치 앱을 위한 반응형 레이아웃 구축
  • Flutter 프로젝트에서 상태 관리 간소화
  • 다양한 화면 크기에 맞는 적응형 UI 만들기
  • 일관된 디자인으로 크로스플랫폼 애플리케이션 개발하기
  • 방향에 따라 레이아웃 조정 자동화
  • 수동 미디어 쿼리 처리 감소

주요 기능

  • 화면 크기에 따른 자동 반응성
  • 내장된 상태 관리 유틸리티
  • 모든 플러터 플랫폼 지원
  • 방향 인식 레이아웃 적응
  • 최소한의 보일러플레이트 코드
  • pub add를 통한 간편한 통합

적합한 대상

  • 다중 플랫폼을 대상으로 하는 Flutter 개발자
  • 반응형 UI 디자인을 우선시하는 팀
  • 적은 설정으로 적응형 레이아웃을 사용하는 프로젝트
  • 경량 상태 관리가 필요한 개발자
  • 기기 간에 일관된 UX가 필요한 앱
  • 반응형 컴포넌트를 활용한 빠른 프로토타이핑

고려 사항

  • 새로운 반응형 패턴을 배워야 할 수 있습니다
  • 완전한 사용자 지정 솔루션에 비해 커스터마이제이션이 제한적
  • Flutter의 렌더링 파이프라인에 의존합니다
  • 매우 복잡한 상태 흐름에 적합하지 않음
  • 중간에서 대규모의 반응형 앱에 가장 적합
  • Flutter 위젯 트리에 대한 이해가 필요합니다

원본 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 개

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.