Flutter键盘检测插件keyboard_detection的使用
Flutter键盘检测插件keyboard_detection的使用
Keyboard Detection
此插件为您提供了一种简单的方法来检测键盘是否可见。它通过底部视图内边距(inset)的调整来检查键盘的可见性,因此它是Flutter原生支持的功能。
简单用法
您只需像下面这样将Scaffold
包裹在KeyboardDetection
中,并监听onChanged
值。
@override
Widget build(BuildContext context) {
return MaterialApp(
home: KeyboardDetection(
controller: KeyboardDetectionController(
onChanged: (value) {
print('Keyboard visibility onChanged: $value');
setState(() {
keyboardState = value;
stateAsBool = keyboardDetectionController.stateAsBool();
stateAsBoolWithParamTrue =
keyboardDetectionController.stateAsBool(true);
});
},
),
child: Scaffold(
appBar: AppBar(
title: const Text('Keyboard Detection'),
),
body: Center(
child: Column(
children: [
Text('State: $keyboardState'),
Text(
'State as bool (includeTransitionalState = false): $stateAsBool'),
Text(
'State as bool (includeTransitionalState = true): $stateAsBoolWithParamTrue'),
const TextField(),
],
),
),
),
),
);
}
onChanged
将以枚举KeyboardState
的形式返回(unknown
:未知, visibling
:显示中, visible
:已显示, hiding
:隐藏中, hidden
:已隐藏)。
使用控制器
您可以像下面这样在build
方法外部声明controller
:
late KeyboardDetectionController keyboardDetectionController;
@override
void initState() {
keyboardDetectionController = KeyboardDetectionController(
onChanged: (value) {
print('Keyboard visibility onChanged: $value');
setState(() {
keyboardState = value;
stateAsBool = keyboardDetectionController.stateAsBool();
stateAsBoolWithParamTrue =
keyboardDetectionController.stateAsBool(true);
});
},
);
// Listen to the stream
_sub = keyboardDetectionController.stream.listen((state) {
print('Listen to onChanged with Stream: $state');
});
// One time callback
keyboardDetectionController.addCallback((state) {
print('Listen to onChanged with one time Callback: $state');
// End this callback by returning false
return false;
});
// Looped callback
keyboardDetectionController.addCallback((state) {
print('Listen to onChanged with looped Callback: $state');
// This callback will be looped
return true;
});
// Looped with future callback
keyboardDetectionController.addCallback((state) async {
await Future.delayed(const Duration(milliseconds: 100));
print('Listen to onChanged with looped future Callback: $state');
// This callback will be looped
return true;
});
super.initState();
}
并在build
方法内部添加到controller
:
@Override
Widget build(BuildContext context) {
return KeyboardDetection(
controller: keyboardDetectionController,
child: Scaffold(
appBar: AppBar(
title: const Text('Keyboard Detection'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('State: $keyboardState'),
Text('State as bool (includeTransitionalState = false): $stateAsBool'),
Text('State as bool (includeTransitionalState = true): $stateAsBoolWithParamTrue'),
FutureBuilder(
future: keyboardDetectionController.ensureSizeLoaded,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
'Keyboard size is loaded with size: ${keyboardDetectionController.size}');
}
return const Text('Keyboard size is still loading');
},
),
const TextField(),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const MyApp(),
),
);
},
child: const Text('Navigate to another page'),
),
ElevatedButton(
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (_) => const MyApp(),
),
(_) => false);
},
child: const Text('Move to another page'),
)
],
),
),
),
),
);
}
您可以使用以下方式获取当前键盘可见性的状态:
keyboardDetectionController.state
: 返回当前键盘可见性的状态,以枚举KeyboardState
的形式(unknown
:未知,visibling
:显示中,visible
:已显示,hiding
:隐藏中,hidden
:已隐藏)。keyboardDetectionController.stateAsBool([bool includeTransitionalState = false])
: 返回当前键盘可见性的状态,以bool?
的形式(null
:未知,true
:可见,false
:隐藏)。如果includeTransitionalState
为true
,那么即使状态是visibling
时也会返回true
,当状态是hiding
时会返回false
。keyboardDetectionController.addCallback(callback)
:添加一个回调,在键盘状态改变时调用。如果回调返回true
,则每次键盘改变时都会调用;如果返回false
,则会被忽略。这个callback
也支持Future
方法。keyboardDetectionController.stream
:监听键盘可见性变化事件,以KeyboardState
的形式。keyboardDetectionController.size
:获取键盘大小。请注意,这个值可能在键盘状态为可见时仍返回0,因为键盘需要时间完全显示。因此,您应该调用keyboardDetectionController.isSizeLoaded
来检查键盘大小是否已经加载。从版本0.5.0
开始,您可以通过await keyboardDetectionController.ensureSizeLoaded
等待这个值。
局限性
- 此包使用底部内边距来检测键盘可见性,因此不适用于浮动键盘(Issue #1)
完整示例代码
// ignore_for_file: avoid_print
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:keyboard_detection/keyboard_detection.dart';
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
KeyboardState keyboardState = KeyboardState.unknown;
bool? stateAsBool;
bool? stateAsBoolWithParamTrue;
StreamSubscription<KeyboardState>? _sub;
late KeyboardDetectionController keyboardDetectionController;
@override
void initState() {
keyboardDetectionController = KeyboardDetectionController(
onChanged: (value) {
print('Keyboard visibility onChanged: $value');
setState(() {
keyboardState = value;
stateAsBool = keyboardDetectionController.stateAsBool();
stateAsBoolWithParamTrue =
keyboardDetectionController.stateAsBool(true);
});
},
);
_sub = keyboardDetectionController.stream.listen((state) {
print('Listen to onChanged with Stream: $state');
});
// One time callback
keyboardDetectionController.addCallback((state) {
print('Listen to onChanged with one time Callback: $state');
// End this callback by returning false
return false;
});
// Looped callback
keyboardDetectionController.addCallback((state) {
print('Listen to onChanged with looped Callback: $state');
// This callback will be looped
return true;
});
// Looped with future callback
keyboardDetectionController.addCallback((state) async {
await Future.delayed(const Duration(milliseconds: 100));
print('Listen to onChanged with looped future Callback: $state');
// This callback will be looped
return true;
});
super.initState();
}
@override
void dispose() {
_sub?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return KeyboardDetection(
controller: keyboardDetectionController,
child: Scaffold(
appBar: AppBar(
title: const Text('Keyboard Detection'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('State: $keyboardState'),
Text(
'State as bool (includeTransitionalState = false): $stateAsBool'),
Text(
'State as bool (includeTransitionalState = true): $stateAsBoolWithParamTrue'),
FutureBuilder(
future: keyboardDetectionController.ensureSizeLoaded,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
'Keyboard size is loaded with size: ${keyboardDetectionController.size}');
}
return const Text('Keyboard size is still loading');
},
),
const TextField(),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const MyApp(),
),
);
},
child: const Text('Navigate to another page'),
),
ElevatedButton(
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (_) => const MyApp(),
),
(_) => false);
},
child: const Text('Move to another page'),
)
],
),
),
),
),
);
}
}
更多关于Flutter键盘检测插件keyboard_detection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter键盘检测插件keyboard_detection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用keyboard_detection
插件的代码示例。这个插件可以帮助你检测键盘的显示和隐藏状态,以便你可以根据这些状态调整你的UI布局。
步骤 1: 添加依赖
首先,你需要在你的pubspec.yaml
文件中添加keyboard_detection
插件的依赖。
dependencies:
flutter:
sdk: flutter
keyboard_detection: ^0.5.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
步骤 2: 导入插件
在你的Dart文件中(通常是main.dart
或者一个特定的页面文件),导入keyboard_detection
插件。
import 'package:keyboard_detection/keyboard_detection.dart';
步骤 3: 使用插件
你可以使用KeyboardVisibilityBuilder
小部件来检测键盘的显示和隐藏状态,并根据这些状态执行不同的操作。下面是一个简单的示例,展示如何根据键盘的显示状态来调整底部内边距。
import 'package:flutter/material.dart';
import 'package:keyboard_detection/keyboard_detection.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Keyboard Detection Example'),
),
body: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: KeyboardVisibilityBuilder(
builder: (context, isVisible) {
return Column(
children: [
TextField(
decoration: InputDecoration(
hintText: 'Type something...',
),
),
SizedBox(height: 20),
Text(
'Keyboard is ${isVisible ? 'visible' : 'not visible'}',
style: TextStyle(fontSize: 20),
),
],
);
},
),
),
),
);
}
}
解释
-
KeyboardVisibilityBuilder
:这是一个小部件,它接受一个builder
函数,该函数返回一个小部件,并传递一个布尔值isVisible
,指示键盘是否可见。 -
MediaQuery.of(context).viewInsets.bottom
:这是Flutter提供的一个方法,用于获取屏幕底部被键盘遮挡的部分的尺寸。通过将其设置为底部内边距,你可以确保你的内容不会被键盘遮挡。 -
TextField
:一个简单的输入框,用于触发键盘的显示。 -
Text
:显示键盘的可见性状态。
这个示例展示了如何使用keyboard_detection
插件来检测键盘的显示状态,并根据这个状态调整UI布局。你可以根据需要进一步自定义和扩展这个示例。