我正在為Android TV開發一款應用程式,并使用DPAD導航。 我在一列中擁有多個小組件。當我導航到視圖外的小組件時,小組件/視圖沒有移動以反映所選小組件。
// ignore_for_file: avoid_print
import 'package:flutter/material.dart'。
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
void main() => runApp(const MyApp())。
class MyApp extends StatelessWidget{
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
標題。_title,
首頁。Scaffold(
appBar: AppBar(title: const Text(_title))。
body: const MyStatelessWidget()。
),
);
}
}
class MyStatelessWidget extends StatelessWidget{
const MyStatelessWidget({Key? key}) : super(key: key)。
@override
Widget build(BuildContext context) {
final TextTheme textTheme = Theme.of(context).textTheme。
return DefaultTextStyle(
style: textTheme.headline4!
孩子。ChangeNotifierProvider<SampleNotifier>(
創建。(context) => SampleNotifier(), child: const CardHolder())。
);
}
}
class CardHolder extends StatefulWidget{
const CardHolder({Key? key}) : super(key: key);
@override
_CardHolderState createState() => _CardHolderState()。
}
class _CardHolderState extends State< CardHolder> {
late FocusNode _focusNode;
late FocusAttachment _focusAttachment;
@override
void initState() {
super.initState()。
_focusNode = FocusNode(debugLabel: "traversal_node"/span>)。
_focusAttachment = _focusNode.attach(context, onKey: _handleKeyPress)。
_focusNode.requestFocus()。
}
@override
Widget build(BuildContext context) {
_focusAttachment.reparent()。
return Focus(
focusNode: _focusNode,
autofocus: true,
onKey: _handleKeyPress,
孩子。Consumer<SampleNotifier>(
構建者。(context, models, child) {
int listSize = Provider.of<SampleNotifier>(context).listSize。
return SingleChildScrollView(
孩子。SampleRow(cat: "Test", models: models.modelList)。
);
},
),
);
}
KeyEventResult _handleKeyPress(FocusNode node, RawKeyEvent event) {
if (event is RawKeyDownEvent) {
print("t:FocusNode: ${node.debugLabel}事件。${event.logicalKey}")。)
if (event.logicalKey == LogicalKeyboardKey.arrowRight) {
Provider.of<SampleNotifier>(context, listen: false).moveRight()。
return KeyEventResult.handled。
} else if (event.logicalKey == LogicalKeyboardKey.arrowLeft) {
Provider.of<SampleNotifier>(context, listen: false).moveLeft()。
return KeyEventResult.handled。
}
}
//debugDumpFocusTree();
return KeyEventResult.ignored;
}
}
class SampleCard extends StatefulWidget{
final int number。
final SampleModel model;
final bool focused;
const SampleCard(
{required this.number,
required this.focus,
required this.model。
Key? key})
: super(key: key)。
@override
_SampleCardState createState() => _SampleCardState()。
}
class _SampleCardState extends State< SampleCard> {
late Color _color;
@override
void initState() {
super.initState()。
_color = Colors.red.shade900;
}
@ override.
void dispose() {
super.dispose()。
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric( horizontal: 10)。
child: widget.focused
? 容器(
width: 150,
高度。300,
color: Colors.white,
孩子。Center(
孩子。文本(
"${widget.model.text} ${widget.model.num}"/span>。
風格。TextStyle(color: _color)。
),
),
)
: 容器(
width: 150,
高度。300。
color: Colors.black,
孩子。Center(
孩子。文本(
"${widget.model.text} ${widget.model.num}"/span>。
風格。TextStyle(color: _color)。
),
),
),
);
}
}
class SampleRow extends StatelessWidget{
final String cat。
final List< SampleModel> models;
SampleRow({Key? key, required this.cat, required this.models}) : super(key: 關鍵)。
@override
Widget build(BuildContext context) {
final int selectedIndex =
Provider.of<SampleNotifier>(context).selectedIndex。
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
兒童。[
const Padding(
padding: EdgeInsets.only(left: 16, bottom: 8)。)
),
models.isNotEmpty
? SizedBox(
高度。200。
孩子。ListView.custom(
padding: const EdgeInsets.all(8)。
滾動方向。Axis.horizontal,
childrenDelegate: SliverChildBuilderDelegate(
(context, index) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 8) 。
孩子。SampleCard(
重點: index == selectedIndex,
模型: models[index],
number: index,
),
),
childCount: models.length,
findChildIndexCallback。_findChildIndex。
),
),
)
: SizedBox(
高度。200。
孩子。容器(
color: Colors.teal,
),
)
],
);
}
int _findChildIndex(Key key) => models.indexWhere((model) =>
"$cat-${model.text}_${model. num}" ==(key as ValueKey<String>).value)。
}
class SampleNotifier extends ChangeNotifier{
final List<SampleModel> _models = [
SampleModel(0, "zero") 。
SampleModel(1, "one")。
SampleModel(2, "2")。
SampleModel(3, "three") 。
SampleModel(4, "4")。
SampleModel(5, "5")。
SampleModel(6, "6")。
SampleModel(7, "7")。
SampleModel(8, "8")。
SampleModel(9, "9")。
SampleModel(10, "ten")
];
int _selectedIndex = 0;
List<SampleModel> get modelList => _models;
int get selectedIndex => _selectedIndex;
int get listSize => _models.length;
void moveRight() {
if (_selectedIndex < _models.length - 1) {
_selectedIndex = _selectedIndex 1;
}
notifyListeners()。
}
void moveLeft() {
if (_selectedIndex > 0) {
_selectedIndex = _selectedIndex - 1;
}
notifyListeners()。
}
}
class SampleModel{
int num;
String text。
SampleModel(this.num, this.text)。)
我需要一種方法來移動/滾動小部件進入視圖。是否有任何方法可以做到這一點,使用安卓電視上的DPAD導航
。uj5u.com熱心網友回復:
你可以使用scrollable_positioned_list包。
代替基于像素滾動的ListView.custom,這個小部件基于索引:
final ItemScrollController itemScrollController = ItemScrollController() 。
ScrollablePositionedList.builder(
itemCount: 500,
itemBuilder: (context, index) => Text('Item $index')。
itemScrollController: itemScrollController,
itemPositionsListener: itemPositionsListener,
);
因此,你可以保持一個當前滾動位置的索引,在DPAD上按下 :
itemScrollController.jumpTo(index: currentItem)。
setState((){currentItem ;})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/313109.html
標籤:
