单击Flutter ListView导航到另一个屏幕

时间:2020-04-13 00:40:38

标签: android listview flutter dart

我正在学习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,
          )
    );
  }
}

2 个答案:

答案 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步:将CardInkWell换行并调用onTap()

 return InkWell(
      onTap: () {
        onTap();
      },
      child: Card(

工作演示

enter image description here

完整代码

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,
        ),
      ),
    );
  }
}