Flutter Social Forum Application
Published March 27, 2020This Example will show the Prototype for Forum Application with Flutter.
In this Example hanlde the state by ScopedModel
Let's check code:
ScopedModel class
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
class MyScopeModel extends Model{
int selectedTyep=1;
String selectedCategory="";
get selectedTypes=>selectedTyep;
get selectedCat=>selectedCategory;
void setSelected(int value)
{
selectedTyep=value;
notifyListeners();
}
void setCategory(String value)
{
selectedCategory=value;
notifyListeners();
}
}
|
Login page
import 'package:flutter/material.dart';
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.green,
centerTitle: true,
elevation: 0.0,
title: new Text(
"Welcome",
textScaleFactor: 1.3,
),
),
body: new Container(
color: Colors.amberAccent,
padding: const EdgeInsets.all(30.0),
child: ListView(
children: <Widget>[
new Container(
margin: const EdgeInsets.all(20.0),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(new Radius.circular(30.0)),
),
height: 100.0,
alignment: Alignment.center,
child: new Icon(
Icons.beach_access,
size: 100.0,
color: Colors.green,
),
),
new TextField(
controller: new TextEditingController(),
decoration: new InputDecoration(
hintText: 'Username',
filled: true,
fillColor: Colors.white,
),
),
SizedBox(height: 10,),
new TextField(
controller: new TextEditingController(),
obscureText: true,
decoration: new InputDecoration(
hintText: 'Password',
filled: true,
fillColor: Colors.white,
),
),
new Container(
// margin: const EdgeInsets.only( bottom: 150.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: new RaisedButton(
child: new Text("Login",style: TextStyle(color: Colors.white),),
onPressed: onPressed,
color: Colors.pink,
),
),
new RaisedButton(
child: new Text("Forgot Password"),
onPressed: onPressed,
),
],
),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Container(
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: new RaisedButton(
child: new Text("Register"),
onPressed: onPressed,
color: Colors.yellow,
),
),
new RaisedButton(
child: new Text("Continue as Guest"),
onPressed: () {Navigator.pushNamed(context, '/forum');},
),
],
),
)
],
)
),
);
}
void onPressed() {}
}
|
To handle the Forum category created few model classes.
Forum List page
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:practice1/assets/colors.dart';
import 'package:scoped_model/scoped_model.dart';
import 'constants/icons.dart';
import 'model/category.dart';
import 'model/listdata.dart';
import 'model/scopemodel.dart';
class ForumPage extends StatefulWidget {
ForumPage({Key key, this.title}) : super(key: key);
final String title;
@override
_ForumPageState createState() => new _ForumPageState();
}
class _ForumPageState extends State<ForumPage> {
List<CategoryIcon>listCategory;
@override
void initState() {
super.initState();
listCategory=new List();
print("reading");
loadCategory();
}
MyScopeModel model;
Container topCategoyIcons(model) {
return new Container(
alignment: Alignment.center,
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [
AppColorsTheme.myTheme.titleBarGradientStartColor,
AppColorsTheme.myTheme.titleBarGradientEndColor
],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(0.0, 1.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)),
child: new Container(
margin: EdgeInsets.only(top: 20,left: 10,right: 10),
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 10),
decoration: new BoxDecoration(
color: AppColorsTheme.myTheme.secondaryGradientColor,
// border: new Border.all(color: Colors.black, width: 1.0),
borderRadius: new BorderRadius.only(
topLeft: new Radius.circular(30.0),
topRight: new Radius.circular(30.0),
),
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
listCategory[0],
listCategory[1],
listCategory[2],
listCategory[3],
],
),
),
);
}
Container categoryMetric(model) {
return new Container(
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 15.0),
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [
AppColorsTheme.myTheme.secondaryGradientColor,
AppColorsTheme.myTheme.secondaryGradientColor
],
begin: const FractionalOffset(0.0, 0.5),
end: const FractionalOffset(0.0, 1.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
),
// border: new Border.all(color: Colors.black, width: 1.0),
borderRadius: new BorderRadius.only(
bottomLeft: new Radius.circular(30.0),
bottomRight: new Radius.circular(30.0),
),
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
listCategory[4],
listCategory[5],
listCategory[6],
listCategory[7],
],
),
);
}
listView(MyScopeModel model) {return
new ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) =>
new EntryItem(myForums[model.selectedTyep][index]),
itemCount: myForums[model.selectedTyep].length,
shrinkWrap: true,
);}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.green,
centerTitle: false,
elevation: 0.0,
title: new Text(
widget.title,
textScaleFactor: 1.3,
),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
onPressed: _onSearchPressed,
),
],
),
body: new Container(
child:ScopedModelDescendant<MyScopeModel>(
builder: (context,child,model){
this.model=model;
return SingleChildScrollView(
child: Column(
children: <Widget>[ (listCategory.length>4)?topCategoyIcons(model):Container(), Divider(height: 1,color: Colors.white,), (listCategory.length>7)?categoryMetric(model):Container(), listView(model)],
),
);
},
),
),
);
}
void _onSearchPressed() {
Navigator.pop(context);
}
loadCategory() {
DefaultAssetBundle.of(context).loadString("assets/category.json")
.then((s) {
List list=json.decode(s) as List;
print(list);
setState(() { listCategory= list.map((e) => fromJson(e)).toList();});/*{
setState(() {
print("reading");
listCategory.add();
print("${listCategory.length}");
})
});*/
})
.catchError((error) {
print(error);
});
}
}
|
Forum Details Page
import 'package:flutter/material.dart';
import 'package:practice1/assets/colors.dart';
import 'package:scoped_model/scoped_model.dart';
import 'model/scopemodel.dart';
class ForumDetailPage extends StatefulWidget {
ForumDetailPage();
@override
_ForumDetailPageState createState() => new _ForumDetailPageState();
}
var ForumPostArr = [
new ForumPostEntry("User1", "2 Days ago", 0 , 0 , "Hello,\n\nDummy Text about flutter post "),
new ForumPostEntry("User2", "23 Hours ago", 1 , 0 , "he basic component in a Flutter program is a "widget", which can in turn consist of other widgets. A widget describes the logic, interaction, and design of a UI element with an implementation similar to React. Unlike other cross-platform toolkits such as React Native and Xamarin which draw widgets using native platform components, Flutter renders widgets itself on a per-pixel basis.
There are two fundamental types of widgets: stateless and stateful. Stateless widgets only update if their inputs change, making them very efficient, while stateful widgets can call the setState() method to update an internal state and redraw.[27]
Although widgets are the primary method of constructing Flutter applications, they can also be bypassed in favor of directly drawing on a canvas. This feature has been occasionally used to implement game engines in Flutter
."),
new ForumPostEntry("User3", "2 Days ago", 5 , 0 , "Dummy Text about flutter post ."),
new ForumPostEntry("User4", "2 Days ago", 0 , 0 , "Dummy Text about flutter post ."),
];
class _ForumDetailPageState extends State<ForumDetailPage> {
int forumtype;
String category;
@override
Widget build(BuildContext context) {
var questionSection = new Padding(
padding: const EdgeInsets.all(8.0),
child: new Column(
children: <Widget>[
new Text(
"How do I become a expert in programming as well as design ??",
textScaleFactor: 1.5,
style: new TextStyle(fontWeight: FontWeight.bold),
),
new Padding(
padding: const EdgeInsets.all(12.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new IconWithText(Icons.laptop_mac, "Technology"),
new IconWithText(
Icons.check_circle,
"Answered",
iconColor: Colors.green,
),
new IconWithText(Icons.remove_red_eye, "54")
],
),
),
new Divider()
],
),
);
var responses = new Container(
padding: const EdgeInsets.all(8.0),
child: new ListView.builder(
itemBuilder: (BuildContext context, int index) => new ForumPost(ForumPostArr[index]),
itemCount: ForumPostArr.length,
)
);
return ScopedModelDescendant<MyScopeModel>(builder: (context,child, model){
return Scaffold(
appBar: new AppBar(
backgroundColor: Colors.green,
title: new Text(model.selectedCat,style: TextStyle(color: Colors.white),),
),
body: new Column(
children: <Widget>[
questionSection,
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: responses,
))
],
),
);
});
}
}
class ForumPostEntry{
final String username;
final String hours;
final int likes;
final int dislikes;
final String text;
ForumPostEntry(this.username, this.hours, this.likes, this.dislikes, this.text);
}
class ForumPost extends StatelessWidget {
final ForumPostEntry entry;
ForumPost(this.entry);
@override
Widget build(BuildContext context) {
return new Container(
margin: const EdgeInsets.all(5.0),
decoration: new BoxDecoration(
color: Colors.green,
borderRadius: const BorderRadius.all(const Radius.circular(20.0)),
),
child: new Column(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
color: Colors.green,
borderRadius: const BorderRadius.only(
topLeft: const Radius.circular(20.0),
topRight: const Radius.circular(20.0)),
),
child: new Row(
children: <Widget>[
new Icon(
Icons.person,
color: Colors.white,
size: 50.0,
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(
entry.username
,style: TextStyle(color: Colors.white),
),
new Text(
entry.hours,style: TextStyle(color: Colors.white),
),
],
),
),
new Row(
children: <Widget>[
new Padding(
padding: const EdgeInsets.all(2.0),
child: new Icon(Icons.thumb_up,color: Colors.amber,),
),
new Padding(
padding: const EdgeInsets.all(2.0),
child: new Text(entry.likes.toString(),style: TextStyle(color: Colors.white),),
),
new Padding(
padding: const EdgeInsets.all(2.0),
child: new Icon(Icons.thumb_down,color: Colors.amber,),
),
new Padding(
padding: const EdgeInsets.only(right: 8.0, left: 2.0),
child: new Text(entry.dislikes.toString(),style: TextStyle(color: Colors.white),),
),
],
)
],
),
),
new Container(
margin: const EdgeInsets.only(left: 2.0,right: 2.0,bottom: 2.0),
padding: const EdgeInsets.all(8.0),
decoration: new BoxDecoration(
color: Colors.grey[200],
borderRadius: const BorderRadius.only(bottomLeft :const Radius.circular(20.0),bottomRight :const Radius.circular(20.0))
),
child: new Text(entry.text),
),
],
),
);
}
}
class IconWithText extends StatelessWidget {
final IconData iconData;
final String text;
final Color iconColor;
IconWithText(this.iconData, this.text, {this.iconColor});
@override
Widget build(BuildContext context) {
return new Container(
child: new Row(
children: <Widget>[
new Icon(
this.iconData,
color: this.iconColor,
),
new Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text(this.text),
),
],
),
);
}
}
|
Donwload complete code at github repo
Article Contributed By :
|
|
|
|
654 Views |