Невозможно переключить фокус между двумя перекрывающимися виджетами.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Невозможно переключить фокус между двумя перекрывающимися виджетами.

Сообщение Anonymous »

Я работаю над приложением, адаптированным для Android TV, и вот мой макет:
элемент списка с кнопкой удаления, это два дочерних элемента в виджете «Стек».
чтобы запустить его на телевизоре, мне нужно убедиться, что мы можем переключить фокус на все, но в этом макете я не могу переключить фокус с всего элемента на эту конечную кнопку с помощью любой клавиши со стрелкой.
в начале я придумал способ, вот мой код
class ListItem extends HookWidget {
final (int, PlayableItem) e;

const ListItem(
this.e, {
super.key,
});

@override
Widget build(BuildContext context) {
// whole item focusNode
final itemFocusNode = useFocusNode();
// trailing focusNode
final trailingFocusNode = useFocusNode();

// item focus state
final itemFocused = useState(false);

//change color by item focusState
final foregroundColor = useState(Colors.black);
final bgColor = useState(Colors.transparent);

itemFocusNode.addListener(() {
itemFocused.value = itemFocusNode.hasFocus;
if (itemFocusNode.hasFocus) {
foregroundColor.value = Colors.white;
bgColor.value = Theme.of(context).primaryColor;
} else {
foregroundColor.value = Colors.black;
bgColor.value = Colors.transparent;
}
});

return Stack(
alignment: Alignment.center,
children: [
InkWell(
// for Tap and Enter interaction
focusNode: itemFocusNode,
onTap: () {
/// to support touch screen Tap and keyboard Enter key
/// seems only inkwell can do this
},
focusColor: bgColor.value, // when whole item is focused, bg is blue, otherwise transparent
child: Focus(
// to switch focus manually
onKeyEvent: (node, event) {
switch (event.logicalKey) {
case LogicalKeyboardKey.arrowRight:
// switch focus here
itemFocusNode.unfocus();
trailingFocusNode.requestFocus();
break;
default:
break;
}
return KeyEventResult.ignored;
},
child: Container()), // ignored child
),
Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.only(right: 8.0),
child: PBInkWell(
/// my own inkwell to implement outline border as focused bg.
focusNode: trailingFocusNode, // trailing focusNode
focusBorderType: FocusBorderType.rect,
onTap: () => ListController.find().removeFile(e.$1),
builder: (context, isFocused, child) => SvgPicture.asset(
"assets/images/delete.svg",
width: 20,
colorFilter: itemFocused.value
? const ColorFilter.mode(Colors.white, BlendMode.srcIn)
: isFocused
? ColorFilter.mode(Theme.of(context).primaryColor, BlendMode.srcIn)
: null,
),
),
),
)
],
);
}
}


с помощью этого кода я могу переключить фокус с всего элемента на его конечный элемент, и благодаря поведению флаттера по умолчанию мне не нужно обрабатывать обратную версию, от завершающего элемента к его родительскому элементу, это может быть легко переключается клавишей «Стрелка влево» без какого-либо дополнительного кода.
Кажется, все в порядке, но, как вы можете видеть, это список, и, кстати, я использую ReorderableListView для поддержки изменения порядка при касании экран, моя проблема:
После прыжка вниз к элементу он работает хорошо, но после прыжка вверх он не работает.
показан gif эта проблема
на этой гифке я использую только клавишу со стрелкой на клавиатуре для управления, и, подпрыгивая, чтобы сфокусироваться на первом элементе, я на самом деле нажимал клавишу со стрелкой вправо столько раз, и это просто не работает. Но переходя ко второму элементу, он работает хорошо.
вот мой код просмотра списка, он находится в ящике
class PlayerDrawer extends HookWidget {
const PlayerDrawer({super.key});

@override
Widget build(BuildContext context) {
final isReorderMode = useState(fasle);

return Container(
color: Colors.white.withAlpha((255 * 0.9).round()),
width: 300,
child: Column(
children: [
ListTile(
style: ListTileStyle.list,
leading: Text("Play List", style: Theme.of(context).textTheme.titleLarge),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (!isReorderMode.value)
PBInkWell(
onTap: ListController.find().removeAll,
builder: (context, isFocused, child) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 2.0),
child: Text("Clear All",
style: TextStyle(
color: isFocused ? Theme.of(context).primaryColor : Colors.black,
)),
),
),
Obx(() {
final isUsingKeyboard = ListController.find().isUseKeyboard.value;

return isUsingKeyboard
? const SizedBox()
: PBInkWell(
onTap: ListController.find().switchMode,
builder: (context, isFocused, child) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 2.0),
child: Text(isReorderMode.value ? "Done" : "Sort",
style: TextStyle(
color: isFocused ? Theme.of(context).primaryColor : Colors.black,
)),
),
);
}),
],
),
),
Expanded(
child: Obx(() {
final list = ListController.find().data;
return ReorderableListView(
onReorder: ListController.find().reorderFileList,
children: buildList(context, list),
);
}),
),
],
),
);
}

List buildList(BuildContext context, List
list) {
return list.indexed
.map(
(e) => ListItem(
e,
key: ValueKey("${e.$1}-${e.$2.uri}"),
),
)
.toList();
}
}

дайте мне знать, если вам нужно увидеть больше кода.
кстати, это результат команды flutter Doctor -v
[✓] Flutter (Channel stable, 3.19.6, on macOS 14.3.1 23D60 darwin-arm64, locale zh-Hans-JP)
• Flutter version 3.19.6 on channel stable at /Users/inbottest2/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 54e66469a9 (4 个月前), 2024-04-17 13:08:03 -0700
• Engine revision c4cd48e186
• Dart version 3.3.4
• DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/inbottest2/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• ANDROID_HOME = /Users/inbottest2/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15F31d
• CocoaPods version 1.15.2

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)

[✓] VS Code (version 1.91.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.94.0

[✓] Connected device (4 available)
• AGS3 AL09HN (mobile) • 192.168.22.112:5555 • android-arm64 • Android 10 (API 29)
• Connected (mobile) • 00008110-00142D6E2E78801E • ios • iOS 17.6 21G80
• macOS (desktop) • macos • darwin-arm64 • macOS 14.3.1 23D60 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 127.0.6533.74

[✓] Network resources
• All expected network resources are available.

• No issues found!


Подробнее здесь: https://stackoverflow.com/questions/788 ... ing-widget
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»