Article

Design Trends 2020: Neumorphism Using Flutter

Last updated 
Feb 8, 2020
 min read

It is already 2020, and Neumorphism is trending, bringing a new dimension to our digital experiences. Neumorphism is all about making on-screen elements look lifelike by creating a sort of soft 3D appearance. It’s as if the buttons and icons on your phone or computer could just be taken right out.

Neumorphism goes beyond being a fad; it helps make our digital universe more hospitable and intuitive. When using subtle shadows and highlights, virtual objects can appear recognizable and easy to handle.

In this blog post, we shall guide you on how to create this stunning effect with Flutter. You don’t have to worry about being a tech expert because we will take you through the process step-by-step. So let’s start having fun with Neumorphism!

What is Neumorphism?

Also called “Soft UI,” Neumorphism blends skeuomorphism and minimalism into one design style. It means designing user interfaces (UIs) that feel soft and almost three-dimensional. Just think about buttons, switches, and cards which seem placed within the background that makes them tangible to the touch.

Neumorphism draws inspiration from the real world and the digital sphere. Unlike traditional skeuomorphism that aims to recreate reality in a digital space, neumorphism deviates from this approach. The emphasis is on subtle contrasts, solid colors, and clever manipulation of shadows and lights. The result is a gentle, inviting feel that is both familiar and new.

Implementing Neumorphism with Flutter

Now that we are conversant with the basics, let us now see how you can apply neumorphism in your Flutter framework. We will walk you through creating soft interfaces that are visually appealing that users will love, whether you are an experienced developer or you just want to know what it is all about.

Note: It is assumed that you have Flutter set up. This tutorial is primarily for Mobile Applications, although the implementation can also be applied to web applications.

Creating the Convex Widget

First We will Create Convex Widget

1Widget convex(String txt) {
2    return Container(
3      width: MediaQuery.of(context).size.width / 4,
4      height: MediaQuery.of(context).size.height / 8,
5      child: Center(child: Icon(Icons.favorite_border)),
6      decoration: BoxDecoration(
7          color: Color(0xFFf8fbf8),
8          borderRadius: BorderRadius.all(Radius.circular(30)),
9          boxShadow: [
10            BoxShadow(
11                color: Colors.grey[200],
12                offset: Offset(10.0, 10.0),
13                blurRadius: 10.0,
14                spreadRadius: 2.0),
15            BoxShadow(
16                color: Colors.white,
17                offset: Offset(-10.0, -10.0),
18                blurRadius: 10.0,
19                spreadRadius: 2.0)
20          ]),
21    );
22}

After Creating Convex its time to create Concave Widget

1static List<Color> _fill = <Color>[
2    Colors.grey[200],
3    Color(0xFFf8fbf8),
4    Colors.white
5];
6
7Widget concav(String txt, Color _clr) {
8    return Container(
9      width: MediaQuery.of(context).size.width / 4,
10      height: MediaQuery.of(context).size.height / 8,
11      child: Center(
12        child: Icon(
13          Icons.favorite,
14          color: Colors.red,
15        ),
16      ),
17      decoration: BoxDecoration(
18        color: _clr,
19        borderRadius: BorderRadius.all(Radius.circular(30)),
20        gradient: LinearGradient(
21          begin: Alignment.topLeft,
22          end: Alignment.bottomRight,
23          colors: _fill,
24          stops: [0.1, 0.5, 0.9],
25        ),
26      ),
27    );
28}

Similarly, add Icon of thumbs up( ) in new concave and convex Widget,

Link to the Thumbsup Concave and Convex.

Wrapping It Up with the MainScreen

Now Let’s wrap it up with the MainScreen

1class HeartScreen extends StatefulWidget {
2  @override
3  _HeartScreenState createState() => _HeartScreenState()
4}
5
6class _HeartScreenState extends State<HeartScreen> {
7  bool isPressed = false;
8  static List<Color> _fill = <Color>[
9    Colors.grey[200],
10    Color(0xFFf8fbf8),
11    Colors.white
12  ];
13
14  @override
15  Widget build(BuildContext context) {
16    return SafeArea(
17      child: Scaffold(
18        backgroundColor: Color(0xFFf8fbf8),
19        body: Center(
20          child: Row(
21            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
22            children: <Widget>[
23              GestureDetector(
24                onTap: () {
25                  _change();
26                },
27                child: AnimatedContainer(
28                  width: MediaQuery.of(context).size.width / 4,
29                  height: MediaQuery.of(context).size.height / 8,
30                  duration: Duration(seconds: 2),
31                  child: isPressed
32                      ? concav("Synth", Color(0xFF649166))
33                      : convex("Beat"),
34                ),
35              ),
36              SizedBox(
37                width: 30.0,
38              ),
39              GestureDetector(
40                onTap: () {
41                  _change();
42                },
43                child: AnimatedContainer(
44                  width: MediaQuery.of(context).size.width / 4,
45                  height: MediaQuery.of(context).size.height / 8,
46                  duration: Duration(seconds: 2),
47                  child: isPressed
48                      ? convexWithThumb("Synth", Color(0xFF649166))
49                      : concaveWithThumb("Beat"),
50                ),
51              ),
52            ],
53          ),
54        ),
55      ),
56    );
57  }
58
59  void _change() {
60    if (this.isPressed == true) {
61      setState(() {
62        isPressed = false;
63      });
64    } else if (this.isPressed == false) {
65      setState(() {
66        isPressed = true;
67      });
68    }
69  }
70
71  Widget convex(String txt) {
72    return Container(
73      width: MediaQuery.of(context).size.width / 4,
74      height: MediaQuery.of(context).size.height / 8,
75      child: Center(child: Icon(Icons.favorite_border)),
76      decoration: BoxDecoration(
77          color: Color(0xFFf8fbf8),
78          borderRadius: BorderRadius.all(Radius.circular(30)),
79          boxShadow: [
80            BoxShadow(
81                color: Colors.grey[200],
82                offset: Offset(10.0, 10.0),
83                blurRadius: 10.0,
84                spreadRadius: 2.0),
85            BoxShadow(
86                color: Colors.white,
87                offset: Offset(-10.0, -10.0),
88                blurRadius: 10.0,
89                spreadRadius: 2.0)
90          ]),
91    );
92  }
93
94  Widget concav(String txt, Color _clr) {
95    return Container(
96      width: MediaQuery.of(context).size.width / 4,
97      height: MediaQuery.of(context).size.height / 8,
98      child: Center(
99        child: Icon(
100          Icons.favorite,
101          color: Colors.red,
102        ),
103      ),
104      decoration: BoxDecoration(
105        color: _clr,
106        //  border: Border.fromBorderSide(BorderSide(style: BorderStyle.solid,width: 3.0,color: Color(0xFFF8F1F1))),
107        borderRadius: BorderRadius.all(Radius.circular(30)),
108        gradient: LinearGradient(
109          begin: Alignment.topLeft,
110          end: Alignment.bottomRight,
111          colors: _fill,
112          stops: [0.1, 0.5, 0.9],
113        ),
114      ),
115    );
116  }
117
118  Widget concaveWithThumb(String txt) {
119    return Container(
120      width: MediaQuery.of(context).size.width / 4,
121      height: MediaQuery.of(context).size.height / 8,
122      child: Center(child: Icon(Icons.thumb_up)),
123      decoration: BoxDecoration(
124          color: Color(0xFFf8fbf8),
125          borderRadius: BorderRadius.all(Radius.circular(30)),
126          boxShadow: [
127            BoxShadow(
128                color: Colors.grey[200],
129                offset: Offset(10.0, 10.0),
130                blurRadius: 10.0,
131                spreadRadius: 2.0),
132            BoxShadow(
133                color: Colors.white,
134                offset: Offset(-10.0, -10.0),
135                blurRadius: 10.0,
136                spreadRadius: 2.0)
137          ]),
138    );
139  }
140
141  Widget convexWithThumb(String txt, Color _clr) {
142    return Container(
143      width: MediaQuery.of(context).size.width / 4,
144      height: MediaQuery.of(context).size.height / 8,
145      child: Center(
146        child: Icon(
147          Icons.thumb_up,
148          color: Colors.blueAccent,
149        ),
150      ),
151      decoration: BoxDecoration(
152        color: _clr,
153        //  border: Border.fromBorderSide(BorderSide(style: BorderStyle.solid,width: 3.0,color: Color(0xFFF8F1F1))),
154        borderRadius: BorderRadius.all(Radius.circular(30)),
155        gradient: LinearGradient(
156          begin: Alignment.topLeft,
157          end: Alignment.bottomRight,
158          colors: _fill,
159          stops: [0.1, 0.5, 0.9],
160        ),
161      ),
162    );
163  }
164}

We have Placed AnimatedContainer For Button Animation.

1AnimatedContainer(
2   width: MediaQuery.of(context).size.width / 4,
3   height: MediaQuery.of(context).size.height / 8,
4   duration: Duration(seconds: 2),
5       child: isPressed
6            ? convexWithThumb("Synth", Color(0xFF649166))
7            : concaveWithThumb("Beat"),
8),

Hurrah Neumorphism Effect Worked ….

Now you all can explore more on this on your own.

Remote Controller Example

Remote Controller

Link to the Source Code: NeumorphismFlutter

Conclusion

Neumorphism is a mesmerizing design trend that bridges the gap between the digital and physical worlds. Its soft, inviting aesthetic has made its way into mobile applications, websites, and user interfaces, creating delightful experiences for users.

Remember, Neumorphism isn’t just about aesthetics; it’s about enhancing usability. By subtly blending shadows, gradients, and solid colors, designers can make buttons, cards, and icons feel tangible—as if they’re waiting to be touched.

So, if you are a curious designer or a well-seasoned developer, then consider incorporating some elements of Neumorphism into your next project.

At Aubergine Solutions, we are experts in creating outstanding digital experiences and use a perfect blend of creativity and user-centric design to offer distinguished software solutions. Whether you need mobile applications, responsive websites, or custom software, we will do it all. Contact us today to learn more about our design and software development services.

Authors

Vishwesh Soni

Software Engineer
I’m a software engineer with experience in developing scalable solutions. I focus on building efficient, scalable systems and love solving challenging technical problems. Constantly learning and exploring new tools, I’m committed to improving both my skills and the software I create.

Tags

No items found.

Have a project in mind?

Read