我正在学习Flutter。我有一个ListView,我想使列表项可单击。我的想法是,当用户单击某个项目时,它将被定向到另一个屏幕。每个按钮应导致不同的屏幕。我在实现它时遇到了麻烦,我不知道该用什么:手势检测器或ontap。我该怎么办?我应该使用ListTile而不是ListView吗?
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = "ListView List";
return MaterialApp(
title: title,
home: Scaffold(appBar: AppBar(
title: Text(title),
),
body: new ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(20.0),
children: List.generate(choices.length, (index) {
return Center(
child: ChoiceCard(choice: choices[index], item: choices[index]),
);
}
)
)
)
);
}
}
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'This is a Car', icon: Icons.directions_car),
const Choice(title: 'This is a Bicycle', icon: Icons.directions_bike),
const Choice(title: 'This is a Boat', icon: Icons.directions_boat),
const Choice(title: 'This is a Bus', icon: Icons.directions_bus),
const Choice(title: 'This is a Train', icon: Icons.directions_railway),
];
class ChoiceCard extends StatelessWidget {
const ChoiceCard(
{Key key, this.choice, this.onTap, @required this.item, this.selected: false}
) : super(key: key);
final Choice choice;
final VoidCallback onTap;
final Choice item;
final bool selected;
@override
Widget build(BuildContext context) {
TextStyle textStyle = Theme.of(context).textTheme.display1;
if (selected)
textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
return Card(
color: Colors.white,
child: Row(
children: <Widget>[
new Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.topLeft,
child: Icon(choice.icon, size:80.0, color: textStyle.color,)),
new Expanded(
child: new Container(
padding: const EdgeInsets.all(10.0),
alignment: Alignment.topLeft,
child:
Text(choice.title, style: null, textAlign: TextAlign.left, maxLines: 5,),
)
),
],
crossAxisAlignment: CrossAxisAlignment.start,
)
);
}
}
答案 0 :(得分:2)
您可以在
第1步:要允许Navigator.push
工作,您可以将MaterialApp
移到上一级
步骤2:在onTap
中传递Navigator.push
ChoiceCard(
choice: choices[index],
item: choices[index],
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(choice: choices[index])),
);
},
),
第3步:将Card
与InkWell
换行并调用onTap()
return InkWell(
onTap: () {
onTap();
},
child: Card(
工作演示
完整代码
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: HomePage());
}
}
class HomePage extends StatelessWidget {
final title = "ListView List";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: new ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(20.0),
children: List.generate(choices.length, (index) {
return Center(
child: ChoiceCard(
choice: choices[index],
item: choices[index],
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detail(choice: choices[index])),
);
},
),
);
})));
}
}
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'This is a Car', icon: Icons.directions_car),
const Choice(title: 'This is a Bicycle', icon: Icons.directions_bike),
const Choice(title: 'This is a Boat', icon: Icons.directions_boat),
const Choice(title: 'This is a Bus', icon: Icons.directions_bus),
const Choice(title: 'This is a Train', icon: Icons.directions_railway),
];
class ChoiceCard extends StatelessWidget {
const ChoiceCard(
{Key key,
this.choice,
this.onTap,
@required this.item,
this.selected: false})
: super(key: key);
final Choice choice;
final VoidCallback onTap;
final Choice item;
final bool selected;
@override
Widget build(BuildContext context) {
TextStyle textStyle = Theme.of(context).textTheme.display1;
if (selected)
textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
return InkWell(
onTap: () {
onTap();
},
child: Card(
color: Colors.white,
child: Row(
children: <Widget>[
new Container(
padding: const EdgeInsets.all(8.0),
alignment: Alignment.topLeft,
child: Icon(
choice.icon,
size: 80.0,
color: textStyle.color,
)),
new Expanded(
child: new Container(
padding: const EdgeInsets.all(10.0),
alignment: Alignment.topLeft,
child: Text(
choice.title,
style: null,
textAlign: TextAlign.left,
maxLines: 5,
),
)),
],
crossAxisAlignment: CrossAxisAlignment.start,
)),
);
}
}
class Detail extends StatelessWidget {
final Choice choice;
Detail({this.choice});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Column(
children: <Widget>[
Text("${choice.title}"),
Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
],
),
);
}
}
答案 1 :(得分:0)
import 'package:easy_buss/screen/client.dart';
import 'package:easy_buss/screen/invoice.dart';
import 'package:easy_buss/screen/invoice_settings.dart';
import 'package:easy_buss/screen/payment_info.dart';
import 'package:easy_buss/widgets/payment_info_form.dart';
import 'package:flutter/material.dart';
class Settings extends StatefulWidget {
@override
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<Settings> {
List<IconData> _icon = [
Icons.accessible,
Icons.analytics,
Icons.question_answer_sharp,
Icons.message,
Icons.share,
Icons.star_half,
Icons.add_business,
Icons.privacy_tip,
];
List<String> _title = [
'Invoice Settings',
'Reports',
'Frequently Ask Questions',
'Write Us',
'Share With A Friends',
'Rate Us',
'Terms & Conditions',
'Privacy Policy',
];
List<Color> _colors = [
Colors.cyan,
Colors.yellow,
Colors.red,
Colors.purple,
Colors.orange,
Colors.grey,
Colors.pink[300],
Colors.green[200],
];
List _items = [
InvoiceSettings(),
InvoiceSettings(),
InvoiceSettings(),
InvoiceSettings(),
InvoiceSettings(),
InvoiceSettings(),
InvoiceSettings(),
InvoiceSettings(),
];
@override
Widget build(BuildContext context) {
return ListView.separated(
itemCount: _title.length,
separatorBuilder: (BuildContext context, int index) => Container(
padding: EdgeInsets.only(
left: 10,
right: 10,
),
child: Divider(
thickness: 1,
),
),
itemBuilder: (BuildContext context, int index) => ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => _items[index],
),
);
},
leading: Container(
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: _colors[index],
),
child: Icon(
_icon[index],
color: Colors.white,
size: 20,
),
),
title: Text(
_title[index],
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
trailing: Icon(
Icons.chevron_right,
size: 40,
),
),
);
}
}