Hi im trying to get the index of a particular widget in a list
static const List<Widget> _widgetOptions = <Widget>[
Index(),
Achievements(),
];
so get it when to get a certain widget
_widgetOptions.elementAt(_selectedIndex)
but I am having a hard time getting the index of a widget.
I tried int index = _widgetOptions.indexOf(Index());
but it is returning a value of -1 which translate to not found.
CodePudding user response:
I don't know what type of widgets are in your list but it would be better to use you list in ListView.builder
and if the widgets are wrapped in something like gestureDetector
or button
just create an int variable index = - 1
and when one widget is clicked or pressed use a setSate(() => index = i)
. (I call i
the index in your ListView.builder
.
CodePudding user response:
So let's talk about List<T>
in Dart!
If you look at the source code for indexOf
you'll see this documentation:
/// The first index of [element] in this list.
///
/// Searches the list from index [start] to the end of the list.
/// The first time an object `o` is encountered so that `o == element`,
/// the index of `o` is returned.
Pay special attention to the o == element
meaning that the item that you're trying to find has to implement the ==
operator. If you look deeper into the source code for Flutter you will see that StatelessWidget
implements DiagnosticableTree
and that itself implements the ==
operator:
/// Compare two widgets for equality.
///
/// When a widget is rebuilt with another that compares equal according
/// to `operator ==`, it is assumed that the update is redundant and the
/// work to update that branch of the tree is skipped.
You can prove that it all works by writing this code:
final widget1 = const MyText();
final widget2 = const MyText();
final List<dynamic> texts = [widget1, widget2];
final i1 = texts.indexOf(widget1);
final i2 = texts.indexOf(widget2);
assert(i1 == 0);
assert(i2 == 1);
And you'll see that Flutter is indeed able to find those elements at the right index. So that's the first point.
However, after more than 2 years of Flutter development I've never had to do this which tells me what you're doing can be achieved in many other ways, such as using a ListView.builder()
that creates a widget for all the itemCount
that you provide to it.
CodePudding user response:
When you call '_widgetOptions.indexOf(Index())' to find Widget index,
the two 'Index()' Widget instance will be made.
So the 'Index()' instance is different between '_widgetOptions' and 'Index()'.
Below is example code and result.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// the text entered by the user
Widget? indexWidget;
Widget? achievements;
Widget Index() {
return Container();
}
Widget Achievements() {
return Column(
children: [
Container(),
]
);
}
@override
void initState() {
super.initState();
indexWidget = Index();
achievements = Achievements();
List<Widget?> _widgetOptions = <Widget?> [
Index(),
Achievements(),
];
List<Widget?> _widgetOptions2 = <Widget?> [
indexWidget,
achievements,
];
print(_widgetOptions.indexOf(Index()));
print(_widgetOptions2.indexOf(indexWidget));
print(_widgetOptions2.indexOf(Index()));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(),
),
),
);
}
}