LinkedIn Experience with Flutter: LinkedIn is a powerful professional networking platform, and creating a clone of its homepage using Flutter can be an exciting project. In this blog post, we’ll guide you through the process of building a visually appealing and functional LinkedIn homepage clone using Flutter.
1. Setting Up Your Flutter Project: Begin by creating a new Flutter project
2. Designing the User Interface: The LinkedIn homepage features a clean and user-friendly design. Utilize Flutter’s widget system to create a similar layout. Use ListView
, Column
, and Row
widgets to structure your UI components, such as the profile header, news feed, and side navigation bar.
3. Implementing the Profile Header: LinkedIn’s profile header typically includes the user’s profile picture, name, headline, and a navigation bar. Use Flutter’s Container
, Image
, and Text
widgets to achieve a similar layout. You can also add interactivity to the navigation bar using GestureDetector or InkWell.
4. Creating the News Feed:
The heart of any social media platform is its news feed. Implement a dynamic feed using Flutter’s ListView.builder and Card widgets. Populate the feed with sample posts, each containing a profile picture, user name, post content, and engagement metrics.
5. Integrating User Interactivity: Make your LinkedIn clone interactive by allowing users to like, comment, and share posts. Utilize Flutter’s InkWell or GestureDetector for tap gestures. Implement functionalities such as updating like counts and displaying comments dynamically.
6. Building the Side Navigation Bar: LinkedIn’s side navigation bar includes sections like “Home,” “My Network,” “Jobs,” and more. Use Flutter’s Drawer widget to create a responsive side navigation bar. Add icons and text to represent each section, and implement navigation between different pages.
7. Styling and Theming: Ensure your LinkedIn clone looks polished and professional by applying consistent styling and theming. Flutter allows you to define global themes for your app, making it easy to maintain a cohesive design throughout.
8. Handling State Management: Manage the state of your app efficiently using Flutter’s state management solutions, such as Provider or Riverpod. This is crucial for updating UI elements dynamically and ensuring a smooth user experience.
9. Implementing Authentication: Integrate authentication to simulate user logins. You can use Firebase Authentication or any other authentication solution compatible with Flutter. Secure access to certain features and pages based on the user’s authentication status.
10. Testing and Debugging: Thoroughly test your LinkedIn clone on different devices and screen sizes. Use Flutter’s debugging tools to identify and fix any issues. Consider running automated tests to ensure the stability of your application.
Create Homepage in Flutter:
Responsive Design for a Dynamic Experience
The foundation of this LinkedIn-inspired app lies in its responsiveness. The use of ResponsiveBuilder
ensures a fluid transition across various screen sizes. Whether viewed on a desktop or a mobile device, the app adapts dynamically, providing an optimal user experience.
Navigating with Finesse
The bottom navigation bar is a pivotal element in guiding users through different sections of the app. Icons representing the home feed, network, post creation, notifications, and job listings make navigation intuitive. Tapping on an icon updates the content dynamically, creating a seamless and engaging navigation experience.
Scrolling Magic for a Clean UI
To enhance the user interface’s responsiveness, the code incorporates a scroll controller. As users scroll, the app intelligently hides or reveals the app bar, contributing to a clean and unobtrusive design. This subtle animation adds an extra layer of sophistication to the overall user experience.
import 'package:job/linkedin/model/company.dart';
class FakeRepository {
static final List<UserPostModel> postList = [
UserPostModel(
name: "Shehroz Jamal",
profileUrl: "assets/profileImage4.jpeg",
headline: "HR Executive ",
tags:
"#positivity #motivation #learning #progress #development #networking #business #jobhunters #jobseekers #connections #networking #linkedin #nevergiveup #staypositive #staystrong #positiveattitude",
description:
"Stay Strong!\n\nKeep Your Head Up!\n\nRejection means a better opportunity awaits you elsewhere.\n\nYour thoughts?",
isVideoPost: false,
comments: "100",
video: "",
isOnline: false,
image: "assets/postImage4.jpeg",
likes: "800"),
UserPostModel(
name: "Arslan nasir",
profileUrl: "assets/profileImage6.jpeg",
headline: "MEAN Stack Developer | Freelancer",
tags: "#independenceday2020",
description:
"Without the sweat, toil and sacrifices of our heroes, we wouldn’t have this bright day that we celebrate today. Happy Independence Day.",
isVideoPost: false,
comments: "1k",
video: "",
isOnline: true,
image: "assets/postImage6.jpeg",
likes: "20k"),
UserPostModel(
name: "Mohsin Ali",
profileUrl: "assets/profileImage3.jpeg",
headline: "Logo Designer | Freelancer |",
tags: "#datascience #machinelearning #programming #python #joke",
description: "Google, Stack Overflow are your saviors :)",
isVideoPost: false,
comments: "100",
video: "",
isOnline: true,
image: "assets/postImage3.jpeg",
likes: "230"),
UserPostModel(
name: "Sahar Salimi",
profileUrl: "assets/profileImage2.jpeg",
headline:
"LOGO DESIGN 🔹3D LOGO ANIMATION 🔹 DRAW CARTOON 🔹 BUSINESS CARD 🔹 PENCIL SKETCH 🔹 FLYER DESIGN 🔹 BROCHURE DESIGN 🔹",
tags: "#Respect #SadioMane #PayBack #Love",
description: "Rate my art work",
isVideoPost: false,
comments: "500",
video: "",
isOnline: false,
image: "assets/postImage2.jpeg",
likes: "10k"),
UserPostModel(
name: "Ali Raza",
profileUrl: "assets/profileImage1.jpeg",
headline: "Creative Content Writer | Content Specialist | Storyteller ",
tags: "#Respect #SadioMane #PayBack #Love",
description:
"The world famous football player Sadio Mane of Senegal (West Africa), whose income in Indian rupees is around Rs. 1 crore 40 lacs per week, was seen in many places with a broken mobile phone. In an interview when asked about it, he said, I'll get it fixed. When asked, Why you are not buying a new one? He said, I could buy thousands of it, 10s Ferraris, couple of Jet Planes, Diamond watches that I can buy, but why do I need all of these? I saw poverty, so I couldn't learn, I built schools so that people could learn, I didn't have shoes, I played without shoes, I didn't have good clothes, I didn't have food. I have so much today that I want to share it with my people instead of showing off.Huge respect for him! We all must spend atleast some portion of our excess incomes in people who are deserving and can't even buy necessities.",
isVideoPost: false,
comments: "400",
video: "videos/flutterIntro.mp4",
isOnline: false,
image: "assets/postImage1.jpeg",
likes: "1.1k"),
UserPostModel(
name: "Flutter World",
profileUrl: "assets/flutter_logo.png",
headline: "Flutter Open Projects | Flutter Drat world",
tags:
"#FlutterOpenProject, #FlutterMagicWorld, #Mobile&WebOpenApps, #Flutter+Dart❤️",
description:
"Flutter is an open-source mobile application development framework created by Google. It is used to develop applications for Android and iOS, as well as being the primary method of creating applications for Google Fuchsia.",
isVideoPost: false,
comments: "20k",
video: "videos/flutterIntro.mp4",
isOnline: true,
image: "assets/flutter_post.jpeg",
likes: "101k"),
UserPostModel(
name: "Amazon Web Service (AWS)",
profileUrl: "assets/profileImage5.png",
headline: "4,594,488 followers",
tags: "",
description:
"Better protect your S3 data with expanded Amazon GuardDuty threat detection to monitor for suspicious data access & other threats:",
isVideoPost: false,
comments: "400",
video: "",
isOnline: false,
image: "assets/postImage5.jpeg",
likes: "1k"),
];
static final userProfile = UserModel(
headline:
"Android & IOS Mobile Application flutter developer | Freelancer",
profileUrl: "assets/profile.jpg",
name: "Amir Khan",
connections: "1,837",
viewProfile: "300");
static final List<GroupModel> recentData = [
GroupModel("Recent", [
GroupModel("World Wide Flutter"),
GroupModel("Flutter Developer Community"),
GroupModel("Flutter Open Projects"),
GroupModel("Firebase flutter"),
]),
GroupModel("Groups", [
GroupModel("World Wide Flutter"),
GroupModel("Flutter Developer Community"),
GroupModel("Flutter Open Projects"),
GroupModel("Firebase flutter"),
]),
];
static final List<CompanyModel> companyListData = [
CompanyModel(
name: "Pakistan Jobs",
description: "We help to Build Your Career",
profileUrl: "",
),
CompanyModel(
name: "Upwork",
description: "company * internet ",
profileUrl: "assets/icons/upwork.png",
),
CompanyModel(
name: "Flutter + Dart",
description: "Open projects Contribution",
profileUrl: "assets/icons/flutter_logo.jpeg",
),
];
}
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:job/linkedin/customapp.dart';
import 'package:job/linkedin/navi.dart';
import 'package:job/linkedin/model/res.dart';
import 'package:job/linkedin/row.dart';
import 'package:job/linkedin/theme.dart';
import 'package:responsive_builder/responsive_builder.dart';
class MobileScreen extends StatefulWidget {
@override
_MobileScreenState createState() => _MobileScreenState();
}
class _MobileScreenState extends State<MobileScreen> {
int _currentNavIndex = 0;
final _post = FakeRepository.postList;
bool _showAppNavBar = true;
late ScrollController _scrollController;
bool _isScrollDown = false;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_initialScroll();
}
void _initialScroll() async {
_scrollController.addListener(() {
if (_scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
if (!_isScrollDown) {
_isScrollDown = true;
_hideAppNavBar();
}
}
if (_scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
if (_isScrollDown) {
_isScrollDown = false;
_showAppNvBar();
setState(() {});
}
}
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ResponsiveBuilder(
builder: (BuildContext context, SizingInformation sizingInformation) {
return Scaffold(
bottomNavigationBar: _showAppNavBar
? Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
height: sizingInformation.screenSize.height * 0.07,
decoration: const BoxDecoration(
color: Colors.white54,
border: Border(
top: BorderSide(color: Colors.black26, width: 0.80))),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
setState(() {
_currentNavIndex = 0;
});
},
child: SingleNavBarButton(
name: "home",
icon: FontAwesomeIcons.home,
selectedButton:
_currentNavIndex == 0 ? true : false,
)),
InkWell(
onTap: () {
setState(() {
_currentNavIndex = 1;
});
},
child: SingleNavBarButton(
name: "My Network",
icon: FontAwesomeIcons.userFriends,
selectedButton: _currentNavIndex == 1 ? true : false,
),
),
InkWell(
onTap: () {
setState(() {
_currentNavIndex = 2;
});
},
child: SingleNavBarButton(
name: "Post",
icon: FontAwesomeIcons.plusCircle,
selectedButton: _currentNavIndex == 2 ? true : false,
),
),
InkWell(
onTap: () {
setState(() {
_currentNavIndex = 3;
});
},
child: SingleNavBarButton(
name: "Notification",
icon: FontAwesomeIcons.solidBell,
selectedButton: _currentNavIndex == 3 ? true : false,
),
),
InkWell(
onTap: () {
setState(() {
_currentNavIndex = 4;
});
},
child: SingleNavBarButton(
name: "Jobs",
icon: FontAwesomeIcons.briefcase,
selectedButton: _currentNavIndex == 4 ? true : false,
),
),
],
),
)
: Container(
height: 0.0,
width: 0.0,
),
body: Container(
color: Colors.black12,
child: Column(
children: [
_showAppNavBar
? CustomAppBar(
sizingInformation: sizingInformation,
)
: Container(
height: 0.0,
width: 0.0,
),
_listPostWidget(sizingInformation),
],
),
),
);
},
);
}
Widget _listPostWidget(SizingInformation sizingInformation) {
return Expanded(
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView.builder(
controller: _scrollController,
itemCount: _post.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 15),
margin: const EdgeInsets.only(bottom: 0.0, top: 8),
decoration: const BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(color: Colors.black54, width: 0.50),
bottom: BorderSide(color: Colors.black54, width: 0.50))),
child: Column(
children: [
Row(
children: [
Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(40))),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(40)),
child: Image.asset(
_post[index].profileUrl,
fit: BoxFit.cover,
)),
),
const SizedBox(
width: 4,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_post[index].name,
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
Container(
width: sizingInformation.screenSize.width / 1.24,
child: Text(
_post[index].headline,
style: const TextStyle(
fontSize: 12, color: Colors.black54),
overflow: TextOverflow.ellipsis,
),
),
],
)
],
),
Text(
_post[index].description,
style: const TextStyle(fontSize: 14),
),
Text(
_post[index].tags,
style: TextStyle(color: blueColor),
),
const SizedBox(
height: 10,
),
Container(
width: sizingInformation.screenSize.width,
child: Image.asset(
_post[index].image,
fit: BoxFit.contain,
),
),
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
child: Row(
children: [
Container(
width: 25,
height: 25,
child: Image.asset('assets/icons/like_icon.png')),
Container(
width: 25,
height: 25,
child: Image.asset(
'assets/icons/celebrate_icon.png')),
if (index == 0 || index == 4 || index == 6)
Container(
width: 25,
height: 25,
child:
Image.asset('assets/icons/love_icon.png')),
const SizedBox(
width: 5,
),
Text(
_post[index].likes,
style: const TextStyle(fontSize: 14),
)
],
),
),
Container(
child: Row(
children: [
Text(_post[index].comments),
const Text(" comments")
],
),
)
],
),
const Divider(
thickness: 0.50,
color: Colors.black26,
),
_rowButton(),
],
),
);
},
),
));
}
void _hideAppNavBar() {
setState(() {
_showAppNavBar = false;
});
}
void _showAppNvBar() {
setState(() {
_showAppNavBar = true;
});
}
Widget _rowButton() {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {},
child: rowSingleButton(
color: Colors.black,
name: "Like",
iconImage: "assets/icons/like_icon_white.png",
isHover: false),
),
InkWell(
onTap: () {},
child: rowSingleButton(
color: Colors.black,
name: "Comment",
iconImage: "assets/icons/comment_icon.png",
isHover: false),
),
InkWell(
onTap: () {},
child: rowSingleButton(
color: Colors.black,
name: "Share",
iconImage: "assets/icons/share_icon.png",
isHover: false),
),
],
),
);
}
}
For more: To know about Facebook Homepage Clone in Flutter.
Leave a Reply