Flutter ListView при нажатии перейти к другому экрану - PullRequest
0 голосов
/ 13 апреля 2020

Я учу Флаттер. У меня есть 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,
          )
    );
  }
}

1 Ответ

1 голос
/ 13 апреля 2020

Вы можете скопировать код вставки и выполнить полный код ниже

Шаг 1: Чтобы разрешить Navigator.push работу, вы можете переместить MaterialApp на верхний уровень
Шаг 2: В onTap pass 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(

рабочая демонстрация

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!'),
            ),
          ),
        ],
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...