How can I prevent options view of the RawAutocomplete widget from overflowing on screen in Flutter? - flutter

I'm currently using a custom widget similar to this chips_input library. However, I don't want to give the options view (the popup list) a static maximum height. What I want to achieve is to dynamically set a maximum height of screen height - popup y offset. In this way, bottom of the options view will be at the bottom of the screen and all of the content inside the options view will be visible through scrolling. Is there any that I can access the textfield's or options view's offset to calculate the height?
My autocomplete widget looks similar to this:
RawAutocomplete<T>(
...
optionsViewBuilder: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: textFieldWidth,
child: Material(
elevation: 16,
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final T option = options.elementAt(index);
return suggestionBuilder(context, option);
},
),
),
),
),
);

You can do this by putting a height on your SizedBox that uses MediaQuery to get the screen height:
popupOffset = 20;
RawAutocomplete<T>(
...
optionsViewBuilder: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: textFieldWidth,
height: MediaQuery.of(context).size.height - popupOffset,
child: Material(
elevation: 16,
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final T option = options.elementAt(index);
return suggestionBuilder(context, option);
},
),
),
),
),
);

Related

Change scroll bar color of a list

I have a List View builder that builds some widget and puts them in a scroll bar:
I want the scrollbar to be purple, which is right now. The problem is that whenever I scroll I get The Scrollbar attempted to use the PrimaryScrollController. This ScrollController should be associated with the ScrollView that the Scrollbar is being applied to.A ScrollView with an Axis.vertical ScrollDirection on mobile platforms will automatically use the PrimaryScrollController if the user has not provided a ScrollController. To use the PrimaryScrollController explicitly, set ScrollView.primary to true for the Scrollable widget.
Is there a way to create a similar result without getting this error? What goes wrong?
Code:
RawScrollbar(
thumbColor: Colors.purple,
child: ListView.separated(
// controller: c,
primary: false,
padding: EdgeInsets.only(left: 15.0, right: 15.0, top: 10.0),
separatorBuilder: (BuildContext context, int index) {
return Visibility(
visible: true,
child: Container(
height: height * margin,
width: width * .8,
));
},
itemCount: _foundEvents.length,
itemBuilder: (context, index) => EventCard(
width: width * .8,
cardPadding: width * .05,
height: getCardHeight(height, margin: margin),
event: _foundEvents[index]["event"],
isLoading: eventsState.eventIdLoading ==
_foundEvents[index]["event"].id,
),
),
)
In order to RawScrollbar could works, its need to Apply on primary scroll list. But now you are setting ListView's primary to false. So you need set primary to true.

Why Can't I Define the Height of an Inner Container?

No matter what I do I can't seem to adjust the height of a nested Container in my flutter app. It always seems to inherit the height of the parent Container. Everything I read online said to wrap the inner container with a Center(). I tried this but still ended up with the same issue.
final _recommendations = <String>["Embroidery", "Jewelry Making", "Tennis", "Hiking", "Disc Golf"];
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 16.0),
height: 200,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _recommendations.length,
itemBuilder: (context, index) {
return Container(
width: 150,
height: 50,
child: Card(
color: Colors.blue,
child: Center(
child: Text(_recommendations[index])
)
)
);
}
)
)
);
Seems to me like the height of ListView is defined by its parent which is Container. So I expect ListView to have a height of 200. Then the height of Card should be defined by its parent container which gives a height of 50. However Card instead takes a height of 200...
Usually, a ListView widget tries to fill all the available space given by the parent element, even when the list items would require less space. You can disable this feature using shrinkWrap parameter of ListView as follow:\
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _recommendations.length,
shrinkWrap:true,
itemBuilder: (context, index) {
return Container(
width: 150,
height: 100,
child: Card(
color: Colors.blue,
child: Center(
child: Text(_recommendations[index])
)
)
);
}
)

Flutter - Add Layers on top of ListView to scroll

I am making a reader app and I have a ListView.builder which is loading multiple Images from the API. Now I want to add a layer on top of the ListView with 2 transparent containers so that when I click the left container the list goes up and when I click the right container the list goes down. I tried adding the ListView to stack but then the scrolling ability of the list is gone. This is my code so far:
return Scaffold(
body: Stack(
children: [
ListView.builder(
controller: _scrollViewController,
cacheExtent: 1000,
itemCount: _picLinkMap.length,
itemBuilder: (BuildContext ctx, int index) {
return buildImageLoader(
_picLinkMap[index], index + 1);
},
),
Row(
children: [
GestureDetector(
child: Container(
width: mySize.width * 0.5,
color: Colors.black38,
),
onTap: () {
print("Tap Left");
},
),
GestureDetector(
child: Container(
width: mySize.width * 0.5,
color: Colors.red.withOpacity(0.5),
),
onTap: () {
print("Tap RIGHT");
},
),
],
),
],
),
);
I only want to scroll about half the height of the screen on tap.
I searched the web but did not find a suitable solution.
ScrollController _scrollViewController = ScrollController();
...
var jumpTo = (MediaQuery.of(context).size.height - 104)/2;
//104 is random number for the rest of the screen widgets (e.g. appbar ..)
_scrollViewController.jumpTo(jumpTo); //pixel value
...
ListView.builder(
controller: _scrollViewController,

How to make a container 'lighten' on hold / on tap in Flutter?

I am trying to create an app with a scroll view and the objects are clickable like the google news app. Can anyone answer how to animate the container to have a white glow on holding the tile?
Here is the list view builder I have for the app
Container(
padding: EdgeInsets.only(top: 16),
child: ListView.builder(
physics: ClampingScrollPhysics(),
itemCount: article.length,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (context, index) {
return news_tile(
imageurl: article[index].urlToimage,
news_title: article[index].title,
news_desc: article[index].description,
web_url: article[index].url
);
}),
)
and this is the contents of the tile which the list view builder calls
class news_tile extends StatelessWidget {
String imageurl, news_title, news_desc,web_url;
news_tile({this.imageurl, this.news_title, this.news_desc,this.web_url});
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => article_view(
web_url: web_url,
)
));
},
child: Container(
margin: EdgeInsets.only(bottom: 16),
child: Column(
children: <Widget>[
ClipRRect(borderRadius: BorderRadius.circular(6), child: Image.network(imageurl)),
SizedBox(
height: 8,
),
Text(news_title, style: TextStyle(fontSize: 17,fontWeight: FontWeight.w600)),
SizedBox(
height: 8,
),
Text(news_desc, style: TextStyle(color: Colors.black54))
],
),
),
);
}
}
You could go with the InkWell Widget. It provides a tapping/holding color effect similar to that. Have a look at the official docs here:
https://api.flutter.dev/flutter/material/InkWell-class.html
Note that you need a Material Widget as an ancestor of your InkWell, but the docs explain that more.
Hope it works for you!
Edit: Sorry, since you are working with a Container, Ink is also important for you:
https://api.flutter.dev/flutter/material/Ink-class.html
Check the docs section "The ink splashes aren't visible!" for why that is.

Flutter: flutter_swiper package control space between slides

I am using flutter_swiper package in my app. I have following code:
Container(
height: size.getSizePx(200),
child: Swiper(
itemBuilder: (BuildContext context, int index) {
return Align(
alignment: Alignment.topLeft,
child: Container(
height: size.getSizePx(200),
child: Image.network(imageList[index].thumb),
),
);
},
itemCount: imageList.length,
),
)
Image size that comes server is normally 370x276
Problem
Swiper works very well, but space between two images is very big. Is there any how I can control the spaces between Swiper slides (images)?
Thanks