Skip to main content

another_flutter_devtool 0.5.2 copy "another_flutter_devtool: ^0.5.2" to clipboard
another_flutter_devtool: ^0.5.2 copied to clipboard

An in-app devtool for Flutter: a draggable launcher opens a panel with app info, a network inspector, data usage and route navigation tools.

example/lib/main.dart

import 'package:another_flutter_devtool/another_flutter_devtool.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'my_custom_tool.dart';

// Navigation key (works with all routers)
final navigatorKey = GlobalKey<NavigatorState>();

void main() {
  // For tracking startup time.
  AnotherFlutterDevtool.markStartup();
  // Your custom tools.
  // Could be in a separate file.
  DevtoolTools.registerAll([const MyCustomTool(), const MyCustomTool2()]);

  runApp(
    AnotherFlutterDevtool(
      config: DevtoolConfig(
        // Can be kDebugMode or your own condition.
        enabled: kDebugMode,
        sections: [
          GeneralSection(
            // This configuration is required to navigate to a route.
            configuration: ConfigurationTool(onNavigate: (route) => navigatorKey.currentState?.pushNamed(route)),
          ),
          const NetworkSection(),
          playgroundSection,
        ],
      ),
      child: const ExampleApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Devtool Example',
      navigatorKey: navigatorKey,
      theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo)),
      home: const CounterPage(),
      routes: {
        '/example': (_) => const PlaceholderPage(title: '/example'),
        '/test': (_) => const PlaceholderPage(title: '/test'),
      },
    );
  }
}

class PlaceholderPage extends StatelessWidget {
  const PlaceholderPage({super.key, required this.title});

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: Center(child: Text('You navigated to $title')),
    );
  }
}

class CounterPage extends StatefulWidget {
  const CounterPage({super.key});

  @override
  State<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  int _count = 0;
  String _lastResult = '';

  Future<void> _fetchWithHttp() =>
      _run(() async => (await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'))).statusCode);

  Future<void> _fetchWithDio() =>
      _run(() async => (await Dio().get<String>('https://httpbin.org/bytes/20480')).statusCode ?? 0);

  Future<void> _postJson() => _run(
    () async => (await http.post(
      Uri.parse('https://jsonplaceholder.typicode.com/posts?source=devtool'),
      headers: {'Content-Type': 'application/json', 'Authorization': 'Bearer example-token'},
      body: '{"title": "Hello", "body": "From the devtool example", "userId": 1}',
    )).statusCode,
  );

  Future<void> _fetchStatus(int status) =>
      _run(() async => (await http.get(Uri.parse('https://httpbin.org/status/$status'))).statusCode);

  Future<void> _fetchUnreachable() =>
      _run(() async => (await http.get(Uri.parse('https://unreachable.invalid/ping'))).statusCode);

  Future<void> _run(Future<int> Function() request) async {
    try {
      final status = await request();
      if (mounted) setState(() => _lastResult = 'Status $status');
    } catch (error) {
      if (mounted) setState(() => _lastResult = 'Failed: $error');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Devtool Example')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text('Drag the code icon around, tap it to open the devtool.'),
            const SizedBox(height: 16),
            Text('Count: $_count', key: const Key('counter_text'), style: Theme.of(context).textTheme.headlineMedium),
            const SizedBox(height: 24),
            Wrap(
              spacing: 12,
              runSpacing: 8,
              alignment: WrapAlignment.center,
              children: [
                OutlinedButton(onPressed: _fetchWithHttp, child: const Text('Fetch with http')),
                OutlinedButton(onPressed: _fetchWithDio, child: const Text('Fetch with Dio')),
                OutlinedButton(onPressed: _postJson, child: const Text('POST JSON')),
                OutlinedButton(onPressed: () => _fetchStatus(404), child: const Text('404')),
                OutlinedButton(onPressed: () => _fetchStatus(500), child: const Text('500')),
                OutlinedButton(onPressed: _fetchUnreachable, child: const Text('Unreachable host')),
              ],
            ),
            const SizedBox(height: 8),
            Text(_lastResult),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        key: const Key('increment_button'),
        onPressed: () => setState(() => _count++),
        child: const Icon(Icons.add),
      ),
    );
  }
}
5
likes
150
points
41
downloads

Documentation

API reference

Publisher

verified publisherbeka-jikia.com

Weekly Downloads

An in-app devtool for Flutter: a draggable launcher opens a panel with app info, a network inspector, data usage and route navigation tools.

Repository (GitHub)
View/report issues

Topics

#devtools #debugging #network #developer-tools #inspector

License

MIT (license)

Dependencies

device_info_plus, flutter, package_info_plus, share_plus, shared_preferences

More

Packages that depend on another_flutter_devtool