Create Gridview with user input(Row and Column) in flutter - flutter

How can we create Gridview with the user input? the user is allowed to enter the no of rows and columns.

class Class extends StatefulWidget {
#override
_ClassState createState() => _ClassState();
}
class _ClassState extends State<Class> {
TextEditingController row = TextEditingController();
TextEditingController column = TextEditingController();
int rowC = 2;
int colC = 2;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
height: 500,
child: GridView.builder(
itemCount: colC * rowC,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: rowC,childAspectRatio: colC*rowC/2 ,crossAxisSpacing: 10,mainAxisSpacing: 10),
shrinkWrap: true,
itemBuilder: (context, index) => Container(
color: Colors.greenAccent,
),
),
),
Text("Row"),
TextField(
controller: row,
),
SizedBox(height: 20,),
Text("Column"),
TextField(
controller: column,
),
SizedBox(height: 20,),
FlatButton(onPressed: (){
rowC = int.parse(row.text);
colC = int.parse(column.text);
setState(() {
});
}, child: Container(
color: Colors.purple,
padding: EdgeInsets.all(20),
child: Text("Add")))
],
),
);
}
}

You can achieve your requirement by using the GridView.builder.
GridView.builder(
shrinkWrap: true,
itemCount: (rowCount * ColumnCount),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: ColumnCount),
itemBuilder: (context, index) {
return Container(
child: Text(index.toString()),
);
}, );
Every user input you must to refresh the widget.

Related

Flutter TextFormField suggestion or auto complete

I want to implement suggestions inside textFormField. same as below
So, I've searched regarding this but with no success. Everywhere I've got is suggestions inside list. Which is easy to do. If you have any suggestions then please add your valuable answer and comment.
Here is my code
Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: controller,
onFieldSubmitted: (value) {},
onChanged: (value) {
displaySuggestionInList(value);
},
),
const SizedBox(height: 30),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 100,
maxWidth: 200,
minWidth: 200,
minHeight: 100,
),
child: ListView.builder(
shrinkWrap: true,
itemCount: dashboardLayouts!.length,
itemBuilder: (context, index) {
return Text((dashboardLayouts![index]['dashBoardData']
as DashboardInfo)
.commonName
.toString());
},
),
)
],
),
What you need to create is a Type-Ahead Widget. To do that, you will firstly create the normal List suggestion StatefulWidget. While on the filter function you should update the hint with the first value from the suggestion list. This way you can call the hint value and place it anywhere on your screen. Unfortunately for us, flutter doesn't allow the update showing of hint within the input field while typing.
Although I made an example for you to get the idea.
class AutocompleteExample extends StatefulWidget {
const AutocompleteExample({super.key});
#override
State<AutocompleteExample> createState() => _AutocompleteExampleState();
}
class _AutocompleteExampleState extends State<AutocompleteExample> {
TextEditingController controller = TextEditingController();
List suggestionList = [];
String hint = "";
List<String> nameList = <String>[
'aardvark',
'bobcat',
'chameleon',
'Nathaniel Bond',
'Taylor Story',
'Lamont Padilla',
'Jamia Sun',
'Nikki Reichert',
'Tea Holguin',
'Rafael Meade',
'Mercedez Goad',
'Aileen Foltz',
'Bryant Burt',
];
void typeAheadFilter(String value) {
suggestionList.clear();
if (value.isEmpty) {
setState(() {});
return;
}
for (String name in nameList) {
if (name.toLowerCase().contains(value)) {
suggestionList.add(name);
}
}
if (suggestionList.isNotEmpty) {
var firstSuggestion = suggestionList[0];
setState(() => hint = firstSuggestion);
}
setState(() {});
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: controller,
onFieldSubmitted: (value) {},
onChanged: (value) => typeAheadFilter(value),
decoration: InputDecoration(
hintText: hint,
labelText: hint.isEmpty ? "Search" : hint,
alignLabelWithHint: true,
hintTextDirection: TextDirection.rtl),
),
const SizedBox(height: 10),
if (suggestionList.isNotEmpty || controller.text.isNotEmpty) ...[
Expanded(
child: ListView.separated(
padding: const EdgeInsets.all(10),
shrinkWrap: true,
itemCount: suggestionList.length,
separatorBuilder: (context, index) => const Divider(),
itemBuilder: (context, index) {
return Text((suggestionList[index]));
},
),
)
] else ...[
Expanded(
child: ListView.separated(
padding: const EdgeInsets.all(10),
shrinkWrap: true,
itemCount: nameList.length,
separatorBuilder: (context, index) => const Divider(),
itemBuilder: (context, index) {
return Text((nameList[index]));
},
),
)
]
],
);
}
}

multi type list View in Flutter

How I can display list View with multi-type for example(item 1: text, item 2: image with Text ...)
using flutter?
Here is the code:
I need to make the ListView show onlyText in item1, imageWithText for item2 and so on, How I can do that?
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
SizedBox(height: 5),
ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) => onlyText(),
separatorBuilder: (context, index) => SizedBox(height: 10),
itemCount: 100,
),
],
),
);
}
}
Widget imageWithText() => Container(
child: Card(
child: Row(
children: [
Text(
'sara ahmad',
style: TextStyle(fontSize: 16),
),
SizedBox(width: 10),
Image.network(
'https://th.bing.com/th/id/R.e3a5da5209f4c39f1899456c94371a6f?rik=mz9sVBWxRJKGgA&riu=http%3a%2f%2fmedia1.santabanta.com%2ffull1%2fAnimals%2fHorses%2fhorses-62a.jpg&ehk=o%2fS9l8DSJtUbl%2bYcrwLMJy6W4MfUby7bTUHRwJu7a%2bU%3d&risl=&pid=ImgRaw&r=0',
width: 100,
height: 100,
),
],
),
),
);
Widget onlyText() => Container(
child: Card(
child: Row(
children: [
Text(
'sara ahmad',
style: TextStyle(fontSize: 16),
),
SizedBox(width: 10),
Text('Nour'),
],
),
),
);
In the itemBuilder you can check if the item is only text or image with text with a ternary operator ?:, i.e. condition ? expr1 : expr2, like so:
itemBuilder: (context, index) => index == 0 ? onlyText() : imageWithText(),
Or, if you have a list of more than 2 items it could be something like this (assuming the items have a property bool isOnlyText):
itemBuilder: (context, index) => _chats[index].isOnlyText
? onlyText()
: imageWithText(),
Below is the result of the 1st snippet above:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
SizedBox(height: 5),
Expanded(
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) =>
index == 0 ? onlyText() : imageWithText(),
separatorBuilder: (context, index) => SizedBox(height: 10),
itemCount: 100,
),
),
],
),
);
}
///crete an empty widget list
List<Widget> item_list=[];
///create a function to add data to list and call this function in the initstate
add_items_to_list()async{
item_list.add(Text(('data')));
item_list.add(Image.asset('name'));
///add as much as you want
}
///use widget as below
Widget items()=>ListView(
children: item_list,
);
if you want to show static list, you can do like this
itemBuilder: (context, index) => index.isEven
? onlyText()
: imageWithText(),
or you have dynamic data then follow below
let's assume you have list of Model class like this
class Model{
String text,
String img,
}
var list = <Model>[]; //your data will be here
and to check if is there only image, you need condition like below,
so in your ListView you can check like this
itemBuilder: (context, index) => list[index].img == null
? onlyText()
: imageWithText(),

Create Blocks of containers which can scroll both horizontally and vertically in flutter

I am designing the app in which i have to create some number of blocks which represent the flats of building.
in which i have 2 numbers
number of floors
number of flats per floor
so i tried 2 ways
Using gridview and give itemCount as number of floors crossAxisCount as - number of flats per floor
Using 2 Listview. first listview for floor - which scroll vertically and inside its builder second listview for flats which scroll horizontally.
but i want to make it as scrollable for both horizontally and vertically, so i don't know how to do it, can anyone help me please !
look this,created using listview
You can achieve this by nesting horizontal ListViews inside a vertical ListView:
ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemExtent: 50,
itemBuilder: (context, verticalIndex) => ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 15,
itemExtent: 50,
itemBuilder: (context, appartmentIndex) => Container(),
),
);
Full Demo
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
const List<Color> kColors = [
Color(0x66a7414a),
Color(0x66282726),
Color(0x666a8a82),
Color(0x66a37c27),
Color(0x66563838),
];
const double kOpacity = .6;
const double kAppartmentSize = 64.0;
const TextStyle kFloorTextStyle = TextStyle(
fontSize: 8.0,
fontWeight: FontWeight.normal,
);
const TextStyle kApartmentTextStyle = TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
);
const int kMinNbFloors = 10;
const int kMaxNbFloors = 18;
const int kMinNbApartments = 3;
const int kMaxNbApartments = 10;
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Real Estate Demo',
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(title: Text('Real Estate Demo')),
body: MyWidget(),
),
),
);
}
class MyWidget extends HookWidget {
final Random random = new Random();
#override
Widget build(BuildContext context) {
final nbFloors = useState(
kMinNbFloors + random.nextInt(kMaxNbFloors - kMinNbFloors + 1));
final nbAppartments = useState(
List.generate(
nbFloors.value,
(index) =>
kMinNbApartments +
random.nextInt(kMaxNbApartments - kMinNbApartments + 1),
),
);
return ListView.builder(
shrinkWrap: true,
itemCount: nbFloors.value,
itemExtent: kAppartmentSize,
reverse: true,
itemBuilder: (context, floorIndex) => ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: nbAppartments.value[floorIndex],
itemExtent: kAppartmentSize,
itemBuilder: (context, appartmentIndex) => Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color:
kColors[random.nextInt(kColors.length)].withOpacity(kOpacity),
border: Border.all(
width: .5, // red as border color
),
image: DecorationImage(
image: AssetImage("images/window.png"),
fit: BoxFit.contain,
alignment: Alignment.center,
),
),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(appartmentIndex.toString(), style: kApartmentTextStyle),
const SizedBox(width: 4.0),
Text(floorIndex.toString(), style: kFloorTextStyle),
],
),
),
),
),
);
}
}

Flutter: How can I use DraggableScrollableActuator.reset AND the ScrollController from DraggableScrollableSheet for a nested list?

I am getting this error.
The following assertion was thrown building _InheritedResetNotifier(dirty):
flutter: ScrollController attached to multiple scroll views.
flutter: 'package:flutter/src/widgets/scroll_controller.dart':
flutter: Failed assertion: line 111 pos 12: '_positions.length == 1'
It seems I can either attach DraggableScrollableSheet's ScrollController to the nested list OR use DraggableScrollableActuator.reset(context) to reset the extent. I don't see why I can't do both. Is this a bug? Is there a work around or another way?
Here is my code:
class InterfaceSelector extends StatefulWidget {
#override
InterfaceSelectorState createState() => InterfaceSelectorState();
}
class InterfaceSelectorState extends State<InterfaceSelector> {
double initialChildSize = 0.5;
double minChildSize = 0.5;
double maxChildSize = 0.7;
#override
Widget build(BuildContext context) {
return DraggableScrollableActuator(
child: DraggableScrollableSheet(
initialChildSize: initialChildSize,
minChildSize: minChildSize,
maxChildSize: maxChildSize,
builder: (BuildContext ctx, ScrollController scrollController) {
return SingleChildScrollView(
controller: scrollController,
child: Container(
height: MediaQuery.of(context).size.longestSide * .7,
color: Theme.of(ctx).primaryColor,
child: DefaultTabController(
length: 4,
child: Column(
children: <Widget>[
Material(
color: Theme.of(ctx).accentColor,
child: TabBar(
tabs: [
Tab(text: "One"),
Tab(text: "Two"),
Tab(text: "Three"),
Tab(text: "Four"),
],
),
),
Expanded(
child: TabBarView(
children: [
One(),
Two(),
Three(scrollController),
Four(),
],
),
),
],
),
),
),
);
},
),
);
}
}
class Three extends StatefulWidget {
ScrollController scrollController;
Three(this.scrollController);
#override
_ThreeState createState() => _ThreeState();
}
class _ThreeState extends State<Three> with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
Stuff stuff = Provider.of<Stuff>(context);
return Column(
children: <Widget>[
MaterialButton(onPressed: () {
DraggableScrollableActuator.reset(context);
}),
Expanded(
child: GridView.builder(
controller: widget.scrollController,
padding: const EdgeInsets.all(10),
itemCount: stuff.all.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: stuff.all[i],
key: UniqueKey(),
child: StuffCard(i, stuff.all[i], stuff),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),
),
],
);
}
}
Your GridView doesn't need scrolling - scrolling is provided by your SingleChildScrollView. Don't pass the scrollController to GridView, set physics: NeverScrollableScrollPhysics(), in your grid builder instead:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(10),
itemCount: stuff.all.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: stuff.all[i],
key: UniqueKey(),
child: StuffCard(i, stuff.all[i], stuff),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),

How to add scroll indicator in ListView

Is there any way to show the scroll indicator on the ListView?
Here is my basic code:
ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => ListTile(title: Text("Item= ${index + 1}"),),
)
Thanks to Günter Zöchbauer.
You can wrap your ListView in Scrollbar
Scrollbar(
child: ListView.builder(
itemCount: 50,
itemBuilder: (context, index) => ListTile(title: Text("Item= ${index + 1}"),),),
)
I think better to use CupertinoScrollbar instead of Scrollbar. CupertinoScrollbar is can touch and scroll to the bottom..
Ex:
CupertinoScrollbar(
child: ListView.builder(...),
Or
Scrollbar(
child: ListView.builder(...),
You can implement this designer scrollbar library :
draggable_scrollbar
alphabet scrolling
OR
You can wrap ListView in Scrollbar widget
Scrollbar(
child: ListView.builder(...),
)
Create a ScrollController variable (ScrollController _scrollController);
Instatiate _scrollController inside initState() or wherever you want, _scrollController = ScrollController();
Add _scrollController variable inside Scrollbar and ListView properties,
controller:_scrollController
Here's the code:
ScrollController _scrollController;
#override
void initState() {
super.initState();
_scrollController = ScrollController();
}
Scrollbar(
isAlwaysShown: true,
controller: _scrollController,
child: ListView(
controller: _scrollController,
)
if you don't want it always shown set to false
thumbVisibility: false,
Scrollbar(
thickness: 10,
isAlwaysShown: true,
child: ListView.builder(
itemCount: _controller().transactonsList.length,
itemBuilder: (context, index) {
return Card(
elevation: 5,
child: Container(
padding: const EdgeInsets.only(bottom: 16),
height: 80,
child: Row(
children: [
SizedBox(width: 10),
amountOfTransaction(index),
SizedBox(width: 16),
dateAndTitleOfTransaction(index),
],
),
),
);
},
),
)
final ScrollController _scroll = ScrollController();
#override
Widget build(BuildContext context) {
(...)
child: ListView.builder(
controller: _scroll,
)
}
If u need to style your scroll bar a bit wrap the ListView in RawScrollbar and use the same scroll controller instance for both widgets
final ScrollController _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
(...)
child: RawScrollbar(
controller: _scrollController,
thumbColor: Colors.redAccent,
radius: const Radius.circular(8),
crossAxisMargin: 2,
child: ListView.builder(
controller: _scrollController,
itemCount: 50,
itemBuilder: (context, index) => ListTile(
title: Text("Item= ${index + 1}"),
),
),
),
}
Scrollbar(
child:ListView.builder(
itemCount:20,
itemBuilder:(c,i) => MyItem(i),
),
),
You have to give itemcount as how many list you have
-----Example: itemCount: items.length,-----