Is there a way to achieve popup menu on header which expands on hover and closes on mouse exit
You can use the MouseRegion widget to determine the hover changes. Popup in the sense, could you explain what exactly you want to achieve? Some would be possible some wouldn't be. I hope you just need to expand the menu button on hover, which you can use an AnimatedContainer for the menu, warp it with MouseRegion widget, declare a variable that says the width, and height of AnimatedContainer widget. MouseRegion has onEnter and onExit functions, onEnter is when the container has hovered and onExit is when the user stops hovering the container. During onEnter you can increase the width and height and during onExit, you can set it to default.
double _animatedContainerHeight = 30; //Default height
double _animatedContainerWidth = 30; //Default width
MouseRegion(
onEnter: (value) {
setState(() {
_animatedContainerHeight = 50; //OnHover height
_animatedContainerWidth = 50; //OnHover width
});
},
onExit: (value) { setState(() {
_animatedContainerHeight = 30; //Return back to normal height
_animatedContainerWidth = 30; //Return back to normal width
});
},
cursor: SystemMouseCursors.click, //Cursor type on hover
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
height: _animatedContainerHeight, //Animation height control
width: _animatedContainerWidth, //Animation width control
),
)
Related
So the basic scaffold in flutter has appbar, body and bottom bar.
in my bottom navigation bar I have 3 items:
Page 1 (Editor Page)
page 2 (Stickers)
page 3 (Text Customization Page)
Each of these pages have their own scaffolds.
Editor page has a widget called LayoutCanvas which is something like:
Widget build(BuildContext context) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
CanvasModel.of(context).init(canvasKey!);
});
return Container(
Inside init:
void init(GlobalKey canvasKey) {
_canvasKey = canvasKey;
final context = _canvasKey.currentContext;
if (context == null) return;
final bounds = context.findRenderObject()!.paintBounds;
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
var canvasHeight = screenHeight * 0.7;
var canvasWidth = layout.aspectRatio * canvasHeight;
Issue:
As you can see I'm taking 0.7 or 70% of the screen height as the canvas height and calculating the rest from there. But 70% is quite small for something like an editor canvas. But if I make it 80% some of the editor is getting cut by the bottom navigation bar.
Maybe the screenHeight is not taking the bottom navigation bar height into consideration?
I either need to make it dynamic or I need to subtract the bottom nav height from screenHeight.
aspectRatio:
double get aspectRatio => isInitialized ? height / _layout!.height : 0;
How can I solve this issue?
To get the maximum available height you need to distract some values from MediaQuery.of(context).size.height. Assuming that you have a top AppBar and a BottomNavigationBar, you can use this formula:
MediaQuery.of(context).size.height - // total height
kToolbarHeight - // top AppBar height
MediaQuery.of(context).padding.top - // top padding
kBottomNavigationBarHeight // BottomNavigationBar height
you can use MediaQuery.of(context).size.width and
MediaQuery.of(context).size.height
I am trying to create a view that consist of a background image with widgets positioned dynamically in certain places on this image, each widget will have an x and y that needs to be calculated for different screens and for different image sizes.
what i did so far was showing the image in a stack and made a list of widgets where each widget type is being checked then create a flutter widget that corresponds with it adding it to this list and displaying it over the image in the stack, but i am looking for a cleaner way to create this behavior, also when rotating the screen the widgets are not being placed in a correct position,
Thank you for your time.
You can do something like:
Stack(
children: [
Image.asset('YOUR IMAGE HERE', fit: BoxFit.cover), // this is your bg image,
..List.generate(imagesCollection.length, (index) {
// you could encapsulate all this logic in a separate widget
var img = imagesCollection[index];
var r = Random();
// make sure to stay within the bounds of your screen
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
var randomX = r.nextInt(screenWidth);
var randomY = r.nextInt(screenHeight);
// before you position the image, check that is within the bounds
// check if the randomX - IMAGE_WITH is less than the screen width, same for the height
return Positioned(
top: randomY,
left: randomX,
child: Image.asset(img, width: IMAGE_WIDTH, height: IMAGE_HEIGHT)
);
}
]
)
Something around those lines.
I want to show some animation when user tap on the screen. The animation need to be controllable too as it needs to be reset after each tap.
What I have tried:
1. Show a Gif image in Overlay.
RenderBox renderBox = context.findRenderObject();
var size = renderBox.size;
var offset = renderBox.localToGlobal(Offset.zero);
_myGif = Image.asset('images/mygif.gif', width: 100, height: 100,);
return OverlayEntry(
builder: (context) => Positioned(
left: offset.dx - 50.0 + size.width/2,
top: offset.dy - 50.0 + size.height/2,
child: Container(
child: _myGif
),
)
);
Problem: The Gif animation is not controllable. The animation also appears to be played from random frames and end at random frames each time.
Use third party widget (gif_ani)
_animationCtrl = GifController(vsync: this, duration: new Duration(milliseconds: 1000), frameCount: 38);
_mygifAnimation = GifAnimation(
width: 100.0,
height: 100.0,
image: AssetImage('images/mygif.gif'),
controller: _animationCtrl,
);
Problem: It only works when it's not on an Overlay. When the GifAnimation is added as a child in Overlay it doesn't display at all.
Use Flame to run sprite sheet
Problem: AnimationAsWidget doesn't fit my requirement as I need to control the animation. Other ways would make my code too complex as I'm not building a game.
Is there any solution on this? Thank you in advance.
Fullscreen I mean the popup usercontrol covers the whole cellphone screen, maximize. can this be done?
thx!
You can get the current width and height by Content.ActualHeight/Width property
here's a code snippet
public void showPopUp()
{
//get heigth and width
double height=Application.Current.Host.Content.ActualHeight;
double width = Application.Current.Host.Content.ActualWidth;
//child content
StackPanel stk = new StackPanel();
stk.Height = height; //set height
stk.Width = width; //set width
stk.Background = new SolidColorBrush(Colors.Red);
TextBlock txtblock = new TextBlock() { FontSize=40, Text="HELLO WORLD", TextWrapping=TextWrapping.Wrap};
stk.Children.Add(txtblock);
Popup _popup = new Popup();
_popup.Child = stk; //set child content
this.LayoutRoot.Children.Add(_popup);
_popup.IsOpen = true;
}
and then you get this result ;)
For Windows Phone 8.1 you can get the current Application width and height by Window.Current.Bounds
double height = Window.Current.Bounds.Height;
double width = Window.Current.Bounds.Width;
I am new to Titanium.
I have taken 3 view and want to hide show that view on button click for iPhone app.
Any idea how to achieve this?
You can hide / show a view very easily, heres a self contained example:
var win = Ti.UI.createWindow();
var view = Ti.UI.createView({
width : 100,
height : 100,
backgroundColor : 'red'
});
var redView = Ti.UI.createView({
title : 'Hide / Show Red View',
bottom : 0,
width : 200,
height : 35
});
var visible = true;
button.addEventListener('click', function(e) {
if(visible) {
redView.hide();
} else {
redView.show();
}
visible = !visible;
});
win.add(redView);
win.add(button);
win.open();
While the other answer is certainly useful, two other (slightly) different methods for doing the same thing, just in case Titanium flips out when you use show() and hide().
//Method 1, using part of Josiah Hester's code snippet
var visible = true;
button.addEventListener('click', function(e) {
if(visible) {
redView.setVisible(false); //This is the exact same thing as hide() method
} else {
redView.setVisible(true); //This is the exact same thing as show() method
}
visible = !visible;
});
You can set opacity to 0 and even if the view's visible property is set to true, it will still be invisible, due to a completely nonexistent level of opacity. This is useful if you want something to be visible, but not clickable (by placing a view behind a view with an opacity of zero.
//Method 2, same code section
var opacity = 0;
button.addEventListener('click', function(e) {
if(opacity) {
redView.setOpacity(0); //This is the NOT the same thing as hide() method
} else {
redView.setOpacity(1); //This is the NOT thesame thing as show() method
}
opacity = Math.abs(opacity - 1);
});