How to create dash rounded circle image view in Flutter - flutter

I want to create this type of design for my profile page but I really don't know how to create the dashed circle in a flutter.

Create a rounded image or rounded container and then use this plugin dotted_border: ^2.0.0+2
import 'package:flutter/material.dart';
import 'package:dotted_border/dotted_border.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Dotted Border'),
),
body: SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 8,
children: <Widget>[
rectBorderWidget,
roundedRectBorderWidget,
customBorder,
roundStrokeCap,
solidBorder,
fullWidthPath,
],
),
),
),
),
),
);
}
/// Draw a border with rectangular border
Widget get rectBorderWidget {
return DottedBorder(
dashPattern: [8, 4],
strokeWidth: 2,
child: Container(
height: 200,
width: 120,
color: Colors.red,
),
);
}
/// Draw a border with a rounded rectangular border
Widget get roundedRectBorderWidget {
return DottedBorder(
borderType: BorderType.RRect,
radius: Radius.circular(12),
padding: EdgeInsets.all(6),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Container(
height: 200,
width: 120,
color: Colors.amber,
),
),
);
}
/// Draw a border with custom path border
Widget get customBorder {
Path customPath = Path()
..moveTo(20, 20)
..lineTo(50, 100)
..lineTo(20, 200)
..lineTo(100, 100)
..lineTo(20, 20);
return DottedBorder(
customPath: (_) => customPath,
color: Colors.indigo,
dashPattern: [8, 4],
strokeWidth: 2,
child: Container(
height: 220,
width: 120,
color: Colors.green.withAlpha(20),
),
);
}
/// Set border stroke cap
Widget get roundStrokeCap {
return DottedBorder(
dashPattern: [8, 4],
strokeWidth: 2,
strokeCap: StrokeCap.round,
borderType: BorderType.RRect,
radius: Radius.circular(5),
child: Container(
height: 200,
width: 120,
color: Colors.red,
),
);
}
Widget get solidBorder {
return DottedBorder(
dashPattern: [4, 3],
strokeWidth: 2,
strokeCap: StrokeCap.round,
child: Container(
color: Colors.green,
height: 200,
width: 120,
),
);
}
Widget get fullWidthPath {
return DottedBorder(
customPath: (size) {
return Path()
..moveTo(0, 20)
..lineTo(size.width, 20);
},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(),
),
);
}
}
Or try this
dashed_circle: ^0.0.2
import 'package:flutter/material.dart';
import 'package:dashed_circle/dashed_circle.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/Bill_Gates_Buys_Skype_%285707954468%29.jpg/2560px-Bill_Gates_Buys_Skype_%285707954468%29.jpg';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dashed Circle Example',
theme: ThemeData(),
home: Scaffold(
body: Center(
child: DashedCircle(
child: Padding(padding: EdgeInsets.all(6.0),
child: CircleAvatar(
radius: 70.0,
backgroundImage: NetworkImage(url),
),
),
color: Colors.deepOrangeAccent,
)
),
),
);
}
}

Related

Can't solve this error "The argument type 'Animation<dynamic>?' can't be assigned to the parameter type 'Animation<double>'."

I'm following this speed code tutorial(https://www.youtube.com/watch?v=KO_PYJKHglo) and I'm facing some problems during somewhere on 6:04.
I did some typing ! and ? for any null safety related problems but nothing had changed.
import 'package:flutter/material.dart';
import 'package:secondlife_mobile/clipper.dart';
import 'package:secondlife_mobile/wave_base_painter.dart';
import 'package:secondlife_mobile/wave_color_painter.dart';
void main() {
runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: PlayerApp(),
),
);
}
class PlayerApp extends StatefulWidget {
const PlayerApp({super.key});
#override
State<PlayerApp> createState() => _PlayerAppState();
}
class _PlayerAppState extends State<PlayerApp> with TickerProviderStateMixin {
AnimationController? _controller;
Animation? _waveAnim;
Animation? _waveConstAmpAnim;
#override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: const Duration(seconds: 20))
..addListener(() => setState(() {}));
_waveAnim = Tween<double>(begin: 1, end: 1).animate(_controller);
_waveConstAmpAnim = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(curve: Curves.easeInSine, parent: _controller));
_controller!.forward(); //null safe 6:32
}
#override
Widget build(BuildContext context) {
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
return Scaffold(
body: Stack(
children: <Widget>[
Positioned(
height: height,
width: width,
child: Material(
elevation: 16,
color: const Color(0xFFd6dde5), //Background Color
borderRadius: BorderRadius.circular(20),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0,
),
child: Column(
children: <Widget>[
const SizedBox(
height: 90,
),
const Text(
'Music title',
),
const SizedBox(
height: 15,
),
const Text(
'Music artist',
),
const SizedBox(
height: 75,
),
buildRecordPlayer(),
const SizedBox(
height: 60,
),
Row(
children: <Widget>[
const Text('time'),
const SizedBox(
width: 8,
),
buildWave(width),
const SizedBox(
width: 8,
),
const Text('end'),
],
)
],
),
),
),
)
],
),
);
}
Widget buildRecordPlayer() {
return Container(
height: 270,
width: 270,
alignment: Alignment.center,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/vinyl.png'),
fit: BoxFit.fitHeight,
colorFilter: ColorFilter.mode(
Colors.blue,
BlendMode.color,
),
),
shape: BoxShape.circle,
),
child: ClipOval(
child: Image.asset(
'assets/images/SL.png',
height: 165,
width: 165,
fit: BoxFit.fill,
),
),
);
}
Widget buildWave(double width) {
return SizedBox(
width: 260 * _waveAnim.value,
height: 40,
child: CustomPaint(
painter: WaveBasePainter(),
child: ClipRect(
clipper: WaveClipper(_waveConstAmpAnim.value * width),
child: CustomPaint(
painter: WaveBasePainter(),
foregroundPainter: WaveColorPainter(_waveAnim),
),
),
),
);
}
}
And this is how my vscode looks like right now. I would be grateful if I could get rid of this error.

I can't click on Buttons in Appbar

I have created a custom appbar that contains buttons.The Problem is I cannot click on these buttons. I have checked the buttons with an output but not happened.
main.dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
initialRoute: '/',
routes: <String, WidgetBuilder>{
'/': (BuildContext context) {
return const HomeScreen();
},
'/archive': (BuildContext context) {
return const ArchiveScreen();
}
},
);
}
}
HomeScreen.dart
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Stack(
children: const [
Indexed(
index: 10,
child: Positioned(bottom: 0, left: 0, child: BottomNav()),
),
Indexed(
index: 1,
child: Positioned(
bottom: 0,
left: 0,
right: 0,
top: 0,
child: Text("hallo"),
),
),
],
),
),
);
}
}
BottomBar.dart
class BottomNav extends StatefulWidget with PreferredSizeWidget {
const BottomNav({super.key});
#override
Size get preferredSize => const Size.fromHeight(70.0);
#override
State<BottomNav> createState() => _BottomNavState();
}
class _BottomNavState extends State<BottomNav> {
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: 60,
decoration: const BoxDecoration(
border: Border(
top: BorderSide(width: 1.0, color: Color(0xFF999999)),
),
color: Color(0xFFF0F1F4),
),
child: Stack(
children: [
Align(
alignment: const Alignment(0, -0.5),
child: SizedBox(
width: 0,
height: 0,
child: OverflowBox(
minWidth: 0.0,
maxWidth: 100.0,
minHeight: 0.0,
maxHeight: 100.0,
child: Container(
width: 64,
height: 64,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(100)),
color: Color(0xFF00007F)),
child: IconButton(
icon: SvgPicture.asset('assets/icons/search-navbar.svg'),
tooltip: 'Increase volume by 10',
onPressed: () => {
Navigator.pushNamed(context, '/'),
debugPrint("home")
},
),
),
),
),
),
Align(
alignment: const Alignment(-0.8, 0),
child: IconButton(
icon: SvgPicture.asset('assets/icons/archive.svg'),
tooltip: 'Increase volume by 11',
onPressed: () => {
Navigator.pushNamed(context, '/archive'),
debugPrint("archive")
},
),
),
],
),
);
}
}
My first thought was that the cause is the stack and there is an element above the button. So I removed all the elements so that there was only one button in the appbar, but it didn't help.
change
onPressed: () => {
Navigator.pushNamed(context, '/'),
debugPrint("home")
},
to
onPressed: () {
Navigator.pushNamed(context, '/');
debugPrint("home");
},
and moreover, you can set BottomNavigationBar like this, it is easier than your Stack implementation
Scaffold(
bottomNavigationBar: BottomNav(),
// your body
)
you should find another solution, because your second Indexed with "hallo" is above the BottomNav and it covers the entire area.
I made it red so you can see it when you start the application
Stack(
children: [
const Indexed(
index: 10,
child: Positioned(bottom: 0, left: 0, child: BottomNav()),
),
Indexed( /// <- this widget is above the BottomNav and it covers the entire area
index: 1,
child: Positioned(
bottom: 0,
left: 0,
right: 0,
top: 0,
child: Container(
color: Colors.red,
child: Text("hallo"),
),
),
),
],
)
I got a Solution. It was a Combination of multiple problems. Like #Stellar Creed said, the Container was above my AppBar.
Another Problem was that I put SizedBox to width: 0 and height: 0.
Align(
alignment: const Alignment(0, -0.5),
child: SizedBox(
width: 0,
height: 0,
child: OverflowBox(
minWidth: 0.0,
maxWidth: 100.0,
minHeight: 0.0,
maxHeight: 100.0,
child: Container(
width: 64,
height: 64,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(100)),
color: Color(0xFF00007F)),
child: IconButton(
icon: SvgPicture.asset('assets/icons/search-navbar.svg'),
tooltip: 'Increase volume by 10',
onPressed: () {
/* Navigator.pushNamed(context, '/'); */
debugPrint("home");
}),
),
),
),
),

Responsive Layout with Flutter

I'm having issue while making the dashboard for my WebApp. I'm trying to make my webApp responsive. But not able to make it. Here is the image with the code for what I tried.
import 'package:flutter/material.dart';
class MyHomeScreen extends StatefulWidget {
const MyHomeScreen({super.key});
#override
State<MyHomeScreen> createState() => _MyHomeScreenState();
}
class _MyHomeScreenState extends State<MyHomeScreen> {
List<Widget> customWidgetList = [
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 300,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 200,
width: 200,
color: Colors.grey.shade200,
),
Container(
height: 100,
width: 200,
color: Colors.grey.shade200,
),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Responsiveness')),
body: Wrap(
spacing: 2.0,
runSpacing: 2.0,
clipBehavior: Clip.antiAlias,
children: customWidgetList,
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}
Result of above code :
Where as I want to fill all the empty spaces. Here is the image of what I want to do it.
Simple answer is to add direction: Axis.vertical to Wrap widget.
The correct answer is to create your own LayoutBuilder and calculate for each Container its correct position.
The easiest is to use https://pub.dev/packages/flutter_staggered_grid_view

Flutter: how to use ListView with expanded inside the nested column

#override
Widget build(BuildContext context) {
return Column(
children: [
Text(
"Scrolling Viewww :( ",
style: TextStyle(fontSize: 25),
),
Column(
children: [
Container(
height: 100,
width: 100,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.blue,
),
SizedBox(
height: 10,
),
Column(children: [
ListView( <------------------ **Making this Expanded**
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
],
),
]),
Container(
height: 100,
width: 100,
color: Colors.blue,
),
SizedBox(
height: 10,
),
],
)
],
);
I have tried to implement Expanded to resolved this. However, since it is nested twice, it was quite tricky. Only way that I could have done is just to set the Container() widget with given height.
But, in my real Column() widget, I have an AnimatedContainer that changes with its height. So, I want to find a way that I can do this with Expanded or Flexible.
I'd tried million different combinations. Nothing seems to work. How can I make the ListView that is inside the nested Column expandable?
Did you want to fix two item over ListView?
I implemented your request.
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _buildBody() {
return SafeArea(
child: Container(
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 40,
maxHeight: 40,
child: Container(
color: Colors.white,
child: Text(
"Scrolling Viewww :( ",
style: TextStyle(fontSize: 25),
),
),
),
),
SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 90,
maxHeight: 90,
child: Container(
height: 100,
width: 100,
color: Colors.blue,
child: Text('box1'),
),
),
),
SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 90,
maxHeight: 90,
child: Container(
height: 100,
width: 100,
color: Colors.blue,
child: Text('box2'),
),
),
),
];
},
body: Builder(
builder: (BuildContext context) {
final innerScrollController = PrimaryScrollController.of(context);
return SingleChildScrollView(
controller: innerScrollController,
child: Column(
children: [
ListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
Container(
height: 100,
width: 100,
color: Colors.red,
),
SizedBox(
height: 10,
),
],
),
Container(
height: 100,
width: 100,
color: Colors.blue,
),
SizedBox(
height: 10,
),
],
),
);
},
),
),
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
#required this.minHeight,
#required this.maxHeight,
#required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
#override
double get minExtent => minHeight;
#override
double get maxExtent => math.max(maxHeight, minHeight);
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return SizedBox.expand(child: child);
}
#override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
To avoid the bottom overflow, try wrapping a SingleChildScrollView around the first Column. Additionally you can play around with the mainAxisSize property of the different Columns.

Flutter ListView.builder() widget's cross Axis is taking up the entire Screen height

I am using ListView.builder(scrollDirection: Horizontal) widget inside a Container in Flutter. The main Axis of the ListView is taking up the entire screen width which is expected. I want the ListView's crossAxis(vertical direction) to take up the ListView's Item height (only wrapping the content), but it is taking up the entire screen height.
I have created the DartPard to explain the Issue. I want the ListView to take up the Item height and not the entire screen height.
Dart Pad Link : DartPard which shows the issue I am facing
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView.builder(
itemCount: 10,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
color: Colors.red,
child: Text(
'Item $index',
style: TextStyle(color: Colors.black),
),
);
},
),
),
),
),
);
}
}
Few workarounds which will work :
Using Row or Wrap instead of ListView.
Giving a Fixed height to the ListView.
I know the above listed approaches will work. But I want to achieve this using a ListView only.
This question is similar to this: Flutter: Minimum height on horizontal list view
After digging around a bit, I've realized that a ListView may not be the widget you are looking for.
Prior to this, I showed that the only way to control the height of the ListView was through a fixed setting of height because that is what a ListView is designed to do - display a list of items that is pre-formatted.
If you want to have the same functionality where the children set the height instead, meaning the widget wraps only the content, then I would suggest a SingleChildScrollView with a Row (note: Make sure to set the scrollDirection: Axis.horizontal)
Like this:
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(
// height: 100, // no need to specify here
color: Colors.white,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
),
)),
),
),
);
}
}
+++++++Added after OP comment+++++++
If you want to use a builder for a dynamic list, you can always define your own too!
import 'dart:math';
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
var _randHeight = Random();
List<int> someList = [
1,
2,
3,
4,
5,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
];
var randHeight = Random();
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: _createChildren(),
),
)),
),
),
);
}
List<Widget> _createChildren() {
return List<Widget>.generate(someList.length, (int index) {
return Container(
color: Colors.red,
width: 100,
height: _randHeight.nextInt(300).toDouble(),
child: Text(someList[index].toString(),
style: TextStyle(color: Colors.black)),
);
});
}
}
Did you try to use shrinkWrap: true on listview?