Flutter: Where I can add Text() - flutter

I want to tap on the screen, and change background color to random color. It works fine, but I want to add Text on the center of screen, help me please.
Maybe someone have ideas, Thank you!
I try to add multiple child to AnimatedContainer.
Tried to add text in GestureDetector, but it doesn't work correctly
TopScreen.dart
import 'package:flutter/material.dart';
class TopScreen extends StatefulWidget {
final Widget child; //child widget
TopScreen({this.child});
#override
State createState() => _TopScreenState();
static _TopScreenState of (BuildContext context) {
assert(context != null);
final _TopScreenState result = context.findAncestorStateOfType();
return result;
}
}
class _TopScreenState extends State<TopScreen> {
Color _color = Colors.white;
#override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedContainer(
child: widget.child,
color: _color,
duration: Duration(milliseconds: 500),
),
);
}
void setColor(Color color) {
this._color = color;
}
}
main.dart
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:solidsoftwaretest/TopScreen.dart';
void main() => runApp(MaterialApp(home: TopScreen(child: MainScreen())));
class MainScreen extends StatefulWidget {
#override
State createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
TopScreen.of(context).setColor(Colors.primaries[Random().nextInt(Colors.primaries.length)]);
TopScreen.of(context).setState(() {});
},
);
} //build
}
UPD: if I add Child (Text) to GestureDetector - gestureDetector works only on Text.
class _MainScreenState extends State<MainScreen> {
#override
Widget build(BuildContext context) {
return GestureDetector(
child: Center(
child: Text('Hey there!')
),
onTap: () {
TopScreen.of(context).setColor(Colors.primaries[Random().nextInt(Colors.primaries.length)]);
TopScreen.of(context).setState(() {});
}
);
} //build
}

You can add Text widget inside a Container & wrap it further in GestureDetector. In order to make GestureDetector work on the whole area, give the Container a transparent color as follows:
return GestureDetector(
onTap: () {
TopScreen.of(context).setColor(Colors.primaries[Random().nextInt(Colors.primaries.length)]);
TopScreen.of(context).setState(() {});
},
child: Container(
color: Colors.transparent,
alignment: Alignment.center,
child: Text('Hey there'),
),
);
Hope, it will help

You should be able to put a Column inside your AnimatedContainer. The Column will hold multiple Widgets.
I've updated the code to show the full example.
ScaffoldColorCenterText60597839(
child: Text('Bananas'),
)
class ScaffoldColorCenterText60597839 extends StatefulWidget {
final Widget child;
ScaffoldColorCenterText60597839({
this.child
});
#override
_ScaffoldColorCenterText60597839State createState() => _ScaffoldColorCenterText60597839State();
}
class _ScaffoldColorCenterText60597839State extends State<ScaffoldColorCenterText60597839> {
Color _color = Colors.white;
#override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedContainer(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
widget.child,
Text('A text widget')
],
)
),
color: _color,
duration: Duration(milliseconds: 500),
),
);
}
}

Related

Is there way to show pages with transparent background using Navigator 2.0 api in Flutter?

I'm trying to get full control on routes using Navigator 2.0 api. I want some pages to have transparent background (e.g. dialogs and bottom sheets) but still be represented as pages in Navigator. Naive way - just add a MaterialPage with partially transparent widget - doesn't work, lower page becomes black after transition animation.
Minimal code for reproduction is below. I expect to see red square (UpperPage) on green background (RootPage) but background becomes black. Navigator 1.0 api, like showGeneralDialog, works fine with this case, but I don't want to mix declarative and imperative way since it's hard to control from single source of truth like bloc or Provider. Is there any way to achieve this behaviour with pages api only?
class RootPage extends StatelessWidget {
const RootPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox.expand(
child: Container(color: Colors.green),
);
}
}
class UpperPage extends StatelessWidget {
const UpperPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
);
}
}
class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier {
#override
Widget build(BuildContext context) {
return Navigator(
pages: const [
MaterialPage(child: RootPage()),
MaterialPage(child: UpperPage()),
],
onPopPage: (route, result) {
return route.didPop(result);
},
);
}
...
}
import 'package:flutter/material.dart';
class TutorialOverlay extends ModalRoute<void> {
#override
Duration get transitionDuration => Duration(milliseconds: 500);
#override
bool get opaque => false;
#override
bool get barrierDismissible => false;
#override
Color get barrierColor => Colors.black.withOpacity(0.5);
#override
String get barrierLabel => null;
#override
bool get maintainState => true;
#override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
// This makes sure that text and other content follows the material style
return Material(
type: MaterialType.transparency,
// make sure that the overlay content is not cut off
child: SafeArea(
child: _buildOverlayContent(context),
),
);
}
Widget _buildOverlayContent(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'This is a nice overlay',
style: TextStyle(color: Colors.white, fontSize: 30.0),
),
RaisedButton(
onPressed: () => Navigator.pop(context),
child: Text('Dismiss'),
)
],
),
);
}
#override
Widget buildTransitions(
BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
// You can add your own animations for the overlay content
return FadeTransition(
opacity: animation,
child: ScaleTransition(
scale: animation,
child: child,
),
);
}
}
// Example application:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Playground',
home: TestPage(),
);
}
}
class TestPage extends StatelessWidget {
void _showOverlay(BuildContext context) {
Navigator.of(context).push(TutorialOverlay());
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Test')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Center(
child: RaisedButton(
onPressed: () => _showOverlay(context),
child: Text('Show Overlay'),
),
),
),
);
}
}

How to change scaffold colour randomly on clicking separate file's gesturdetector button

I have made two files... one is main.dart and other is homescreen.dart. Homescreen is for scaffold body which is created separately. Now there is a button in home screen for changing colour of scaffold. How to do this?
The main purpose is to know access scaffold from other stateful widget class file...
main.dart
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(child: Scaffold(body: HomeScreen(),)),
);
}
}
homescreen.dart
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
//My query is to PLACE CODE HERE TO CHANGE SCAFFOLD COLOR ON CLICKING
},
child: Center(
child: Container(
color: Colors.red,
height: 60,
width: 200,
child: Center(child: Text('Change Color',)),
),
),
);
}
}
Try this:
main.dart
import 'package:flutter/material.dart';
import 'home.dart';
import 'dart:math' as math;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Color _color = Colors.white;
void changeColor(){
setState(() {
_color = Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(child: Scaffold(
backgroundColor: _color,
body: HomeScreen(changeColor: changeColor,),)),
);
}
}
home.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
VoidCallback? changeColor;
HomeScreen({Key? key, this.changeColor}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: changeColor,
child: Center(
child: Container(
color: Colors.red,
height: 60,
width: 200,
child: const Center(
child: Text(
'Change Color',
),
),
),
),
);
}
}
You can do it like this :
/// EDIT :
I edit it to get the Color random
import 'dart:math' as math;
class _MyAppState extends State<MyApp> {
Color _newColor = Colors.white; // variable with the color you want to change
final rnd = math.Random(); // random
Color getRandomColor() =>
Color(rnd.nextInt(0xffffffff)); // little function to get the color random
void _changeNewColor() { // function that you are going to send to yout HomeScreen
setState(() {
_newColor = getRandomColor();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: HomeScreen(change: _changeNewColor), // function
backgroundColor: _newColor, // here the variable
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({
Key? key,
this.change,
}) : super(key: key);
final Function()? change; // instance and get the funct
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: change,
child: Center(
child: Container(
color: Colors.red,
height: 60,
width: 200,
child: const Center(
child: Text(
'Change Color',
)),
),
),
);
}
}

How to make soft keyboard appearance animation smooth?

I have 2 examples with code and GIF.
Problem with first - it is not working with appropriate height.
Problem with second - when soft keyboard appears it is not animated.
What is the appropriate way to make soft keyboard appearance on the screen smooth and clean, when you have to move some objects, according to new screen height?
GIFS:
Code first:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Example()));
}
class Example extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Spacer(),
Container(
color: Colors.red,
child: TextField(),
),
],
),
);
}
}
Code second:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() {
runApp(MaterialApp(home: Example()));
}
class Example extends StatefulWidget {
#override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
double height = 0;
FocusNode node = FocusNode();
#override
void initState() {
super.initState();
node.addListener(() {
if (height == 0) {
height = 320;
} else {
height = 0;
}
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
Spacer(),
Container(
color: Colors.red,
child: TextField(
focusNode: node,
),
),
AnimatedContainer(
duration: Duration(milliseconds: 370),
curve: Curves.ease,
height: height,
),
],
),
);
}
}

Flutter Web Mouse Region Widget Triggering

I am trying to get this result with Flutter;
I am having this behaviour;
Code;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:html' as html;
class OverlayAnimatedGridElement extends StatefulWidget {
OverlayAnimatedGridElement(this.imagepath, this.postDetail, this.postTitle);
final String imagepath;
final String postTitle;
final String postDetail;
#override
_OverlayAnimatedGridElementState createState() =>
_OverlayAnimatedGridElementState();
}
class _OverlayAnimatedGridElementState extends State<OverlayAnimatedGridElement>
with TickerProviderStateMixin {
AnimationController _controller;
Animation<double> _opacityTween;
bool isHovered = false;
#override
void initState() {
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
_opacityTween = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeInOutCirc));
super.initState();
}
hoverActivation(hoverState) {
bool hoverState;
isHovered = hoverState;
if (isHovered = true) {
_controller.forward();
} else if (isHovered = false) {
_controller.reset();
}
print("activated");
}
#override
Widget build(BuildContext context) {
_opacityTween.addListener(() {
setState(() {
print(_opacityTween.value);
});
});
return MouseRegion(
onHover: hoverActivation(true),
child: Container(
constraints: BoxConstraints(maxHeight: 360, maxWidth: 640),
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Image(image: AssetImage("${widget.imagepath}")),
Opacity(
opacity: _opacityTween.value,
child: Container(
color: Color.fromRGBO(128, 128, 128, 0.5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("${widget.postDetail}"),
Text("${widget.postTitle}")
],
),
],
),
),
),
],
),
),
);
}
}
A standalone widget works okay but when I put it into gridview or pageview it automatically reads it mouse entered when I scroll into it.
I tried to use other widgets like Inkwell, Listener and others. No solution. Can someone guide me if there is better solution?
How Can I solve this?
edit:
Now having this problem. MouseRegion causes multiple controller.forwards
I am Created an Example ... please Try this,
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Todos',
theme: new ThemeData(primarySwatch: Colors.deepOrange),
home: MyHome(),
);
}
}
class MyHome extends StatelessWidget{
#override
Widget build(BuildContext context) {
return GridView.count(crossAxisCount: 3,
children: List.generate(10, (index) {
return OverlayAnimatedGridElement("https://picsum.photos/300/200");
}
));
}
}
class OverlayAnimatedGridElement extends StatefulWidget {
OverlayAnimatedGridElement(this.imagepath);
final String imagepath;
// final String postTitle;
// final String postDetail;
#override
_OverlayAnimatedGridElementState createState() =>
_OverlayAnimatedGridElementState();
}
class _OverlayAnimatedGridElementState extends State<OverlayAnimatedGridElement>
with TickerProviderStateMixin {
bool isHovered = false;
#override
void initState() {
super.initState();
}
hoverActivation(hoverState) {
setState(() {
isHovered = hoverState;
});
print("activated" + hoverState.toString());
}
#override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.red,
height: 200,
width: 300,
child: Stack(
children: [
Image.network(widget.imagepath),
MouseRegion(
onEnter: (event){
hoverActivation(true);
},
onExit: (event){
hoverActivation(false);
},
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
color: Colors.black.withOpacity(isHovered ? 0.5 : 0),
),
)
],
),
),
);
}
}
I solved my second problem by just moving addListener method to initState. Previously it was inside widget itself which was causing adding listeners in every rebuild and causing multiple rebuilds for each listener, I guess.

change variables with setState in Flutter

I have an issue with setState() in Flutter. I just write a simple program that have a container and a button , the color of container is global variable mycolor and i change it in on_pressed function of button with setState but its doesn't change.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: _Home(),));
Color bgColor = Colors.red;
class _Home extends StatefulWidget {
#override
__HomeState createState() => __HomeState();
}
class __HomeState extends State<_Home> {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
//First Widget
Container(
width: 200,
height: 200,
color: bgColor,
),
//Second Widget
SecondWidget()
],
);
}
}
class SecondWidget extends StatefulWidget {
#override
_SecondWidgetState createState() => _SecondWidgetState();
}
class _SecondWidgetState extends State<SecondWidget> {
#override
Widget build(BuildContext context) {
return RaisedButton(
child: Text("Change color"),
onPressed: (){
setState(() {
bgColor = Colors.green;
});
},
);
}
}
image of my program
You are calling setState in _SecondWidgetState not in __HomeState, so only SecondWidget redraws and it does not depend on bgColor.
What you can do here: the easiest option would be to pass a callback function from __HomeState to SecondWidget, which will call setState inside __HomeState.
Example code:
class __HomeState extends State<_Home> {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
//First Widget
Container(
width: 200,
height: 200,
color: bgColor,
),
//Second Widget
SecondWidget(callSetState);
],
);
}
void callSetState() {
setState((){}); // it can be called without parameters. It will redraw based on changes done in _SecondWidgetState
}
}
class SecondWidget extends StatefulWidget {
final Function onClick;
SecondWidget(this.onClick);
#override
_SecondWidgetState createState() => _SecondWidgetState();
}
class _SecondWidgetState extends State<SecondWidget> {
#override
Widget build(BuildContext context) {
return RaisedButton(
child: Text("Change color"),
onPressed: (){
bgColor = Colors.green;
widget.onClick();
},
);
}
}
This is simple solution for two widgets, but you will have problems if you will try to manage state on larger scale. I recommend you to read articles about state management in flutter. This one can be a good start.
You need to pass that variable to your sibling widget SecondWidget().
First you declare it on your SecondWidget like this:
class SecondWidget extends StatefulWidget {
Color backgroundColor;
SecondWidget({Key key, #required this.backgroundColor}) : super(key: key);
#override
_SecondWidgetState createState() => _SecondWidgetState();
}
You need to pass that color from _HomeState to SecondWidget, you do it like this:
class __HomeState extends State<_Home> {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
//First Widget
Container(
width: 200,
height: 200,
color: bgColor,
),
//Second Widget
SecondWidget(backgroundColor: bgColor) // Here you pass that color
],
);
}
}
Then on your SecondWidgetState, you can update your other widget color using setState(), like this:
setState(() {
widget.backgroundColor = Colors.blue;
});
Hope this helps fix your issue.