turnable_page 1.0.1 copy "turnable_page: ^1.0.1" to clipboard
turnable_page: ^1.0.1 copied to clipboard

Realistic page-flipping widget for Flutter with smooth animations, interactive content, and smart gesture detection.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:turnable_page/turnable_page.dart';

void main() {
  runApp(MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'كتاب ذكي - تطبيق تقليب الصفحات',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: _AnimationTestPage(),
    );
  }
}

class _AnimationTestPage extends StatefulWidget {
  const _AnimationTestPage();

  @override
  _AnimationTestPageState createState() => _AnimationTestPageState();
}

class _AnimationTestPageState extends State<_AnimationTestPage> {
  late PageFlipController _controller;
  final List<String> _displayItemsFromMockApi = [];

  final ValueNotifier<int> _currentPageNotifier = ValueNotifier<int>(0);
  final ValueNotifier<int> _flipCountNotifier = ValueNotifier<int>(0);

  @override
  void initState() {
    super.initState();
    _controller = PageFlipController();
    _displayItemsFromMockApi.addAll([
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
    ]);

  }

  @override
  void dispose() {
    _currentPageNotifier.dispose();
    _flipCountNotifier.dispose();
    super.dispose();
  }

  Widget _buildLoadingPage() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          CircularProgressIndicator(color: Colors.pinkAccent),
          SizedBox(height: 20),
          Text(
            "تحميل بيانات واجهة برمجة التطبيقات الوهمية",
            style: TextStyle(color: Colors.pinkAccent),
          ),
        ],
      ),
    );
  }

  Widget _buildTestPage(int index, BoxConstraints constraints) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          colors: [
            Colors.primaries[index % Colors.primaries.length].shade300,
            Colors.primaries[index % Colors.primaries.length].shade600,
          ],
        ),
      ),
      child: Stack(
        children: [
          // Test content
          Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Icon(Icons.auto_stories, size: 80, color: Colors.white),
                SizedBox(height: 20),
                Text(
                  'صفحة ${_displayItemsFromMockApi[index]}',
                  style: TextStyle(
                    fontSize: 32,
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                  ),
                ),
                SizedBox(height: 20),
                Text(
                  'اسحب لتقليب الصفحة',
                  style: TextStyle(fontSize: 18, color: Colors.white70),
                ),
                SizedBox(height: 40),
                // Interactive button for testing
                ElevatedButton.icon(
                  onPressed: () {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(
                        content: Text(
                          'تم النقر على زر الصفحة ${_displayItemsFromMockApi[index]}',
                        ),
                        duration: Duration(seconds: 1),
                      ),
                    );
                  },
                  icon: Icon(Icons.touch_app),
                  label: Text('اختبار النقر'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.white,
                    foregroundColor:
                        Colors.primaries[index % Colors.primaries.length],
                    padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
                  ),
                ),
              ],
            ),
          ),
          // Page info overlay
          Positioned(
            top: 20,
            left: 20,
            child: ValueListenableBuilder<int>(
              valueListenable: _flipCountNotifier,
              builder: (context, flipCount, child) {
                return ValueListenableBuilder<int>(
                  valueListenable: _currentPageNotifier,
                  builder: (context, currentPage, child) {
                    return Container(
                      padding: EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: Colors.black.withValues(alpha: 0.7),
                        borderRadius: BorderRadius.circular(8),
                      ),
                      child: Text(
                        'اختبار الأنيميشن\nالصفحة الحالية: ${currentPage + 1}\nعدد التقليبات: $flipCount',
                        style: TextStyle(color: Colors.white, fontSize: 14),
                      ),
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: _displayItemsFromMockApi.isEmpty
          ? null
          : Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                FloatingActionButton(
                  onPressed: () {
                    _controller.previousPage();
                  },
                  child: Icon(Icons.arrow_back_ios_new_rounded),
                ),
                FloatingActionButton(
                  onPressed: () {
                    _controller.nextPage();
                  },
                  child: Icon(Icons.arrow_forward_ios_rounded),
                ),
              ],
            ),
      body: Center(
        child: TurnablePage(
          key: UniqueKey(),
          controller: _controller,
          pageCount: _displayItemsFromMockApi.isEmpty
              ? 1
              : _displayItemsFromMockApi.length,
          pageViewMode: PageViewMode.single,
          paperBoundaryDecoration: PaperBoundaryDecoration.modern,
          settings: FlipSettings(
            hideLeftShadow: true,
            onlyVerticalPageFlip: true,
            drawShadow: true,
            flippingTime: 800,
            swipeDistance: 60.0,
            cornerTriggerAreaSize: 0.15,
            usePortrait: false,
          ),
          onPageChanged: (leftPageIndex, rightPageIndex) {
            // log('Page: $leftPageIndex, $rightPageIndex');
            _currentPageNotifier.value = rightPageIndex;
            _flipCountNotifier.value = _flipCountNotifier.value + 1;
          },
          builder: (context, pageIndex, constraints) {
            if (_displayItemsFromMockApi.isEmpty) {
              return _buildLoadingPage();
            }
            return _buildTestPage(pageIndex, constraints);
          },
        ),
      ),
    );
  }
}
27
likes
140
points
186
downloads

Publisher

unverified uploader

Weekly Downloads

Realistic page-flipping widget for Flutter with smooth animations, interactive content, and smart gesture detection.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

unknown (license)

Dependencies

flutter, pdfrx

More

Packages that depend on turnable_page