You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Flutter Linux应用TextField闲置失焦问题解决咨询

解决方案:强制Flutter应用保持焦点并常驻前台

一、Flutter代码层面优化

1. 监听TextField焦点,自动重新获取

通过FocusNode监听焦点状态,一旦检测到焦点丢失,立即重新请求焦点:

import 'package:flutter/material.dart';

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

  @override
  State<ScanScreen> createState() => _ScanScreenState();
}

class _ScanScreenState extends State<ScanScreen> with WidgetsBindingObserver {
  final FocusNode _scanFocusNode = FocusNode();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // 初始加载后自动获取焦点
    WidgetsBinding.instance.addPostFrameCallback((_) {
      FocusScope.of(context).requestFocus(_scanFocusNode);
    });
    // 监听焦点丢失事件,自动恢复
    _scanFocusNode.addListener(() {
      if (!_scanFocusNode.hasFocus) {
        Future.delayed(const Duration(milliseconds: 100), () {
          if (mounted) {
            FocusScope.of(context).requestFocus(_scanFocusNode);
          }
        });
      }
    });
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // 应用从后台恢复时,重新获取焦点
    if (state == AppLifecycleState.resumed) {
      Future.delayed(const Duration(milliseconds: 100), () {
        if (mounted) {
          FocusScope.of(context).requestFocus(_scanFocusNode);
        }
      });
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _scanFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TextField(
        focusNode: _scanFocusNode,
        decoration: const InputDecoration(hintText: "等待扫码输入"),
        onSubmitted: (value) {
          // 此处处理扫码内容逻辑
        },
      ),
    );
  }
}

2. 强化全屏与防休眠

确保系统UI完全隐藏,同时禁止屏幕休眠:

import 'package:flutter/services.dart';

@override
void initState() {
  super.initState();
  // 彻底隐藏系统UI
  SystemChrome.setEnabledSystemUIMode(
    SystemUiMode.immersiveSticky,
    overlays: [],
  );
  // 锁定屏幕方向,避免旋转干扰
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}

二、树莓派系统层面配置

1. 关闭屏保与省电模式

针对新版Raspberry Pi OS(GNOME桌面):

# 关闭锁屏功能
gsettings set org.gnome.desktop.screensaver lock-enabled false
# 禁用闲置激活屏保
gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
# 设置屏幕永不超时
gsettings set org.gnome.desktop.session idle-delay 0

针对旧版Raspberry Pi OS(LXDE桌面):

# 关闭屏幕保护
xset s off
# 禁用电源管理
xset -dpms
# 禁止屏幕黑屏
xset s noblank

将上述命令添加到~/.bashrc或开机启动脚本中,确保每次开机自动生效。

2. 强制应用窗口始终置顶

使用wmctrl工具锁定应用为前台窗口:

# 安装wmctrl
sudo apt update && sudo apt install wmctrl -y

创建启动脚本(例如start_scan_app.sh):

#!/bin/bash
# 启动Flutter应用
/path/to/your/flutter/app/executable &
# 等待应用启动
sleep 5
# 将应用窗口设置为始终置顶(替换为你的应用窗口标题)
wmctrl -r "你的应用窗口标题" -b add,above

给脚本添加执行权限:

chmod +x start_scan_app.sh

将脚本加入开机自启项,确保应用启动后立即置顶。

3. 禁用干扰性服务

关闭可能抢占焦点的后台服务,比如通知提示:

# 禁用通知服务(可选)
systemctl stop notification-daemon.service
systemctl disable notification-daemon.service

总结

结合Flutter代码的焦点自动恢复逻辑,加上树莓派系统的屏保禁用、窗口置顶配置,即可解决闲置后TextField失焦的问题,确保应用随时能接收扫码枪输入。

内容的提问来源于stack exchange,提问作者Theuno de Bruin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:37:23