Show full screen image on tap flutter (Hero) - android

I have the image shown using network to local file
Hero(
tag: "customWidget",
child: Container(
width: context.screenWidth / 2,
height: context.screenHeight / 4,
child: NetworkToLocal(
mediaURL: element.payload.uri,
mediaType: 'image',
),
),
),
I want to add functionality that after tapping on the image I can present this image in fullscreen mode. How it can be done with the hero widget?
In the above screenshot, an error occurs highlighting elements when adding
child: NetworkToLocal(
mediaURL: element.payload.uri,
mediaType: 'image',
),

You use the Hero Animation
import 'package:flutter/material.dart';
void main() => runApp(HeroApp());
class HeroApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Transition Demo',
home: MainScreen(),
);
}
}
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Screen'),
),
body: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return DetailScreen();
}));
},
child: Hero(
tag: 'imageHero',
child: Image.network(
'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png',
),
),
),
);
}
}
class DetailScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Center(
child: Hero(
tag: 'imageHero',
child: Image.network(
'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png',
),
),
),
),
);
}
}

Related

Listview.builder Positioning a widget on another widget

I'm trying to make an application like Instagram. But I can't fully view the zoomed picture because of other pictures.
Codes:
List colors = [
Colors.green,
Colors.blue,
Colors.red,
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (_, int index) {
TransformationController controller = TransformationController();
return Container(
child: InteractiveViewer(
transformationController: controller,
onInteractionEnd: (_) {
setState(() {
controller.toScene(Offset.zero);
});
},
child: ColorFiltered(
colorFilter: ColorFilter.mode(colors[index], BlendMode.color),
child: FlutterLogo(),
),
),
height: 200,
width: 200,
);
},
),
);
}
Note: I can't use widgets like stack because of listview.builder
You could either use Visibility widget or Opacity widget to change the visibility of images not being currently panned. Please see the code below I'm using AnimatedOpacity just so that the disappearance of the images does not look too sudden, but you may use Opacity widget as well.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Flutter Demo")),
body: MyStatefulWidget(),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
static List colors = [
Colors.green,
Colors.blue,
Colors.red,
];
final List<double> _opacity = List.generate(colors.length, (index) => 1);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Demo"),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (_, int index) {
final TransformationController controller =
TransformationController();
return AnimatedOpacity(
opacity: _opacity[index],
duration: const Duration(milliseconds: 100),
child: Container(
child: InteractiveViewer(
transformationController: controller,
onInteractionStart: (details) {
for (int i = 0; i < _opacity.length; i++) {
_opacity[i] = i == index ? 1 : 0;
}
setState(() {});
},
onInteractionEnd: (_) {
setState(() {
_opacity.fillRange(0, _opacity.length, 1);
controller.toScene(Offset.zero);
});
},
child: ColorFiltered(
colorFilter: ColorFilter.mode(colors[index], BlendMode.color),
child: const FlutterLogo(),
),
),
height: 200,
width: 200,
),
);
},
),
);
}
}

Black-Screen with the FlatButton in the AppBar

My App contains basically 2 parts -> Appbar (with 1 Button) and BottomNavigationBar (with some buttons that works properly). The problem came when I pressed the Appbar button (goes to a black screen instead of show the "manual_page.dart")
this is the content of the 2 files (the home_page.dart and manual_page.dart):
home_page.dart
import 'package:flutter/material.dart';
import 'package:opening_a_pdf/manual_page.dart';
import 'package:opening_a_pdf/first_page.dart';
import 'package:opening_a_pdf/second_page.dart';
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedPage = 0;
List<Widget> pageList = List<Widget>();
#override
void initState() {
pageList.add(FirstPage());
pageList.add(SecondPage());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFFAFAFA),
appBar: AppBar(
backgroundColor: Colors.black,
title: const Text('Aplicación en Desarrollo'),
actions: <Widget>[
FlatButton(
textColor: Colors.white,
child: Text(
'MANUAL',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Voice()),
);
}
)
],
),
body: IndexedStack(
index: _selectedPage,
children: pageList,
),
bottomNavigationBar: BottomNavigationBar(
// type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.compare_arrows),
title: Text('Conectividad'),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.blur_on),
title: Text('Captura Datos'),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.graphic_eq),
title: Text('Voz'),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.list),
title: Text('Comandos'),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.settings),
title: Text('Ajustes'),
),
],
currentIndex: _selectedPage,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _onItemTapped(int index) {
setState(() {
_selectedPage = index;
});
}
}
manual_page.dart
import 'package:flutter/material.dart';
// ignore: camel_case_types
class Voice extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sección de Órdenes por Voz"),
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Positioned(
bottom: 0,
width: MediaQuery.of(context).size.width,
child: Center(
child: MaterialButton(
onPressed: () {},
color: Colors.red,
),
),
)
],
),
);
}
}
Try to initial the height of container in the second screen before Stack
There are no errors in the code. Works correctly. Maybe the fault is in the main () or in the emulator.
Code in main:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
I executed your code and found no problem with it:
But you can put empty Container() as the child of MaterialButton().
Corrected code:
MaterialButton(
onPressed: () {},
color: Colors.red,
child:Container(),
),

Why is the showModalBottomSheet() function not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Why is this code not working and the bottom sheet is not getting displayed. I've also retried running the code and still it doesn't work. I want to show a modal bottom sheet in flutter on a button click.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
void startInputAction(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (_) {
return Container(
height: 200,
padding: EdgeInsets.all(10),
child: Text("Something"),
);
},
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Error Practice Bottom Sheet"),
backgroundColor: Colors.purple,
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.purple,
padding: EdgeInsets.all(20),
child: Text("Click here"),
onPressed: () => startInputAction(context),
)
],
),
),
),
);
}
}
MateriaApp is at same level that's why you are getting this error.
Following code will solve your issue.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
void startInputAction(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (_) {
return Container(
height: 200,
padding: EdgeInsets.all(10),
child: Text("Something"),
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Error Practice Bottom Sheet"),
backgroundColor: Colors.purple,
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.purple,
padding: EdgeInsets.all(20),
child: Text("Click here"),
onPressed: () => startInputAction(context))
],
),
),
);
}
}
Check out this example in the Flutter docs.
https://api.flutter.dev/flutter/material/showModalBottomSheet.html
Your issue might have to do with you passing the same BuildContext from the Scaffold. You should at least add a Builder widget in the body parameter of Scaffold to get the appropriate context required for this widget.
Here's the code:
class _MyAppState extends State<MyApp> {
void startInputAction(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (_) {
return Container(
height: 200,
padding: EdgeInsets.all(10),
child: Text("Something"),
);
},
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Error Practice Bottom Sheet"),
backgroundColor: Colors.purple,
),
body: Builder(
builder: (context) {
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.purple,
padding: EdgeInsets.all(20),
child: Text("Click here"),
onPressed: () => startInputAction(context),
)
],
),
);
},
),
),
);
}
}
As #Viren suggested, you need to have a MaterialApp in your code.
Check the code below:
import 'package:flutter/material.dart';
void main() => runApp(
// add your material app here
MaterialApp(
home: MyApp(),
),
);
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
void startInputAction(BuildContext context){
showModalBottomSheet(
context: context,
builder: (_){
return Container(
height: 200,
padding: EdgeInsets.all(10),
child: Text("Something"),
);
}
)
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Error Practice Bottom Sheet"),
backgroundColor: Colors.purple,
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.purple,
padding: EdgeInsets.all(20),
child: Text("Click here"),
onPressed: () => startInputAction(context)
)
],
),
),
),
);
}
}

Flutter app not keeping the settings made in the app after reopening the app

I have an app which has two tabs. One of the which is the "SAVED ITEMS" tab. When I save the items (from a different screen of ALL ITEMS LIST) it gets saved and on even switching the tabs works fine. But when I close the app and reopen it, the "SAVED ITEMS" list is empty and I've to select the items again. I've used the AutomaticKeepAliveClientMixin but its not helping. Any idea on how to solve this folks?
My code:
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with AutomaticKeepAliveClientMixin {
#override
Widget build(BuildContext context) {
super.build(context);
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.blue,
accentColor: Colors.white,
),
home: DefaultTabController(
length: 2,
child: Scaffold(
drawer: Drawer(),
backgroundColor: Colors.blueAccent,
appBar: AppBar(
backgroundColor: Colors.blueAccent,
title: Text('AIO'),
bottom: TabBar(
tabs: <Widget>[
Tab(icon: Icon(Icons.search)),
Tab(icon: Icon(Icons.favorite)),
],
),
),
body: TabBarView(
children: <Widget>[
gridView,
SecondPage(),
],
),
),
),
);
}
#override
bool get wantKeepAlive => true;
}
SecondTab code:
Set<int> favorites = {};
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage>
with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
super.build(context);
return Stack(
fit: StackFit.expand,
children: <Widget>[
_getFavoriteList(),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.blue,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditFavorites(),
),
).then((updatedFavorites) {
if (updatedFavorites != null)
// setState(() {
favorites = updatedFavorites;
// });
});
},
),
),
)
],
);
}
Add shared_preferences dependency in pubspec.yaml
Update your main()
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences pref = await SharedPreferences.getInstance();
pref.getStringList("favorites")?.forEach((fav){
favorites.add(int.tryParse(fav));
});
runApp(MyApp());
}
then update your SecondPage
Set<int> favorites = {};
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
Future<void> _upDateFavorites(Set<int> updatedFavorites) async {
print("secong: u$updatedFavorites");
SharedPreferences pref = await SharedPreferences.getInstance();
List<String> favoritesAsString =
updatedFavorites.map((fav) => fav.toString()).toList(); //TODO: Change `favorites` to `updatedFavorites`
print(favoritesAsString);
await pref.setStringList("favorites", favoritesAsString); //TODO: await here to store it completely
favorites = updatedFavorites;
setState(() {});
}
#override
Widget build(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: <Widget>[
_getFavoriteList(),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.blue,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditFavorites(),
),
).then((updatedFavorites) async {
if (updatedFavorites != null)
// setState(() {
_upDateFavorites(updatedFavorites);
// });
});
},
),
),
)
],
);
}
Widget _getFavoriteList() {
if (favorites?.isNotEmpty == true)
return _FavoriteList();
else
return _EmptyFavoriteList();
}
}
Don't forget to import 'package:shared_preferences/shared_preferences.dart'; where you use SharedPreferences
Avoid storing widget in a vaiable, if it needs to be rebuild.
So delete var favGridView = GridView.builder( ....
class _FavoriteList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: favorites.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
print("kkkkkkkkkkk: ${favorites.elementAt(index)}");
return InkWell(
child: Card(
elevation: 10,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10),
child: Container(
child: Image.asset(
'lib/images/${images[favorites.elementAt(index)]}'), //TODO: Change this
// child: SizedBox(child: Text('yashjha'),),
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage('lib/images/${images[index]}'),
// fit: BoxFit.fitWidth,
// alignment: Alignment.topCenter,
// ),
// ),
),
),
Text(nameOfSite[favorites.elementAt(index)]), //TODO: Change This
],
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Text("dsadsa")),
);
},
);
},
);
}
}
I also recommend using actions instead of FloatingButton in _EditFavoritesState. Because the floating button hides last item. which makes it unable to add to favorites
AutomaticKeepAliveClientMixin is used to retain the data when the app is running and you need to retain data while switching between tabs, pages etc.
I would suggest you use SharedPreferences to easily save data to your memory that can be retrieved when the app is started again.
SharedPreferences: https://pub.dev/packages/shared_preferences

How to navigate to another screen from dropdownbutton in Flutter?

I am trying to get a dropdownlist to navigate to another screen once one of the items in the list is pressed via the dropdownbutton. I have tried using Navigator.push straight into onChanged but that doesnt work. And i have tried creating a new button in set state in onChanged. How can I do this because I do not know how?
import 'package:flutter/material.dart';
void main() => runApp(new HomeNavigator());
class HomeNavigator extends StatefulWidget {
#override
_HomeNavigator createState() => _HomeNavigator();
}
class _HomeNavigator extends State<HomeNavigator> {
List<DropdownMenuItem<String>> listMunicipalities = [];
String selected = null;
void loadData() {
listMunicipalities = [];
listMunicipalities.add(new DropdownMenuItem(
child: new Text('Port Moody'),
value: 'Port Moody',
));
listMunicipalities.add(new DropdownMenuItem(
child: new Text('Vancouver Downtown'),
value: 'Vancouver Downtown',
));
listMunicipalities.add(new DropdownMenuItem(
child: new Text('Coquitlam'),
value: 'Coquitlam',
));
}
#override
Widget build(BuildContext context) {
loadData();
Color gradientStart = Colors.deepOrange[700];
Color gradientEnd = Colors.purple[500];
return new MaterialApp(
home: new Scaffold(
body: new Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [gradientEnd, gradientStart],
begin: new FractionalOffset(0.0, 0.5),
end: new FractionalOffset(0.5, 0.0),
stops: [0.0, 1.0]),
),
child: Stack(children: [
Container(
child: Text('',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 30.0,
fontFamily: 'College-Block',
color: Colors.white.withOpacity(0.7))),
alignment: Alignment(0.0, -0.5)),
Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Container(
alignment: Alignment(0.0, 0.05),
child: Container(
width: 350.0,
child: DropdownButtonHideUnderline(
child: new DropdownButton(
value: selected,
items: listMunicipalities,
hint: Text(
'Select City',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white.withOpacity(0.5)),
),
onChanged: (value){
}),
)),
)))
]))));
}
}
class HomePage extends StatefulWidget{
#override
_HomePage createState() => _HomePage();
}
class _HomePage extends State<HomePage> {
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('')
),
);
}
}
you can just use simple switch case over there. refer below example to clear idea.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstScreen(),
));
}
class FirstScreen extends StatelessWidget {
String _selectedGender=null;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Column(
children: <Widget>[
DropdownButton(
value: _selectedGender,
items: _dropDownItem(),
onChanged: (value){
_selectedGender=value;
switch(value){
case "Male" :
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
break;
case "Others" :
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
break;
case "Female" :
Navigator.push(
context,
MaterialPageRoute(builder: (context) => third()),
);
break;
}
},
hint: Text('Select Gender'),
),
],
),
);
}
List<DropdownMenuItem<String>> _dropDownItem() {
List<String> ddl = ["Male", "Female", "Others"];
return ddl.map(
(value) =>
DropdownMenuItem(
value: value,
child: Text(value),
)
).toList();
}
}
class SecondScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
class third extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("tgird Screen"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go back!'),
),
),
);
}
}
for detail go to document https://flutter.io/cookbook/navigation/navigation-basics/
Add below line in your code for Navigation
onChanged: (value){
Navigator.push(context,MaterialPageRoute(builder: (context) =>
YourScreenInstance()),);
}
Navigator.popAndPushNamed(context, "/YourScreenInstance");
Navigator.of(context).pushNamed('/NewPage');

Categories

Resources