Is it possible to fill ExpansionTile title with image in Flutter? - android

I want to create an expandable gallery, which has one image as a main image and upon clicking on it, I want to expand the gallery and show few images below the main image.
So, I have created a ListView, which has a builder that returns ListTileTheme, which I used for removing the contentPadding, with child - ExpansionTile, but I still have some padding left in the container.
Any idea how to completely fill the ExpansionTile? I've tried different approaches that I saw on the web, but no solution so far.
Here is my code:
Container _getGallery() {
Container container = new Container(
height: 500.0,
child: new ListView.builder(itemCount: 1, itemBuilder: (context, i)
{
ListTileTheme tileTheme = new ListTileTheme(
contentPadding: EdgeInsets.all(0.0),
child: ExpansionTile(
trailing: Container(
height: 0.0,
width: 0.0,
),
backgroundColor: Colors.transparent,
title: Image.asset("assets/images/onboarding2.png",
height: 200.0,
width: double.infinity,
alignment: Alignment.center,
fit: BoxFit.cover,
),
children: <Widget>[
new Column(
children: _buildExpandableContent(),
),
],
),
);
return tileTheme;
}),
);
return container;
}
Here you can see what I've achieved so far (1- not expanded, 2- expanded). I want to remove this white lines around the first image.

No, it's not possible. This widget uses ListTile, which adds 16px gap (_horizontalTitleGap constant) if there's trailing widget. The problem is that there's always a trailing widget in ExpansionTile, even if you pass null:
trailing: widget.trailing ?? RotationTransition(
turns: _iconTurns,
child: const Icon(Icons.expand_more),
),
The only dirty workaround I can suggest is to use scale transform to compensate this 16px gap:
title: LayoutBuilder(
builder: (context, constraints) {
final newScale = 1.0 + 16.0 / constraints.maxWidth;
return Container(
transform: Matrix4.identity()..scale(newScale),
child: Image.asset("assets/images/onboarding2.png",
height: 200.0,
width: double.infinity,
alignment: Alignment.center,
fit: BoxFit.cover,
),
);
}
),

Related

How to remove PageView's leading space in Flutter?

I implemented images carousel by using PageView and research about it for a moment and then I archived this result.
As you see, I got extra space in front of first item in PageView. I have no idea to remove it. Has anyone ever did it ? Thank you so much
My PageView Class
List<String> images = [
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQTIZccfNPnqalhrWev-Xo7uBhkor57_rKbkw&usqp=CAU",
"https://cdn.dribbble.com/users/4684322/screenshots/18696799/media/722072055e079b1b7c88b1894a1128d7.png?compress=1&resize=1000x750&vertical=top"
];
return Container(
color: Colors.red,
width: double.infinity,
height: 200,
child: PageView.builder(
itemCount: 2,
pageSnapping: true,
controller: _pageController,
itemBuilder: (context, pagePosition) {
return Container(
margin: EdgeInsets.only(right: 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.network(
images[pagePosition],
fit: BoxFit.cover,
),
));
},
),
);
PageView Controller
_pageController = PageController(viewportFraction: 0.8);
Solution
After I take deep inside PageView class, I just tried every constructor properties ( T_T ) and got solution.
padEnds: false
set it in constructor of PageView
PageView.builder(
itemCount: 2,
padEnds: false,
pageSnapping: true
itemBuilder: (context, pagePosition) {
return Container();
},
)
If anyone has another solution, you can tell me? :)
I copied your code and ran it. There was no problem. It is suggested to change it as follows:
return Container(
margin: const EdgeInsets.only(right: 10),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.asset("asset/bb.jpeg",
fit: BoxFit.cover,
width: double.infinity,
)
))
look here

Flutter - can I make a SingleChildScrollView fill the available space?

I have a Flutter app which I'm building for Android. The structure goes broadly like this:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("")),
body: SingleChildScrollView(
child: Container(
decoration: const BoxDecoration(
gradient: ...
),
child: ...
),
)
);
}
The goal here is to have the gradient background fill all the screen below the app bar, and if the content is larger than that space then to make it scrollable.
If I omit the SingleChildScrollView, the Container fills the space. But of course if it overflows then there is no scrolling. With the code as above, the scroll view does its thing on small screens but on large screens the gradient background doesn't fill the whole available area.
If I change it around like this:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("")),
body: Container(
decoration: const BoxDecoration(
gradient: ...
),
child: Column(children: [
SingleChildScrollView(
child: ...
),
Expanded(child:Container())
]),
)
);
}
then the gradient fills the background but the scroll view doesn't do the right thing - the content overflows the screen but can't be scrolled. How do I get it to do both?
The reason you're facing this issue is that your container is inside the SingleChildScrollView Widget and is getting scrolled along the SingleChildScrollView Widget. And Removing the SingleChildScrollView will result in renderflex overflow error
The Expanded keyword will throw incorrect use of ParentDataWidget
Also, you have added SingleChildScrollView widget inside the column you have to swap these well
Here is an example that I have given which will help you achieve it.
Widget build(BuildContext context) {
return Scaffold(
body: Container(
// Add The Container gradient here
width: double.infinity,
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: Column(
children: [
Container(
height: 100,
width: 50,
color: Colors.red,
),
Container(
height: 100,
width: 50,
color: Colors.blue,
),
Container(
height: 1000,
width: 50,
color: Colors.yellow,
),
Container(
height: 1000,
width: 50,
color: Colors.orange,
),
],
)),
));
}

Problem in body height in SlidingUpPanel flutter

Not all list are visible in body under SlideUpPanel
In list I am having 83 items but last 2~3 items are not visible
SlidingUpPanel(
minHeight: 50,
body: Container(
height: MediaQuery.of(context).size.height-100, //No effect
child: ListView.builder(
itemCount: dataBox.values.length,
itemBuilder: (context, i){
return ListTile(...);
}
)
),
panel: Container(
color: Colors.black,
),
)
If you go into the source code of SlidingUpPanel, you can see that it is using the screen size to set the width and height of the body:
// Inside SlidingUpPanel's build() method:
// ... other lines
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: widget.body,
),
// ... other lines
This is why when you add an AppBar and other elements in the screen, it will reposition the body but the body's height is still equal to the screen height. One workaround is to use a Stack instead of setting the body of the SlidingUpPanel. Something like:
#override
build(context) {
var _collapsedHeight = 50.0;
return Stack(
children: [
Container(
// Set the padding to display above the panel
padding: EdgeInsets.only(bottom: _collapsedHeight),
child: ListView.builder(
itemCount: dataBox.values.length,
itemBuilder: (context, i){
return ListTile(...);
}
)
),
SlidingUpPanel(
minHeight: _collapsedHeight,
panel: Container(
color: Colors.black,
),
),
],
);
}
Use MediaQuery to Get the Size of the Screen then Apply this ,
height: MediaQuery.of(context).size.height*0.7;

Flutter Multiple Heroes That Share The Same Tag Within A Subtree

I am trying to have a hero animation from a post view screen to a full screen post view. As far as I can see, it seems quite normal(my code) and I don't really understand why I am getting this error...
I don't have any other Hero widgets in my code, so I cannot see why I should be getting this error...
Here is the error I am getting:
There are multiple heroes that share the same tag within a subtree.
Here is my code:
Stack(
alignment: Alignment.center,
children: <Widget>[
Hero(
tag: 'test',
child: Container(
height: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
alignment: Alignment.topRight,
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5),
borderRadius: BorderRadius.circular(12.0),
),
width: 120,
height: 40,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (BuildContext context, int index) {
return _configureEmoji(index);
},
),
),
),
),
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(widget.post.imageURL),
fit: BoxFit.cover,
),
),
),
),
],
),
Here is where I want the hero animation to go to:
class FullScreenView extends StatelessWidget {
final String imageURL;
FullScreenView({this.imageURL});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Hero(
tag: 'test',
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(imageURL),
fit: BoxFit.cover,
),
),
),
),
);
}
}
Thanks a lot and I really appreciate your help!
Plausible reason
The Hero widget doesn't know which Hero you clicked on, so it uses the next screen's Hero tag as a reference to perform a screen search that will close by looking for the Hero with that same tag. If there is more than one Hero with the same tag then an error will be returned as it is not known which Hero should do the animation.
Solution
The solution I use is to identify each Hero using as a reference the content inside it and in the navigation I insert this id (tag) in the navigation push argument and then add this id in the Hero of the target screen.
The most plausible way for your project is to use the post id as the Hero tag, that when sending the post data to the next screen already use the post id on the screen's Hero.

Stack Widget Error when using SingleChildScrollView

I have this code as profile screen which I need it to be able to fill a text like "HELLO" on this code example. But when I put a lot of text in it, the screen become overflow.
The problem is everytime I put SingleChildScrollView to avoid the overflow, I got another error instead.
Please tell me how I can fix this problem.
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: FutureBuilder<Profile>(
future: dataService.getHttp(),
builder: ...
),
),
);
}
Widget _buildView(detail) {
return Stack(
alignment: Alignment.center,
children: <Widget>[
Column(
children: <Widget>[
Container(
height: 200.0,
child: Center(
child: Image.network(
'https://i.imgur.com/2F3Al82.jpg',
fit: BoxFit.cover,
height: double.infinity,
width: double.infinity,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0.0, 50.0, 0.0, 0.0),
),
Expanded(
child: Container(
color: Colors.white,
child: Column(
children: <Widget>[
Text('HELLO'),
]
),
)
),
],
),
Positioned(
top: 150.0,
child: Container(
height: 100.0,
width: 100.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.fill,
image: NetworkImage('https://i.imgur.com/2F3Al82.jpg'),
),
),
),
)
],
);
}
this is the error
You are getting this error because of the Expanded widget. SingleChildScrollView allows for infinite height and expanded will take up as much space as it can these two thing are incompatible if you remove the Expanded widget it should work. If you want some space around that container I suggest the Containers margin property.

Categories

Resources