focus_widget 1.0.2+2 copy "focus_widget: ^1.0.2+2" to clipboard
focus_widget: ^1.0.2+2 copied to clipboard

outdated

When the FocusWidget has focus Trigger the PointerDown event outside the FocusWidget area Will make FocusWidget lose focus and trigger the FocusNode listener

Flutter Focus Widget #

一个可以让FocusNode失去焦点的Widget #

A focusable and blurable widget of based on the FocusNode. #

  • 新增的参数:

    • bool showFocusArea

      使用一个半透明的红色方框显示焦点区域,主要用于调试。

    • void Function(Widget widget, FocusNode focusNode) onLostFocus

      失去焦点后会调用这个function。

  • New Parameters:

    • bool showFocusArea

      Display a translucent red box to show the focus area, it's for debug.

    • void Function(Widget widget, FocusNode focusNode) onLostFocus

      When lost focus invoke this function.

  • 当FocusWidget获得焦点后

    在FocusWidget区域外点击

    会调用FocusNode.unfocus()并且触发FocusNode的listener

  • When the FocusWidget had focus

    Tap outside the FocusWidget area

    Will call the FocusNode's unfocus method and trigger the FocusNode's listener

Code #

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:focus_widget/focus_widget.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        Locale.fromSubtags(languageCode: 'zh'),
        Locale.fromSubtags(languageCode: 'en'),
      ],
      home: MyHomePage(title: 'Demo'),
    );
  }
}

class DemoLocalizations {
  DemoLocalizations(this.locale);

  final String locale;

  static DemoLocalizations of(BuildContext context) {
    return DemoLocalizations(Localizations.localeOf(context).languageCode);
  }

  static Map<String, Map<String, String>> _localizedValues = {
    'en': {
      'normal': 'Normal',
      'showFocusArea': 'showFocusArea',
      'onLostFocus': 'onLostFocus event',
      'isEmpty': 'This input can not be empty',
    },
    'zh': {
      'normal': '正常模式',
      'showFocusArea': '显示半透明红色的焦点区域',
      'onLostFocus': 'onLostFocus事件',
      'isEmpty': '这个输入框不能为空',
    },
  };

  String get normal => _localizedValues[locale]['normal'];

  String get showFocusArea => _localizedValues[locale]['showFocusArea'];

  String get onLostFocus => _localizedValues[locale]['onLostFocus'];

  String get isEmpty => _localizedValues[locale]['isEmpty'];
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final FocusNode _address = FocusNode(), _name = FocusNode();
  GlobalKey<ScaffoldState> _scaffold = GlobalKey();
  final TextEditingController _email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final language = DemoLocalizations.of(context);
    return Scaffold(
      key: _scaffold,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      drawer: Drawer(
        child: SafeArea(
          child: ListView(
            padding: EdgeInsets.only(left: 10, right: 10),
            children: ListTile.divideTiles(
                context: context,
                tiles: List.generate(20, (i) {
                  if (i != 5) {
                    return ListTile(title: Text(i.toString()));
                  }
                  return FocusWidget.builder(
                    context,
                    showFocusArea: true,
                    builder: (ctx, focusNode) => TextField(
                      focusNode: focusNode,
                      autofocus: true,
                      decoration: InputDecoration(
                        hintText: 'Input',
                        labelText: 'Input',
                      ),
                    ),
                  );
                })).toList(),
          ),
        ),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Padding(
            padding: EdgeInsets.only(left: 20, right: 20),
            child: Container(
              width: 100,
              child: FocusWidget(
                focusNode: _address,
                child: TextField(
                  focusNode: _address,
                  decoration: InputDecoration(
                      hintText: language.normal, labelText: language.normal),
                ),
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.only(left: 20, right: 20),
            child: FractionallySizedBox(
              widthFactor: 0.6,
              child: FocusWidget.builder(
                context,
                showFocusArea: true,
                builder: (_, FocusNode focusNode) => TextField(
                  focusNode: focusNode,
                  decoration: InputDecoration(
                      hintText: language.showFocusArea,
                      labelText: language.showFocusArea),
                ),
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.only(left: 20, right: 20),
            child: FocusWidget.builder(
              context,
              showFocusArea: true,
              onLostFocus: (_, focusNode) {
                print('input is empty: ${_email.text.isEmpty}');
                setState(() {});
              },
              builder: (context, FocusNode focusNode) {
                return TextField(
                  controller: _email,
                  focusNode: focusNode,
                  decoration: InputDecoration(
                    hintText: language.onLostFocus,
                    labelText: language.onLostFocus,
                    errorText: _email.text.isEmpty ? language.isEmpty : null,
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

录屏 / Screen Recording #

gif

20
likes
0
points
5
downloads

Publisher

unverified uploader

Weekly Downloads

When the FocusWidget has focus Trigger the PointerDown event outside the FocusWidget area Will make FocusWidget lose focus and trigger the FocusNode listener

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on focus_widget