Related
I'm running a search filter function which retrieves players from a Floor DB. The functionality works fine and I can see through logs that the new player are returned, however my UI won't update which seems to be from the new list i assign not triggering a re-render.
Can anyone see what's wrong with my code?
import 'package:flutter/material.dart';
import '../database/LocalDatabase.dart';
import '../model/Player.dart';
class Pitch extends StatefulWidget {
const Pitch({super.key});
#override
_Pitch createState() => _Pitch();
}
class _Pitch extends State<Pitch> {
List<Player> playersList = <Player>[];
Offset positionOne = const Offset(100, 100);
Offset positionTwo = const Offset(200, 100);
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(),
color: Colors.white,
child: Stack(
alignment: Alignment.center,
children: [
Image.asset("assets/images/pitch.png"),
Positioned(
left: positionOne.dx,
top: positionOne.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
),
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
onDragEnd: (details) {
setState(() {
positionOne = details.offset;
});
},
),
),
Positioned(
left: positionTwo.dx,
top: positionTwo.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
),
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
onDragEnd: (details) {
setState(() {
positionTwo = details.offset;
});
},
),
)
],
),
);
}
#override
void initState() {
super.initState();
// getPlayers().then((value) {
// debugPrint("playerfromdb: ${value[0].name}");
// });
}
Future<List<Player>> getPlayers() async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final playerDao = database.playerDao;
final players = playerDao.getAllPlayers();
return players;
}
Widget playerImage(String imageUrl) {
return GestureDetector(
onTap: () => showDialog<void>(
context: context,
builder: (BuildContext context) => Dialog(
backgroundColor: Colors.white,
child: SizedBox(
height: 300,
width: 300,
child: Column(
children: [
const SizedBox(height: 24),
Container(
margin: const EdgeInsets.only(left: 16),
height: 48,
child: TextField(
decoration: const InputDecoration.collapsed(
hintText: 'Enter player name',
focusColor: Colors.transparent),
onChanged: (value) {
searchPlayers(value);
},
)),
const SizedBox(height: 24),
SizedBox(
height: 200,
child: ListView.builder(
itemCount: playersList.length,
itemBuilder: (context, index) {
return playerItem(playersList.elementAt(index));
}),
),
],
)))),
child: SizedBox(
width: 48,
height: 48,
child: Image.network(imageUrl),
));
}
Widget playerItem(Player? player) {
return Container(
height: 48,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [BoxShadow(blurRadius: 8)]),
child: Row(
children: [
SizedBox(
height: 36,
width: 36,
child: Image.network(player?.playerImageUrl ?? "")),
const SizedBox(width: 8),
Text(player?.name ?? "")
],
),
);
}
Future<void> searchPlayers(String query) async {
final database = await $FloorLocalDatabase
.databaseBuilder('local_database.db')
.build();
final playerDao = database.playerDao;
// await List<Player> filteredPlayers =
playerDao.searchPlayers(query).then((value) {
setState(() => playersList = value);
debugPrint(value[0].name);
});
}
}
Because your put ListView.builder in Dialog it will create a new stack and a new stack can't rerender from another stack
You can change your code with create a new stateful widget for dialogs
import 'package:flutter/material.dart';
import '../database/LocalDatabase.dart';
import '../model/Player.dart';
class Pitch extends StatefulWidget {
const Pitch({super.key});
#override
_Pitch createState() => _Pitch();
}
class _Pitch extends State<Pitch> {
Offset positionOne = const Offset(100, 100);
Offset positionTwo = const Offset(200, 100);
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(),
color: Colors.white,
child: Stack(
alignment: Alignment.center,
children: [
Image.asset("assets/images/pitch.png"),
Positioned(
left: positionOne.dx,
top: positionOne.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
),
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
onDragEnd: (details) {
setState(() {
positionOne = details.offset;
});
},
),
),
Positioned(
left: positionTwo.dx,
top: positionTwo.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
),
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
onDragEnd: (details) {
setState(() {
positionTwo = details.offset;
});
},
),
)
],
),
);
}
Widget playerImage(String imageUrl) {
return GestureDetector(
onTap: () => showDialog<void>(
context: context,
builder: (BuildContext context) => Dialog(
backgroundColor: Colors.white,
child: const PlayersDialog(),
),
),
child: SizedBox(
width: 48,
height: 48,
child: Image.network(imageUrl),
),
);
}
}
class PlayersDialog extends StatefulWidget {
const PlayersDialog({super.key});
#override
_PlayersDialog createState() => _PlayersDialog();
}
class _PlayersDialog extends State<PlayersDialog> {
List<Player> playersList = <Player>[];
Future<void> searchPlayers(String query) async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final playerDao = database.playerDao;
// await List<Player> filteredPlayers =
playerDao.searchPlayers(query).then((value) {
setState(() => playersList = value);
debugPrint(value[0].name);
});
}
#override
Widget build(BuildContext context) {
return SizedBox(
height: 300,
width: 300,
child: Column(
children: [
const SizedBox(height: 24),
Container(
margin: const EdgeInsets.only(left: 16),
height: 48,
child: TextField(
decoration: const InputDecoration.collapsed(
hintText: 'Enter player name',
focusColor: Colors.transparent),
onChanged: (value) {
searchPlayers(value);
},
)),
const SizedBox(height: 24),
SizedBox(
height: 200,
child: ListView.builder(
itemCount: playersList.length,
itemBuilder: (context, index) {
return playerItem(playersList.elementAt(index));
},
),
),
],
),
);
}
Widget playerItem(Player? player) {
return Container(
height: 48,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [BoxShadow(blurRadius: 8)]),
child: Row(
children: [
SizedBox(
height: 36,
width: 36,
child: Image.network(player?.playerImageUrl ?? "")),
const SizedBox(width: 8),
Text(player?.name ?? "")
],
),
);
}
#override
void initState() {
super.initState();
// getPlayers().then((value) {
// debugPrint("playerfromdb: ${value[0].name}");
// });
}
Future<List<Player>> getPlayers() async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final playerDao = database.playerDao;
final players = playerDao.getAllPlayers();
return players;
}
}
I am trying to create the build method without side effects (without blinking). I solved this problem using StatefulBuilder, but I read that I should rebuild 1000x times without any change or effect.
The Staggered Grid View Builder Widget are rebuilt when the keyboard is opening, or whenever I open again the page, or add/remove an item from it. That's good, normally, but with side effects like you see below. Maybe there is any solution to animate the remove/add functionality, or the infinite reloading and keep the rest of the items in cache. So I need to limit the builder recreate inside Grid View Builder?
On other applications I don't see this ugly "blinking". Where is the problem and how can I solve it? I used Animation Limiter but it's not working for me, neither PrecacheImage, somehow I need to rebuild without blink (first items).
My code:
class VisionBoard extends StatefulWidget {
const VisionBoard({Key? key}) : super(key: key);
#override
_VisionBoardState createState() => _VisionBoardState();
}
class _VisionBoardState extends State<VisionBoard> with SingleTickerProviderStateMixin {
ScreenshotController screenshotController = ScreenshotController();
String saveGoalsButtonText = "SAVE GOALS";
String wallpaperButtonText = "CREATE WALLPAPER";
String saveWallpaperButtonText = "SAVE";
bool createWallpaper = false;
bool isWallpaperCreated = false;
late File imageFile;
late String newImage;
late Uint8List imageRaw;
int noOfImages = 0;
late Uint8List wallpaperBytes;
String title = "My Vision Board";
String goals = "";
late List<String> visions = <String>[];
final TextEditingController _textFieldController = TextEditingController();
final TextEditingController _goalsController = TextEditingController();
static final _formKey = GlobalKey<FormState>();
#override
void initState() {
super.initState();
loadVisionBoardTitleAndImages();
}
void loadVisionBoardTitleAndImages() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
//await prefs.clear();
setState(() {
_textFieldController.text = prefs.getString('titlu') ?? title;
visions = prefs.getStringList('visions') ?? <String>[];
_goalsController.text = prefs.getString('goals') ?? goals;
});
}
void _removeVisions(int index) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
isButtonDisabled=true;
visions.removeAt(index);
prefs.setStringList('visions', visions);
createWallpaper = false;
wallpaperButtonText = "CREATE WALLPAPER";
isWallpaperCreated = false;
});
await CreateWallpaperLayouts().createWallpaper(visions).then((value) {
setState(() {
wallpaperBytes = value;
wallpaper = Image.memory(wallpaperBytes);
precacheImage(wallpaper.image, context);
isButtonDisabled=false;
});
});
}
#override
Widget build(BuildContext context) {
return Sizer(
builder: (context, orientation, deviceType) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
body: AnimationLimiter(
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/background-marmura.jpeg"), fit: BoxFit.cover)),
child: SafeArea(
child: SingleChildScrollView(
child: Container(
margin: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Column(
children: [
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Row(
children: [
Flexible(
child: Text(_textFieldController.text,
style: const TextStyle(
fontWeight: FontWeight.w700,
fontSize: 21,
color: Color(0xff393432),
),
),
),
IconButton(
icon: const Icon(
Icons.edit,
size: 21,
color: Color(0xff393432),
),
onPressed: () {
showAlertDialog(context, setState);
},
)
]);
}
),
const SizedBox(height: 5),
GridView.builder(
clipBehavior: Clip.none,
physics: const ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: SizeConfig.screenWidth!/3,),
itemCount: (visions.length == 12) ? visions.length : visions.length + 1,
itemBuilder: (BuildContext ctx, index) {
if (index < visions.length) {
return AnimationConfiguration.staggeredGrid(
position: index,
duration: const Duration(milliseconds: 1000),
columnCount: 3,
child: ScaleAnimation(
child: FadeInAnimation(
child: OpacityAnimatedWidget.tween(
opacityEnabled: 1, //define start value
opacityDisabled: 0, //and end value
enabled: index < visions.length, //bind with the boolean
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: 25.w,
height: 25.w,
decoration: BoxDecoration(
image: DecorationImage(
image: CleverCloset.imageFromBase64String(visions[index]).image,
fit: BoxFit.fill),
borderRadius: const BorderRadius.all(
Radius.circular(
5.0) // <--- border radius here
),
),
),
Positioned(
top:0,
right:0,
child: ClipOval(
child: InkWell(
onTap: () {
_removeVisions(index);
},
child: Container(
padding: const EdgeInsets.all(5),
color: Colors.white,
child:
const Icon(
Icons.delete,
size: 16,
color: Color(0xff393432)),
),
),
),
),
],
clipBehavior: Clip.none,
),
),
),
),
);
}
else if(index<12){
return InkWell(
onTap: () {
_openGallery(context);
},
child:
Stack(
alignment: Alignment.center,
children:[
Container(
width: 25.w,
height: 25.w,
decoration:
BoxDecoration(
border: Border.all(color: const Color(0xff393432)),
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
),
child:
const Icon(
Icons.add,
size: 25,
color: Color(0xff393432),
)
),
],
),
);
}
else {
return Container(color: Colors.red);
}
}
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text("You can add up to 12 pictures.",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.italic,
),),
],
),
const SizedBox(height: 10),
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column (
children: [
if(visions.isNotEmpty && visions.length>1 && !isWallpaperCreated) Row(
children: [
SizedBox(
width: 50.w,
child: OpacityAnimatedWidget.tween(
opacityEnabled: 1, //define start value
opacityDisabled: 0, //and end value)
enabled: !isWallpaperCreated &&
visions.isNotEmpty && visions.length > 1,
child: OutlinedButton(
onPressed: visions.isNotEmpty &&
visions.length > 1 ? () async{
setState(() {
wallpaperButtonText = "CREATING...";
//_createWallpaper();
});
wallpaperBytes = await CreateWallpaperLayouts().createWallpaper(visions);
setState(() {
noOfImages = visions.length;
isWallpaperCreated = true;
createWallpaper = true;
});
//Navigator.pushReplacementNamed(context, '/masterclasses');
} : null,
style: OutlinedButton.styleFrom(
primary: const Color(0xffE4BCB4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
18.0),
),
side: const BorderSide(
width: 3, color: Color(0xffE4BCB4)),
),
child: Text(
wallpaperButtonText,
style: const TextStyle(
color: Color(0xff393432),
fontSize: 14,
fontWeight: FontWeight.w700,
)
),
),
),
),
],
),
const SizedBox(height:40),
if(createWallpaper==true) OpacityAnimatedWidget.tween(
opacityEnabled: 1, //define start value
opacityDisabled: 0, //and end value
enabled: createWallpaper, //bind with the boolean
child: Row(
children: const [
Flexible(
child: Text("Wallpaper",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 21,
color: Color(0xff393432),
),
),
),
],
),
),
if(createWallpaper==true) const SizedBox(height:15),
if(createWallpaper==true)
OpacityAnimatedWidget.tween(
opacityEnabled: 1, //define start value
opacityDisabled: 0, //and end value
enabled: createWallpaper,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children:[ Container(
width: 50.w,//double.infinity,
height: 50.h,//SizeConfig.screenHeight,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.memory(wallpaperBytes).image,
fit: BoxFit.fill,
)
),
//child: CreateWallpaperLayouts().createWallpaper(visions),
),],
),
),
if(createWallpaper==true) const SizedBox(height:10),
if(createWallpaper==true) StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return OpacityAnimatedWidget.tween(
opacityEnabled: 1, //define start value
opacityDisabled: 0, //and end value
enabled: createWallpaper,
child: Row(
children: [
SizedBox(
width: 50.w,
child: OutlinedButton(
onPressed: () {
_saveWallpaper(wallpaperBytes);
setState(() {
saveWallpaperButtonText = "SAVED!";
});
Future.delayed(const Duration(milliseconds: 1300), () {
setState(() {
saveWallpaperButtonText = "SAVE";
});
});
//Navigator.pushReplacementNamed(context, '/masterclasses');
},
style: OutlinedButton.styleFrom(
primary: const Color(0xffE4BCB4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
side: const BorderSide(width: 3, color: Color(0xffE4BCB4)),
),
child: Text(
saveWallpaperButtonText,
style: const TextStyle(
color: Color(0xff393432),
fontSize: 14,
fontWeight: FontWeight.w700,
)
),
),
),
const SizedBox(width: 10),
],
),
);
}
),
if(createWallpaper==true) const SizedBox(height:50),
Row(
children: const [
Flexible(
child: Text("Goals & Affirmations",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 21,
color: Color(0xff393432),
),
),
),
],
),
],
);
}
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Text("Add goals and affirmations.",
style: TextStyle(
fontSize: 15,
),),
],
),
const SizedBox(height: 10),
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
children: [
Card(
elevation: 0,
color: const Color(0xffEFEFEF),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
key: _formKey,
controller: _goalsController,
maxLines: 8,
decoration: const InputDecoration(border: InputBorder.none),
),
)
),
const SizedBox(height: 10),
Row(
children: [
Container(
width: 50.w,
margin: const EdgeInsets.fromLTRB(0, 0, 0, 40),
child: OutlinedButton(
onPressed: () async{
setState(() {
saveGoalsButtonText = "SAVED!";
});
Future.delayed(const Duration(seconds: 1), () {
setState(() {
saveGoalsButtonText = "SAVE GOALS";
});
});
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
goals = _goalsController.text;
prefs.setString('goals', goals);
});
//Navigator.pushReplacementNamed(context, '/masterclasses');
},
style: OutlinedButton.styleFrom(
primary: const Color(0xffE4BCB4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
side: const BorderSide(width: 3, color: Color(0xffE4BCB4)),
),
child: Text(
saveGoalsButtonText,
style: const TextStyle(
color: Color(0xff393432),
fontSize: 14,
fontWeight: FontWeight.w700,
)
),
),
),
],
),
],
);
}
),
],
),
),
),
),
),
),
),
);
}
);
}
}
I'm developing a pdf app with flutter. The thing I want to say is how I should do with pdf's thumbnails. I mean when the users open the application the second time after installing, I want to show the screen of pdf's thumbnails instantly not loading again. How should I do? Save images locally or any solution?. The code is below.
import 'dart:io';
import 'dart:typed_data';
import 'package:card_swiper/card_swiper.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'constant.dart';
import 'file_picker.dart';
import 'icon_button.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:pdf_image_renderer/pdf_image_renderer.dart';
import 'package:path_provider_extention/path_provider_extention.dart';
import 'file_manager.dart';
import 'save_screen.dart';
import 'sorting.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<FileSystemEntity> pdffile;
List<Uint8List> pdfimage = [];
BannerAd bannerAds;
AppOpenAd openAd;
bool isAdsload = false;
void initState() {
super.initState();
initBannerAds();
loadAd();
getFile();
}
void dispose() {
super.dispose();
bannerAds.dispose;
}
loadAd() {
AppOpenAd.load(
adUnitId: 'ca-app-pub-4233045876357680/8169845508',
request: const AdRequest(),
adLoadCallback: AppOpenAdLoadCallback(onAdLoaded: (ad) {
print('ad is loaded');
openAd = ad;
openAd.show();
}, onAdFailedToLoad: (error) {
print('ad failed to load $error');
}),
orientation: AppOpenAd.orientationPortrait);
}
initBannerAds() {
bannerAds = BannerAd(
size: AdSize.banner,
adUnitId:'ca-app-pub-4233045876357680/9259518166',
listener: BannerAdListener(
onAdLoaded: (ad) {
setState(() {
isAdsload = true;
});
},
onAdFailedToLoad: (ad, error) {
print(error.toString());
},
),
request: AdRequest(),
);
bannerAds.load();
}
getFile() async {
await Permission.storage.request();
List<StorageInfo> storageInfo = await PathProviderEx.getStorageInfo();
var root = storageInfo[0].rootDir; //storageInfo[1] for SD card, geting the root
// directory
var fm = FileManager(root: Directory(root)); //
pdffile = await fm.filesTree(
excludedPaths: [
"/storage/emulated/0/Android"
],
extensions: [
"pdf",
],
sortedBy: FlutterFileUtilsSorting.Alpha,
//optional, to filter files, list only pdf files
);
print(pdffile);
for (int index = 0; index < pdffile.length; index++) {
final document = await PdfImageRendererPdf(path: pdffile[index].path);
await document.open();
// open a page from the pdf document using the page index
await document.openPage(pageIndex: 0);
// get the render size after the page is loaded
final size = await document.getPageSize(pageIndex: 0);
// get the actual image of the page
final pageImage = await document.renderPage(
pageIndex: 0,
x: 0,
y: 0,
width: size.width,
// you can pass a custom size here to crop the image
height: size.height,
// you can pass a custom size here to crop the image
scale: 1,
// increase the scale for better quality (e.g. for zooming)
background: Colors.white,
);
await document.closePage(pageIndex: 0);
document.close();
setState(() {
pdfimage.add(pageImage);
});
print(pdfimage);
}
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
drawer: Drawer(
child: ListView(
padding: EdgeInsets.all(5),
children: [
DrawerHeader(decoration: BoxDecoration(color: Colors.cyan), child: Text("Jensen
Pdf Viewer", style: fontStyle)),
ListTile(
leading: iconButton(icons: Icons.folder_open, onPress: () {}),
title: Text('Pick Files', style: styles),
onTap: () {
FilePickers().PickFile();
}),
ListTile(
leading: iconButton(icons: Icons.bug_report, onPress: () {}),
title: Text('Report Bug', style: styles),
onTap: () async {
await Future.delayed(const Duration(seconds: 1), () {
Get.toNamed('fourth');
});
})
],
)),
appBar: AppBar(
title: Text('Jensen Pdf Viewer', style: fontStyle),
),
body: pdfimage != null
? Container(
child: Column(
children: [
Expanded(
child: Container(
margin: EdgeInsets.only(left: 3, right: 3),
decoration: BoxDecoration(
color: Color(0xFFA9C9CC),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(4, 3), // changes position of shadow
),
],
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40),
bottomRight: Radius.circular(40),
)),
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(4),
child: Swiper(
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () async {
await Future.delayed(const Duration(milliseconds: 200), () {
Get.toNamed('second', arguments: '${pdffile[index].path}');
});
},
child: Card(
elevation: 20,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Container(
padding: EdgeInsets.all(10),
width: MediaQuery.of(context).size.width * 0.8,
height: MediaQuery.of(context).size.height * 0.8,
decoration: BoxDecoration(
image: DecorationImage(image: MemoryImage(pdfimage[index]), fit: BoxFit.fill),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
),
));
},
itemCount: pdfimage.length,
itemWidth: 250.0,
layout: SwiperLayout.STACK,
))),
),
SizedBox(height: 10),
Container(
child: Text("Categories", style: fontStyle),
),
SizedBox(height: 10),
Expanded(
child: ListView.builder(
itemCount: pdfimage.length,
itemBuilder: (context, index) {
String fileName = pdffile[index].path.split('/').last;
return Card(
color: context.theme.scaffoldBackgroundColor,
elevation: 10,
margin: EdgeInsets.all(5),
child: Container(
margin: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
InkWell(
onTap: () async {
await Future.delayed(const Duration(milliseconds: 200), () {
Get.toNamed('second', arguments: '${pdffile[index].path}');
});
},
child: Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.25,
maxHeight: MediaQuery.of(context).size.width * 0.21,
),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
borderRadius: BorderRadius.all(Radius.circular(10)),
image: DecorationImage(image: MemoryImage(pdfimage[index]), fit: BoxFit.fill),
))),
SizedBox(width: 10),
Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
margin: EdgeInsets.only(left: 20),
child: Text(
fileName,
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
style: styles,
maxLines: 1,
)),
),
iconButton(
icons: Icons.forward,
onPress: () async {
await Future.delayed(const Duration(milliseconds: 200), () {
Get.toNamed('second', arguments: '${pdffile[index].path}');
});
}),
],
),
));
// }))
}),
),
],
),
)
: Container(child: Center(child: Container(margin: EdgeInsets.all(20), child: Text("There is no Pdf in Internal Storage. Tap Menu Icon", style: fontStyle)))),
bottomNavigationBar: isAdsload
? Container(
width: bannerAds.size.width.toDouble(),
height: bannerAds.size.height.toDouble(),
child: AdWidget(
ad: bannerAds,
),
)
: null,
),
);
}
}
I'm developing a package to show thumbnails for PDF files.
pdf_thumbnail
You can simply use it as a widget.
PdfThumbnail.fromFile(pdfFile)
I have a ListView.builder inside a PageView.builder. When ListView elements reach the end of the scroll, colors of items still appear out of the scroll. I may not have explained myself, I added images of it.
This is the initial state
When I start scrolling it becomes like that
I also add my codes. What is the reason beyond it?
class NewBookingPage extends StatefulWidget {
const NewBookingPage({Key? key}) : super(key: key);
#override
_NewBookingPageState createState() => _NewBookingPageState();
}
class _NewBookingPageState extends State<NewBookingPage> with SingleTickerProviderStateMixin {
late final AnimationController animationController;
final pageController = PageController();
#override
void initState() {
super.initState();
animationController = AnimationController(vsync: this, value: 0.25);
animationController.addListener(() {
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Padding(
padding: EdgeInsets.fromLTRB(16, 0, 0, 0),
child: IconButton(
onPressed: () {
if (pageController.page != 0) {
animationController.animateTo(
animationController.value - 0.25,
curve: Curves.easeOut,
duration: Duration(milliseconds: 300),
);
pageController.previousPage(
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
);
} else {
Navigator.of(context).pop();
}
},
icon: SvgPicture.asset(
"assets/icons/arrow_back.svg",
color: text900,
),
),
),
title: Text(
"Reservation",
style: Theme.of(context).appBarTheme.titleTextStyle,
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: LinearProgressIndicator(
color: primary500,
backgroundColor: text300,
value: animationController.value,
),
),
),
SizedBox(height: 24),
Expanded(
child: PageView.custom(
controller: pageController,
scrollBehavior: NoGlowingScrollBehavior(),
physics: NeverScrollableScrollPhysics(),
childrenDelegate: SliverChildListDelegate.fixed(
[DateTab(), HoursTab()],
),
),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Color(0xFF204C3C0A).withOpacity(0.04),
offset: Offset(0, -4),
spreadRadius: 2,
blurRadius: 12,
),
],
),
child: Padding(
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
child: ElevatedButton(
onPressed: () async {
animationController.animateTo(
0.5,
curve: Curves.easeOut,
duration: Duration(milliseconds: 300),
);
pageController.nextPage(
duration: Duration(milliseconds: 300),
curve: Curves.easeOut,
);
},
child: Text("Next"),
),
),
),
],
),
);
}
}
class HoursTab extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Choose hour",
style: Theme.of(context).textTheme.headline3,
),
SizedBox(height: 16),
Expanded(
child: ScrollConfiguration(
behavior: NoGlowingScrollBehavior(),
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
var isFull = index % 2 == 0;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: text200, width: 1),
borderRadius: BorderRadius.circular(8),
),
child: ListTile(
enabled: !isFull,
tileColor: isFull ? text100 : null,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
leading: Radio<bool>(
activeColor: primary500,
value: index == 3,
groupValue: true,
onChanged: (a) {},
),
horizontalTitleGap: 0,
contentPadding: EdgeInsets.only(right: 20),
trailing: isFull
? Chip(
labelStyle: Theme.of(context).textTheme.subtitle2?.copyWith(color: text700),
label: Text("Full"),
backgroundColor: text200,
)
: null,
title: Text(
"15:00 - 16:00",
style: Theme.of(context).textTheme.bodyText1?.copyWith(color: isFull ? text500 : text900),
),
),
),
);
},
),
),
)
],
),
);
}
}
class NoGlowingScrollBehavior extends ScrollBehavior {
#override
Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
return child;
}
}
The problem seems to be a bug caused by ListTile Color. so instead of tileColor use the color property of BoxDecoration:
itemBuilder: (context, index) {
var isFull = index % 2 == 0;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade200, width: 1),
borderRadius: BorderRadius.circular(8),
color: isFull ? Colors.grey.shade100 : null // add it here
),
child: ListTile(
enabled: !isFull,
// tileColor: isFull ? Colors.grey.shade100 : null, remove this line
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
leading: Radio<bool>(
value: index == 3,
groupValue: true,
onChanged: (a) {},
),
horizontalTitleGap: 0,
contentPadding: EdgeInsets.only(right: 20),
trailing: isFull
? Chip(
labelStyle: Theme.of(context).textTheme.subtitle2,
label: Text("Full"),
)
: null,
title: Text(
"15:00 - 16:00",
style: Theme.of(context).textTheme.bodyText1?.copyWith(color: isFull ? Colors.grey.shade500 : Colors.grey.shade900),
),
),
),
);
}
I added padding for transparent outside. But fixed height. How to change it?
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
Is it possible to remove above this line and flexible(center)?
I am expected like this flexible height alert. click here
onPressed: () {
showGeneralDialog(
context: context,
barrierColor: Palette.black.withOpacity(.3),
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 400),
pageBuilder: (_, __, ___) {
return ChangePropertyPage(
propertyModel: propertyModel);
},
);
},
change Property Page
class ChangePropertyPage extends StatelessWidget {
final List<PropertyModel> propertyModel;
const ChangePropertyPage({Key key, this.propertyModel}) : super(key: key);
#override
Widget build(BuildContext context) {
final double width = CustomMediaQuery.width(context);
return Padding(
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
child: Material(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
PropertyListTileWidget(
mainTitle: 'USER\'S Name', subTitle: 'USER\'S Email'),
VerticalSpacing(height: 10),
CustomLine(
height: 1,
width: (width - 40) - 20,
color: Palette.black.withOpacity(.2),
),
Expanded(
child: ListView.builder(
itemCount: propertyModel.length,//now length is 1
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: ()async{
},
child: PropertyListTileWidget(
mainTitle: '${propertyModel[index].propertyName}',
subTitle: '${propertyModel[index].ownerUId}'),
);
}),
)
],
),
),
),
);
}
}
if you are expecting this:
then
full code:
import 'package:flutter/material.dart';
class CustomDialogBox extends StatefulWidget {
#override
_CustomDialogBoxState createState() => _CustomDialogBoxState();
}
class _CustomDialogBoxState extends State<CustomDialogBox> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Custom Dialog Box"),
centerTitle: true,
),
body:Center(
child:FlatButton(
color: Colors.blue,
onPressed: (){
showDialog(
context: (context),
child: ShowCustomDialogBox()
);
},
child: Text("Show Dialog")
)
) ,
);
}
}
class ShowCustomDialogBox extends StatefulWidget {
#override
State<StatefulWidget> createState() => ShowCustomDialogBoxState();
}
class ShowCustomDialogBoxState extends State<ShowCustomDialogBox>with SingleTickerProviderStateMixin {
AnimationController controller;
Animation<double> scaleAnimation;
#override
void initState() {
super.initState();
controller = AnimationController(vsync: this, duration: Duration(milliseconds: 450));
scaleAnimation =CurvedAnimation(parent: controller, curve: Curves.decelerate);
controller.addListener(() {
setState(() {});
});
controller.forward();
}
#override
Widget build(BuildContext context) {
return Center(
child: Material(
color: Colors.transparent,
child: ScaleTransition(
scale: scaleAnimation,
child: Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(8.0),
height: MediaQuery.of(context).size.height/2.5, //Change height of dialog box.
width: MediaQuery.of(context).size.width,
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0))),
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index){
return Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text((index+1).toString(),style: TextStyle(color:Colors.blue,fontSize:40),),
Divider()
],
);
}
)
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 10.0, top: 0.0,),
child: ButtonTheme(
height: 35.0,
minWidth: MediaQuery.of(context).size.width/3.5,
child: RaisedButton(
color: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
splashColor: Colors.white.withAlpha(40),
child: Text(
'Next',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 13.0),
),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
)
)
),
],
)
),
),
),
);
}
}