Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue #9] Implement Home Screen UI #11

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ migrate_working_dir/
.pub-cache/
.pub/
/build/
*.g.dart
*.gen.dart
pubspec.lock

# Symbolication related
app.*.symbols
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
# flutter_movie_clean
A sample Flutter application follow clean architecture

## Installation
Clone this repository
```bash
git clone [email protected]:namnh-0652/flutter_movie_clean.git
```
Install Pub
```bash
flutter clean
flutter pub get
```

Run command to add file `locale_keys.g.dart`, this file support for library `easy_localization`
```bash
flutter pub run easy_localization:generate -S assets/translations -f keys -o locale_keys.g.dart
```

Run command to run code generator for your assets, fonts, colors... by `FlutterGen`
```bash
flutter packages pub run build_runner build
```
4 changes: 4 additions & 0 deletions assets/color/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="crimson_approx">#ED1B24</color>
</resources>
Binary file added assets/images/bg_profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/icons/ic_categories.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/icons/ic_downloads.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/icons/ic_home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/icons/ic_more.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/marvel_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/movies/movies1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/movies/movies2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/movies/movies3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboardings/poster1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboardings/poster2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboardings/poster3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboardings/poster4.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboardings/poster5.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/onboardings/poster6.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/profile_avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/series/series1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/series/series2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/series/series3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/trendings/trending_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/trendings/trending_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/trendings/trending_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/trendings/trending_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions assets/translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"continueOnBoarding": "Continue",
"login": "Login",
"signup": "Signup",
"onBoardingPageFirstTitle": "All your favorite \n MARVEL Movies & Series \n at one place",
"onBoardingPageSecondTitle": "Watch Online \n or \n Download Offline",
"onBoardingPageThirdTitle": "Create profiles for \n different members & \n get personalised \n recommendations",
"onBoardingPageFourthTitle": "Plans according to your \n needs at affordable \n prices",
"onBoardingPageFifthTitle": "Let's Get Started !!!",
"home": "Home",
"categories": "Categories",
"downloads": "Downloads",
"more": "More",
"latestMovies": "Latest Movies",
"latestSeries": "Latest Series",
"trendingToday": "Trending Today",
"oldMovies": "Old Movies",
"oldSeries": "Old Series"
}
19 changes: 19 additions & 0 deletions assets/translations/vi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"continueOnBoarding": "Tiếp tục",
"login": "Đăng nhập",
"signup": "Đăng ký",
"onBoardingPageFirstTitle": "Tất cả \n phim MARVEL & Series \n tại một nơi",
"onBoardingPageSecondTitle": "Xem trực tuyến \n hoặc \n tải xuống ngoại tuyến",
"onBoardingPageThirdTitle": "Tạo hồ sơ cho \n các thành viên khác nhau & \n nhận đề xuất \n được cá nhân hóa",
"onBoardingPageFourthTitle": "Các gói theo nhu cầu của bạn \n với mức giá phải chăng",
"onBoardingPageFifthTitle": "Bắt đầu thôi !!!",
"home": "Trang chủ",
"categories": "Thể loại",
"downloads": "Tải xuống",
"more": "Thêm",
"latestMovies": "Những Bộ Phim Gần Đây",
"latestSeries": "Sê-ri Mới Nhất",
"trendingToday": "Xu Hướng Hôm Nay",
"oldMovies": "Những Bộ Phim Cũ",
"oldSeries": "Sê-ri Cũ"
}
7 changes: 7 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>

<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>vi</string>
</array>

<key>CFBundleDisplayName</key>
<string>Flutter Movie Clean</string>
<key>CFBundleExecutable</key>
Expand Down
29 changes: 29 additions & 0 deletions lib/bloc_observer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flutter_bloc/flutter_bloc.dart';

class AppBlocObserver extends BlocObserver {
const AppBlocObserver();

@override
void onEvent(Bloc bloc, Object? event) {
super.onEvent(bloc, event);
print(event);
}

@override
void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
super.onError(bloc, error, stackTrace);
print(error);
}

@override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
print(change);
}

@override
void onTransition(Bloc bloc, Transition transition) {
super.onTransition(bloc, transition);
print(transition);
}
}
10 changes: 10 additions & 0 deletions lib/categories/categories.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';

class CategoriesScreen extends StatelessWidget {
const CategoriesScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return const Center(child: Text("Categories"),);
}
}
10 changes: 10 additions & 0 deletions lib/downloads/downloads.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';

class DownloadsScreen extends StatelessWidget {
const DownloadsScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return const Center(child: Text("Download"),);
}
}
6 changes: 6 additions & 0 deletions lib/exports/screens.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export '/categories/categories.dart';
export '/downloads/downloads.dart';
export '/home/home_page.dart';
export '/more/more.dart';
export '/moviedetails/movie_details.dart';
export '/onboarding/on_boarding.dart';
51 changes: 51 additions & 0 deletions lib/home/components/carousel_slider_shader.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';

class CarouselSliderShaderWidget extends StatelessWidget {
const CarouselSliderShaderWidget({
super.key,
required List<String> paths, required this.onItemTapped,
}) : _paths = paths;

final Gradient _maskingGradient = const LinearGradient(
colors: [
Colors.black,
Colors.transparent,
],
stops: [0.0, 0.4],
tileMode: TileMode.mirror,
begin: Alignment.centerLeft,
end: Alignment.center,
);
final List<String> _paths;
final Function(int index) onItemTapped;

@override
Widget build(BuildContext context) {
return ShaderMask(
shaderCallback: (bounds) => _maskingGradient.createShader(bounds),
blendMode: BlendMode.darken,
child: CarouselSlider(
options: CarouselOptions(
height: 173.0,
enlargeFactor: 0.2,
viewportFraction: 0.7,
enlargeCenterPage: true,
),
items: _paths.map((path) {
return Builder(builder: (BuildContext context) {
return GestureDetector(
child: Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(horizontal: 6.0),
decoration: const BoxDecoration(color: Colors.amber),
child: Image.asset(path, fit: BoxFit.fill),
),
onTap: () {onItemTapped(_paths.indexOf(path));},
);
});
}).toList(),
),
);
}
}
40 changes: 40 additions & 0 deletions lib/home/components/horizontal_movie_list_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';

class HorizontalMoviesListView extends StatelessWidget {
const HorizontalMoviesListView({
super.key,
required List<String> paths,
required this.itemWidth,
required this.itemHeight,
required this.onItemTapped,
}) : _paths = paths;

final List<String> _paths;
final double itemWidth;
final double itemHeight;
final Function(int index) onItemTapped;

@override
Widget build(BuildContext context) {
return ListView.builder(
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: _paths.length,
itemBuilder: (BuildContext context, int index) => Padding(
padding: const EdgeInsets.only(
left: 12.0,
),
child: GestureDetector(
child: Image.asset(
_paths.elementAt(index),
fit: BoxFit.cover,
width: itemWidth,
height: itemHeight,
),
onTap: () => {onItemTapped(index)},
),
),
);
}
}
6 changes: 6 additions & 0 deletions lib/home/cubit/home_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_movie_clean/home/cubit/home_state.dart';

class HomeCubit extends Cubit<HomeState> {
HomeCubit() : super(HomeState());
}
28 changes: 28 additions & 0 deletions lib/home/cubit/home_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import '../../generated/assets.gen.dart';

class HomeState {
HomeState();

final List<String> moviesPaths = [
Assets.images.movies.movies1.path,
Assets.images.movies.movies2.path,
Assets.images.movies.movies3.path,
];

final List<String> seriesPaths = [
Assets.images.series.series1.path,
Assets.images.series.series2.path,
Assets.images.series.series3.path,
];

final List<String> trendingPaths = [
Assets.images.trendings.trending1.path,
Assets.images.trendings.trending2.path,
Assets.images.trendings.trending3.path,
Assets.images.trendings.trending4.path,
Assets.images.trendings.trending1.path,
Assets.images.trendings.trending2.path,
Assets.images.trendings.trending3.path,
Assets.images.trendings.trending4.path,
];
}
17 changes: 17 additions & 0 deletions lib/home/home_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'cubit/home_cubit.dart';
import 'home_view.dart';

class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => HomeCubit(),
child: const HomeView(),
);
}
}
Loading