Category

Beginner

Category

Flutter Travel App. Ideal template for listing, social media, and e-commerce applications.

Creating a travel app UI using Flutter involves designing screens like the home screen, destination details, booking screens, and more. Below is an example of how you can start building a simple travel app UI in Flutter.

Prerequisites

Ensure you have Flutter installed and set up on your machine. You can follow the official Flutter installation guide to get started.

Step 1: Setting Up the Project

  1. Create a new Flutter project: flutter create travel_app cd travel_app
  2. Open the project in your preferred IDE (e.g., VSCode, Android Studio).

Step 2: Designing the Home Screen

Let’s start with a basic home screen that displays a list of popular destinations.

lib/main.dart:

import 'package:flutter/material.dart';

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

class TravelApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Travel App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  final List<Map<String, String>> destinations = [
    {
      'name': 'Paris',
      'image': 'https://example.com/paris.jpg',
    },
    {
      'name': 'New York',
      'image': 'https://example.com/newyork.jpg',
    },
    {
      'name': 'Tokyo',
      'image': 'https://example.com/tokyo.jpg',
    },
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Travel App'),
      ),
      body: ListView.builder(
        itemCount: destinations.length,
        itemBuilder: (context, index) {
          return DestinationCard(
            name: destinations[index]['name']!,
            image: destinations[index]['image']!,
          );
        },
      ),
    );
  }
}

class DestinationCard extends StatelessWidget {
  final String name;
  final String image;

  DestinationCard({required this.name, required this.image});

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Image.network(
            image,
            height: 200,
            fit: BoxFit.cover,
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: Text(
              name,
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
          ),
        ],
      ),
    );
  }
}

Step 3: Adding Navigation to Detail Screen

Now, let’s add navigation to a detail screen when a destination is tapped.

lib/main.dart (continued):

import 'package:flutter/material.dart';

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

class TravelApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Travel App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  final List<Map<String, String>> destinations = [
    {
      'name': 'Paris',
      'image': 'https://example.com/paris.jpg',
      'description': 'The City of Light.',
    },
    {
      'name': 'New York',
      'image': 'https://example.com/newyork.jpg',
      'description': 'The Big Apple.',
    },
    {
      'name': 'Tokyo',
      'image': 'https://example.com/tokyo.jpg',
      'description': 'The heart of Japan.',
    },
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Travel App'),
      ),
      body: ListView.builder(
        itemCount: destinations.length,
        itemBuilder: (context, index) {
          return GestureDetector(
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailScreen(
                    name: destinations[index]['name']!,
                    image: destinations[index]['image']!,
                    description: destinations[index]['description']!,
                  ),
                ),
              );
            },
            child: DestinationCard(
              name: destinations[index]['name']!,
              image: destinations[index]['image']!,
            ),
          );
        },
      ),
    );
  }
}

class DestinationCard extends StatelessWidget {
  final String name;
  final String image;

  DestinationCard({required this.name, required this.image});

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Image.network(
            image,
            height: 200,
            fit: BoxFit.cover,
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: Text(
              name,
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
          ),
        ],
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  final String name;
  final String image;
  final String description;

  DetailScreen({required this.name, required this.image, required this.description});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(name),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Image.network(
              image,
              height: 300,
              fit: BoxFit.cover,
            ),
            Padding(
              padding: EdgeInsets.all(16),
              child: Text(
                description,
                style: TextStyle(fontSize: 18),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Step 4: Adding Some Styling

To make the app more visually appealing, you can enhance the styling of the components.

lib/main.dart (continued with styling):

“`dart
import ‘package:flutter/material.dart’;

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

class TravelApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Travel App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
);
}
}

class HomeScreen extends StatelessWidget {
final List> destinations = [
{
'name': 'Paris',
'image': 'https://example.com/paris.jpg',
'description': 'The City of Light.',
},
{
'name': 'New York',
'image': 'https://example.com/newyork.jpg',
'description': 'The Big Apple.',
},
{
'name': 'Tokyo',
'image': 'https://example.com/tokyo.jpg',
'description': 'The heart of Japan.',
},
];

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Travel App'),
),
body: ListView.builder(
itemCount: destinations.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(
name: destinations[index]['name']!,
image: destinations[index]['image']!,
description: destinations[index]['description']!,
),
),
);
},
child: DestinationCard(
name: destinations[index]['name']!,
image: destinations[index]['image']!,
),
);
},
),
);
}
}

class DestinationCard extends StatelessWidget {
final String name;
final String image;

DestinationCard({required this.name, required this.image});

@override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
elevation: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(15)),
child: Image.network(
image,
height: 200,
fit: BoxFit.cover,
),
),
Padding(
padding: EdgeInsets.all(10),
child: Text(
name,
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
],
),
);
}
}

class DetailScreen extends StatelessWidget {
final String name;
final String image;
final String description;

DetailScreen({required this.name, required this.image, required this.description});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(name),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Image.network(
image,
height: 300,
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.all(16),
child: Text(
description,
style: TextStyle(font

Explanation

  1. Main Function and App Entry Point: The main function runs the TravelApp widget, which is the root of the app.
  2. MaterialApp: Sets up the app with a title, theme, and home screen.
  3. HomeScreen: A stateless widget that displays the home screen with a list of destinations in a grid view.
  4. Destination Model: A simple class representing a travel destination with a name, image URL, and description.
  5. DestinationCard: A stateless widget to display each destination in a card with an image, name, and description.
  6. Sample Data: A list of sample destinations with dummy data.

You can expand this example by adding more screens (e.g., details screen, profile screen), navigation, and other features. This code provides a starting point for a travel app with a modern and clean UI using Flutter.