📜  Flutter Layout Challenge London App brewery - (1)

📅  最后修改于: 2023-12-03 15:00:47.857000             🧑  作者: Mango

Flutter Layout Challenge: London App Brewery

London App Brewery is a well-known institute that teaches mobile app development to people of all backgrounds. Recently, they posted a layout challenge on their social media platforms.

Challenge Details

The challenge was to build a shopping app that showcases a list of products and product details upon selection. The app was expected to have two screens: a landing screen and a product screen. Additionally, the app was to have a bottom navigation bar, which provides quick access to other app features.

Landing Screen

The landing screen featured a list of products with their images, names, and prices. The user should be able to click on any product to see its detailed description.

Product Detail Screen

The product detail screen displayed the selected product's image, name, description, and price, along with the option to add it to the cart.

Bottom Navigation Bar

The bottom navigation bar included three icons: Home, Products, and Cart. The Home icon was to take the user back to the landing screen, the Products icon was to show a list of all available products, and the Cart icon was to display the current cart status.

Layout Design

The London App Brewery provided a rough design of the app screens, which the developers were expected to make visually appealing while maintaining the layout.

App Design

Solution

The challenge required excellent knowledge of Flutter widgets such as ListView, Card, and BottomNavigationBar. Below is a sample solution in Flutter code:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'London App Brewery Challenge',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'London App Brewery Challenge'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _currentIndex = 0;

  final List<Widget> _children = [
    LandingScreen(),
    ProductsScreen(),
    CartScreen(),
  ];

  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: _children[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: onTabTapped,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.list),
            label: 'Products',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.shopping_cart),
            label: 'Cart',
          ),
        ],
      ),
    );
  }
}

class LandingScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: products.length,
        itemBuilder: (BuildContext context, int index) {
          Product product = products[index];
          return Card(
            child: InkWell(
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => ProductDetailScreen(product: product)),
                );
              },
              child: ListTile(
                leading: CircleAvatar(
                  backgroundImage: NetworkImage(product.imageUrl),
                ),
                title: Text(product.name),
                subtitle: Text('Price: \$${product.price}'),
              ),
            ),
          );
        });
  }
}

class ProductDetailScreen extends StatelessWidget {
  final Product product;

  ProductDetailScreen({required this.product});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(product.name),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          SizedBox(height: 20),
          Image.network(product.imageUrl),
          SizedBox(height: 20),
          Text(product.name, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
          SizedBox(height: 10),
          Text('Price: \$${product.price}', style: TextStyle(fontSize: 20, color: Colors.red)),
          SizedBox(height: 10),
          Text(
            product.description,
            style: TextStyle(fontSize: 16),
            textAlign: TextAlign.center,
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {},
            child: Text('Add to Cart'),
          ),
        ],
      ),
    );
  }
}

class ProductsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: products.length,
        itemBuilder: (BuildContext context, int index) {
          Product product = products[index];
          return ListTile(
            leading: CircleAvatar(
              backgroundImage: NetworkImage(product.imageUrl),
            ),
            title: Text(product.name),
            subtitle: Text('Price: \$${product.price}'),
          );
        });
  }
}

class CartScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(child: Text('Cart Screen')),
    );
  }
}

class Product {
  String name;
  String imageUrl;
  String description;
  num price;

  Product({
    required this.name,
    required this.imageUrl,
    required this.description,
    required this.price,
  });
}

final List<Product> products = [
  Product(
    name: 'Sneaker',
    imageUrl: 'https://i.imgur.com/p0honnv.jpg',
    description: 'Comfortable Sneakers',
    price: 99.99,
  ),
  Product(
    name: 'Headphones',
    imageUrl: 'https://i.imgur.com/DvLZAyU.jpg',
    description: 'Noise-Canceling Headphones',
    price: 299.99,
  ),
  Product(
    name: 'Smart Watch',
    imageUrl: 'https://i.imgur.com/YwLMg4p.jpg',
    description: 'Fitness Tracker Smart Watch',
    price: 199.99,
  ),
];
Conclusion

Flutter Layout Challenge provides an excellent opportunity for developers to practice and demonstrate their skills. The London App Brewery Layout Challenge was a great challenge to build a shopping app with different screens and a bottom navigation bar. With the help of Flutter widgets, the solution presented here shows it is straightforward to create such a project.