John Sly
John Sly

Reputation: 769

Flutter: ontap in a stack

I'm still getting my feet wet working with flutter, so I'm hoping this is something easy to solve

I have a chunk of code that will load a JSON feed, place it in a column and display the individual items. I want to have an onTap to redirect the screen to a detail screen. I want to do a call like:

onTap: (){ showVehiclePage(context, snapshot.data.vehicles[index]); },

The challenge is, I can't figure out how to get it to work. I can't place the onTap anywhere and I tried using InkWell, but I'm not figuring out how to place it without errors. I'm still a bit green with flutter, but how can I call my showVehiclePage function when I tap on the stack children?

class browseRC extends StatelessWidget {
  final Future<Vehicles> vehicles;

  browseRC({Key key, this.vehicles}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Browse RCs',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Center(
          child: FutureBuilder<Vehicles>(
            future: vehicles,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                ListView.builder(
                  itemCount: snapshot.data.vehicles.length,
                  itemBuilder: (context, index) {
                    //Vehicle thisVeh = snapshot.data.vehicles[index];
                    return Column(
                      children: <Widget>[
                        Stack(
                        children: <Widget>[
                          FadeInImage.memoryNetwork(
                            placeholder: kTransparentImage,
                            image: '${snapshot.data.vehicles[index].defImage}',
                            height: 250,
                            fit: BoxFit.cover,
                          ),
                          Container(
                            padding: EdgeInsets.all(5.0),
                            margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 5.0),
                            //width: 250,
                            height: 250,
                            alignment: Alignment.bottomCenter,
                            decoration: BoxDecoration(
                              gradient: LinearGradient(
                                begin: Alignment.topCenter,
                                end: Alignment.bottomCenter,
                                colors: <Color>[
                                  Colors.black.withAlpha(0),
                                  Colors.black12,
                                  Colors.black87
                                ],
                              ),
                            ),

                            child: Text(
                              '${snapshot.data.vehicles[index].title}',
                              style: TextStyle(
                                  color: Colors.white, fontSize: 20.0),
                            ),
                          )
                        ])
                      ],
                    );
                  },
                );
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }
              // By default, show a loading spinner.
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }

  void showVehiclePage(BuildContext context, Vehicle vehicle) {
    Navigator.push(
        context,
        new MaterialPageRoute<Null>(
            settings: const RouteSettings(name: VehiclePage.routeName),
            builder: (BuildContext context) => new VehiclePage(vehicle)));
  }
}

Upvotes: 2

Views: 1575

Answers (2)

chunhunghan
chunhunghan

Reputation: 54365

You can copy paste run full code below
Step 1: You can check ConnectionState
Step 2: You can use InkWell wrap Column
code snippet

 return ListView.builder(
                        itemCount: snapshot.data.vehicles.length,
                        itemBuilder: (context, index) {
                          //Vehicle thisVeh = snapshot.data.vehicles[index];
                          return InkWell(
                            onTap: () {
                              showVehiclePage(
                                  context, snapshot.data.vehicles[index]);
                            },
                            child: Column(
                              children: <Widget>[

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';

class Vehicles {
  List<Vehicle> vehicles;
  Vehicles({this.vehicles});
}

Future<Vehicles> getVehicles() {
  var a = [
    Vehicle(title: "a", defImage: "https://picsum.photos/250?image=9"),
    Vehicle(title: "b", defImage: "https://picsum.photos/250?image=10")
  ];
  print("return");
  return Future.value(Vehicles(vehicles: a));
}

class browseRC extends StatelessWidget {
  final Future<Vehicles> vehicles;

  browseRC({Key key, this.vehicles}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Browse RCs',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(
            body: Center(
          child: FutureBuilder<Vehicles>(
              future: vehicles,
              builder: (context, snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none:
                    return Text('none');
                  case ConnectionState.waiting:
                    return Center(child: CircularProgressIndicator());
                  case ConnectionState.active:
                    return Text('');
                  case ConnectionState.done:
                    if (snapshot.hasError) {
                      return Text(
                        '${snapshot.error}',
                        style: TextStyle(color: Colors.red),
                      );
                    } else {
                      return ListView.builder(
                        itemCount: snapshot.data.vehicles.length,
                        itemBuilder: (context, index) {
                          //Vehicle thisVeh = snapshot.data.vehicles[index];
                          return InkWell(
                            onTap: () {
                              showVehiclePage(
                                  context, snapshot.data.vehicles[index]);
                            },
                            child: Column(
                              children: <Widget>[
                                Stack(children: <Widget>[
                                  FadeInImage.memoryNetwork(
                                    placeholder: kTransparentImage,
                                    image:
                                        '${snapshot.data.vehicles[index].defImage}',
                                    height: 250,
                                    fit: BoxFit.cover,
                                  ),
                                  Container(
                                    padding: EdgeInsets.all(5.0),
                                    margin:
                                        EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 5.0),
                                    //width: 250,
                                    height: 250,
                                    alignment: Alignment.bottomCenter,
                                    decoration: BoxDecoration(
                                      gradient: LinearGradient(
                                        begin: Alignment.topCenter,
                                        end: Alignment.bottomCenter,
                                        colors: <Color>[
                                          Colors.black.withAlpha(0),
                                          Colors.black12,
                                          Colors.black87
                                        ],
                                      ),
                                    ),

                                    child: Text(
                                      '${snapshot.data.vehicles[index].title}',
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 20.0),
                                    ),
                                  )
                                ])
                              ],
                            ),
                          );
                        },
                      );
                    }
                }
              }),
        )));
  }

  void showVehiclePage(BuildContext context, Vehicle vehicle) {
    Navigator.push(
        context,
        MaterialPageRoute<Null>(
            builder: (BuildContext context) => VehiclePage(vehicle)));
  }
}

class Vehicle {
  String defImage;
  String title;

  Vehicle({this.title, this.defImage});
}

class VehiclePage extends StatelessWidget {
  final Vehicle vehicle;
  VehiclePage(this.vehicle);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          appBar: AppBar(
            title: Text("${vehicle.title}"),
          ),
          body: Column(
            children: [
              Text("${vehicle.title}"),
              FadeInImage.memoryNetwork(
                placeholder: kTransparentImage,
                image: '${vehicle.defImage}',
                height: 250,
                fit: BoxFit.cover,
              ),
            ],
          )),
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: browseRC(
        vehicles: getVehicles(),
      ),
    );
  }
}

Upvotes: 2

encubos
encubos

Reputation: 3273

You should take a look at GestureDetector widget.

https://api.flutter.dev/flutter/widgets/GestureDetector-class.html

You can wrap your Container or your Image with this widget like this, and use the onTap method the way you want.

  GestureDetector(
    onTap: () {
      showVehiclePage(context, snapshot.data.vehicles[index]);
    },
    child: Container(,
      child: OtherWidget(),
    ),
  ),

I hope this give you an idea to try somthing similar in your code.

Upvotes: 1

Related Questions