I am making an application where you can edit the profile picture and I want to scroll only when I click on a piece of the screen.
The screen as you see in the picture is divided 50 - 50, the top part is the profile picture, and inside it you can move to select the part that is inside the circle (you can also zoom).
The lower part is the gallery with the latest photos.
Example
What I want to do, is that if I click on the upper part, it does not scroll, it simply works with the zoom that already has that widget. And if I click in the inferior part, I want that a complete zoom is done, that is to say that it raises the whole screen, including the profile photo.
My code is the following:
CustomScrollView(
slivers: [
SliverToBoxAdapter(child: SizedBox(
height: maxHeight,
child: Stack(
children: [
Positioned(
top: 0.1,
child: SizedBox(
height: maxHeight,
width: Sizes.width,
child: Stack(children: [
Positioned.fill(
child: PhotoView(
backgroundDecoration: BoxDecoration(color: Colors.transparent),
minScale: PhotoViewComputedScale.covered,
onScaleEnd: (c, details, controllerValue) {
},
enableRotation: false,
imageProvider: NetworkImage(
'https://i.stack.imgur.com/lkd0a.png',
),
),
),
]),
),
),
IgnorePointer(
child: ClipPath(
clipper: InvertedCircleClipper(),
child: Container(
color: Colors.black.withOpacity(0.3),
)),
),
],
)))),
SliverPadding(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
sliver: SliverToBoxAdapter(
child: Row(children: [
Text(
'gallery'.tr,
),
Icon(Icons.keyboard_arrow_down_rounded)
]),
)),
SliverPadding(
padding: edgeInsets,
sliver: SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
),
delegate: SliverChildBuilderDelegate((context, index) {
final image = localImages[index];
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: FadeInImage(
width: 400,
height: 400,
placeholder: MemoryImage(kTransparentImage),
image: DeviceImage(image, size: const Size(400, 400), quality: 90),
fit: BoxFit.cover,
),
);
},
childCount: localImages.length),
)
],
),
How can I do it? Thank you.
Related
I used gridView.builder. To set the size of the grid, I use MediaQuery, but for some reason the gridView is displayed differently on different devices, using which parameter in gridDelegate: can I fix this?
my gridView code:
Widget buildCatalog(List<Product> product) => CustomScrollView(
controller: sController,
slivers: [
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
// mainAxisExtent: ,
maxCrossAxisExtent: 300,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.3),
crossAxisSpacing: 10,
mainAxisSpacing: 10),
delegate: SliverChildBuilderDelegate(childCount: product.length,
(BuildContext context, int index) {
return GestureDetector(
onTap: () {},
child: Container(
padding: const EdgeInsets.only(left: 2, right: 2, top: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8)),
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: const EdgeInsets.only(top: 5),
child: Image.network(),
),
),
const SizedBox(
height: 10,
),
Text(),
// Spacer(),
const SizedBox(height: 8),
Text(),
const SizedBox(height: 5),
buildButton(index, productItem.id),
],
),
),
);
}),
),
]
);
This is my grid on big displays:
and this on small displays:
The solution was flutter_screenutil package
I want to make this image/Text resizeable when run on a smaller or bigger phone rights now it’s just look like not fitted to the screen. What widgets should I wrap it with?
This is my IphoneS:
And this is my current simulator (Iphone13):
And some of the Code for the CarouselSlider images:
List image1 = [
'assets/images/f1.png',
'assets/images/f2.png',
'assets/images/f3.png',
'assets/images/f4.png',
];
CarouselSlider(
options: CarouselOptions(
height: 200.0,
autoPlay: true,
reverse: false,
enlargeCenterPage: false,
enableInfiniteScroll: false,
scrollDirection: Axis.horizontal,
autoPlayInterval: const Duration(seconds: 6),
autoPlayAnimationDuration:
const Duration(seconds: 3),
),
items: image1
.map(
(item) => Padding(
padding: const EdgeInsets.only(top: 9.0),
child: Card(
margin: const EdgeInsets.only(
top: 10.0,
bottom: 20.0,
),
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0),
),
child: GestureDetector(
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(10.0),
),
child: Image.asset(
item,
fit: BoxFit.fill,
),
),
onTap: () {
image1.indexOf(item);
indexMethod(
image1.indexOf(item).toString());
},
),
),
),
)
.toList(),
),
And some of the Code for the Text:
//profile button only
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: CircleAvatar(
radius: 28,
backgroundColor:
const Color(0xff5CE1E6),
child: IconButton(
icon: const Icon(
Icons.person,
size: 35,
color: Colors.black,
),
onPressed: () => Navigator.push(
context,
PageTransition(
type: PageTransitionType
.rightToLeft,
child:
const ProfileScreen())),
),
),
),
const Padding(
padding: EdgeInsets.only(top: 10.0),
child: Text('Profile'),
),
],
),
try this https://pub.dev/packages/flutter_screenutil
A flutter plugin for adapting screen and font size. Let your UI display a reasonable layout on different screen sizes!
tutorial: https://youtu.be/LWteDQes4Kk
An easy and dependency-free way is to use MediaQuery.of(context).size
Examples:
Use MediaQuery.of(context).size.width to get a full width of the device.
Use MediaQuery.of(context).size.height to get the total height of the device.
Use MediaQuery.of(context).size.height * 0.3 to get 30% of the device height.
I'm making an application in flutter.
And i wanna show some list of items using GridView, showing 3 items in a row. And make their size flexible depend on the devices.
But Actually what i coded doesn't work properly.
When device screen is somewhat narrow, they shrink and messed up like this.
But when the device screen become wider, the size of image doesn't expand but only the spaces between the items expanded like below.
I wanna make the pictures fill the screen. How can i make it?
Thank you for concerning my question, and i'm sorry about the foreign languages in the picture.
return Scaffold(
appBar: AppBar(
title: Text("${getUnitBookClassTitlebyTag(tag!)} 목록"),
backgroundColor: Color(COLOR_PRIMARY),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: CustomScrollView(
primary: false,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.all(20),
sliver: SliverGrid.count(
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: <Widget>[
for (UnitBook _curUnitBook in unitBookList!)
UnitBookDisplay(
bookData: _curUnitBook,
imageHeight: null,
imageWidth: null),
],
),
),
],
)),
);
/***
Widget build(BuildContext context) {
//bookDataReplace();
//debugPrint('cover : ${bookData!.coverUrl!}');
//debugPrint('cover : ${bookData!.coverUrl!.replaceAll('\\/', '/')}' );
if (bookData == null) debugPrint('bookData is null!!');
return Column(
children: [
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
DetailScreen(book: convertUnitBooktoBook(bookData!)),
),
);
},
child: Expanded(
child: Container(
margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 10.0),
height: imageHeight,
width: imageWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
offset: Offset(0.0, 4.0),
blurRadius: 6.0,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: (bookData!.coverUrl == null)
? (Image(
image: AssetImage('images/default_book_cover_image.png'),
fit: BoxFit.cover,
))
: (Image.network(
'${bookData!.coverUrl!.replaceAll('\\/', '/')}',
fit: BoxFit.cover,
)),
),
),
),
),
SizedBox(
child: Text((bookData!.title == null) ? 'unNamed' : bookData!.title!,
overflow: TextOverflow.ellipsis),
width: imageWidth,
),
],
);
}
While using SliverGrid or GirdView, childAspectRatio decide its children size. While children having fixed height on
child: Expanded(
child: Container(
margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 10.0),
height: imageHeight, //<- here
Bottom RenderFlex overflowed occurs only when SliverGrid failed to provide enough height for the children.
You can try removing fixed height from here only UI don't face any issue, but for better design purpose use childAspectRatio on SliverGrid.count, something like
SliverGrid.count(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 3 / 4,// width/height : check and change the way you want.
children: ....
Also, you can try Wrap.
I have this box decoration used for showing the reviews but I don't know what I should use to align the text properly. This is how it looks right now:
I want the username ("La fottaria to have some space left) I used Align( Alignment(8,3)) but it doesn't change the position.
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return Container(
width: 200,
margin: EdgeInsets.only(
top: 8, bottom: 8, right: 12),
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 2,
spreadRadius: 1)
], borderRadius: BorderRadius.circular(4)),
child: Column(
children: [
Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data.documents[index]
.data["avatarUrl"]),
),
Align(
alignment: Alignment(8, 3),
child: Text(snapshot
.data
.documents[index]
.data["name"]),
)
],
),
_buildRatingStars(snapshot.data
.documents[index].data["rating"]),
Text(snapshot
.data.documents[index].data["text"])
],
),
);
}
);
Inside the Row widget, you can use a SizedBox with width property.
It will give some space.
Row(
children: [
CircleAvatar(
backgroundImage:
NetworkImage(snapshot.data.documents[index].data["avatarUrl"]),
),
//insert here
SizedBox(
width: 20.0,
),
Align(
alignment: Alignment(8, 3),
child: Text(snapshot.data.documents[index].data["name"]),
)
],
)
You can remove the Align widget if you want.
Instead of align widget, I suggest you to use Container widget like this:
Container(
margin: const EdgeInsets.only(left: 15),
child: Text(snapshot
.data
.documents[index]
.data["name"]),
)
Use Align
Example:
DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
width: 1,
),
borderRadius: BorderRadius.circular(4),
),
child: Align(
alignment: Alignment.center, // align type
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 15),
child: Text(
title,
style: TextStyle(fontSize: 17, color: Colors.blue),
),
),
),
)
You can use some inbuilt property of rows i.e Main Axis Alignment and Cross Axis Alignment to align its children.For eg:
Row(
mainAxisAligment:MainAxisAlignment.spaceEvenly,
crossAxisAligment:CrossAxisAligment.center,
children: [
CircleAvatar(
backgroundImage:
NetworkImage(snapshot.data.documents[index].data["avatarUrl"]),
),
SizedBox(
width: 20.0,
),
Text(snapshot.data.documents[index].data["name"]),
],
)
You can wrap the text widget inside padding widget also to align according to your needs.
I am trying to scale down the image a bit so that it won't be cropped in grid item element. Actual image size is 300x300.
below is my code where I am explicitly trying to reduce the image width and height, I have also attempted many combinations with the fit type. I do not see any visible impact though. Can you let me know how should I achieve this? Thank you for your patience.
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
childAspectRatio: 1.5,
crossAxisCount: 2,
children: List.generate(
8,
(index) {
return Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(5),
child: CircleAvatar(
backgroundImage: Image.asset(
'assets/icons/antenna_icon.png',
height: 30,
width: 30,
fit: BoxFit.fitWidth,
).image,
backgroundColor: Colors.grey.shade300,
radius: 50,
)),
Text(
"Evve",
style: GoogleFonts.roboto(color: Colors.black87, fontSize: 15),
),
],
));
},
),
));
}
You can use Transform.scale as the child of the CircleAvatar and set the image as the child of the Transform.scale:
CircleAvatar(
child: Transform.scale(
scale: 0.8,
child: Image.asset(
'assets/icons/antenna_icon.png',
height: 30,
width: 30,
fit: BoxFit.fitWidth,
),
),
backgroundColor: Colors.grey.shade300,
radius: 50,
)