How to change color when tapped using touchable custom paint in flutter? - flutter

I make sleep data chart that has touchable bar charts. This is made by using touchable custom painter.
Here is sample code, image. Tooltip that has sleep amount message is shown when you long pressed the bar.
So, I want to add effect that change bar color when I tap down the bar.
But I don't know how to make this effect.
I tried to add some code in component/chart_painter.dart but this can't change color.
//~~~ line 90
touchyCanvas.drawRRect(rect, paint,
onLongPressStart: (_) => showTooltipCallback(
context: context,
amount: dataAmount[index],
left: left,
top: top,
),
// like this
onTapDown: (_) {
canvas.drawRRect(rect, paint);
}
);
//~~~

Related

What is the exact position of the BackButton in an AppBar? Is kToolbarHeight 4px off?

Description
How do you position a custom back button on the exact location where the back button usually would be in an app bar?
Is kToolbarHeight 4px off?
Goal
I fade in the original app bar as the bottom sheet is pushed to the top.
Currently I'm using a Stack widget that positions the back button with kToolbarHeight from the top, but apparently that doesn't really match (It's rather kToolbarHeight - 4px).
I use a custom implementation of a back button, but this problem persists with the original backButton widget too.
Stack(
children: [
Map(...),
const Positioned(
top: kToolbarHeight,
left: 4.0,
child: CustomBackButton(),
),
],
);
Groundwork
I've looked it up in the dev tools and the original source code but couldn't find a reliable constant nor anything helpful.
Try like this:
Give your CustomBackButton() widget the dimensions of a square of kToolbarHeight side.
Inside your Stack, add a SafeArea child, into which you position the CustomBackButton() in the top left corner. That should place it in the right position.

flutter - fab button animation which will go to top from bottom

I need help with the animation, when I click on the FAB icon in the first screen the icon will go up with animation and the other screen (shown in second image) should be displayed with animation like curtain. And the fab icon should be set in the app bar just like second image.
Bottom menu should be there in both of the screen just like the screenshots given.
you can do one thing that just wrap floating action button to AnimatedContainer
AlignmentDirectional _ironManAlignment = AlignmentDirectional.bottomCenter;
...
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: AnimatedContainer(
duration: Duration(seconds: 2),
alignment: _ironManAlignment,
child: FloatingActionButton(
onPressed: () {
_flyIronMan();
},
child: Icon(Icons.add),
),
),
like this
when you press button then call this method
void _flyIronMan() {
setState(() {
_ironManAlignment =
AlignmentDirectional(0.0, -0.8); //AlignmentDirectional(0.0,-0.7);
});
}
Just wrap buttons on each page with Hero widget, like that:
Hero(
tag: 'fab',
child: FloatingActionButton()
);
With the design you want to achieve, I suggest you to use sliding_up_panel instead of pushing new screen.
It has a parameter collapsed, in which you can put FloatingActionButton to expand panel on tap, and show the same button inside the expanded panel. Just set panel non-draggable, and it won't expand on swipe.
Please read it's documentation carefully, I'm sure you can achieve the effect you want with this widget.

Flutter: How to make a ListView transparent to pointer events (but not its non-transparent contents)?

I have a Scrollable (ListView or any other) and it contains a transparent widget, say Container(height:200). I can see through both the widget and the scrollable (in other words I can see the widgets behind the scrollable).
How can I be able to click through the transparent widget and the scrollable, so that I reach the widgets behind the scrollable?
ListView(
children: [
Container(height: 200), // Transparent.
Container(color: Colors.red, height: 200),
],
);
Note, I cannot wrap the scrollable with IgnorePointer, because I still want to click the non-transparent widgets in the scrollable.
The only reasonable solution I can think of is to have a GestureDetector on the transparent container, which will give you the global position of the taps:
GestureDetector(
onTapUp: (TapUpDetails tapUpDetails) {
print("onTapUp global: " + tapUpDetails.globalPosition.toString());
},
And then add a Key to the widget behind the list, and use it to get the global position of the top left corner of the widget's rectangle, as well as the size of the widget, and use those to get the rectangle of the widget:
RenderBox renderBox = _key.currentContext.findRenderObject();
Offset topLeftCorner = renderBox.localToGlobal(Offset.zero);
Size size = renderBox.size;
Rect rectangle = topLeftCorner & size;
If the background widget does not move, you can do it within initState on the very next frame using WidgetsBinding.instance.addPostFrameCallback (the render object will be null if do it synchronously within initState) and save the Rect - otherwise you will have to recalculate it on every tap.
And then finally on each tap on the transparent container you can calculate whether the tap's position is within the boundaries of the background widget, and invoke the corresponding code:
// if tap is within boundaries of the background widget
if (rectangle.contains(tapUpDetails.globalPosition)) {
// your code here
}

How to show the menu of PopupMenuButton from the code

PopupMenuButton opens a menu when user clicks on it. But how do I do open the same menu at the same place as the PopupMenuButton from the code(e.g. due to another user event)?
I am trying to create a nested menu in the AppBar. Like when user clicks on "Sort by" then menu changes to something else. Is there another way to achieve this? I could not find it on the internet.
If you take a look at the sources of PopupMenuButton you can see that it uses showMenu method which is accessible even out of the button's context (potentially comes along with imported material Dart class).
Define a GlobalKey variable and apply it to your PopupMenuButton to have a reference to the context of your button - that's how we get the position of the button on the screen.
Create an array of items for the menu, later to reuse it in both the programmatic call and the physical button itself.
Calculate the position for the menu to appear at, and make the showMenu call.
showMenu returns a Future - listen to its completion to get the chosen item.
// Define these variables somewhere accessible by both the button on `build` & by the programmatic call.
final popupButtonKey = GlobalKey<State>(); // We use `State` because Flutter libs do not export `PopupMenuButton` state specifically.
final List<PopupMenuEntry> menuEntries = [
PopupMenuItem(
value: 1,
child: Text('One'),
),
PopupMenuItem(
value: 2,
child: Text('Two'),
),
];
In your build:
PopupMenuButton(
key: popupButtonKey,
initialValue: null,
itemBuilder: (_) => menuEntries,
// ...
);
To show the menu programmatically:
// Here we get the render object of our physical button, later to get its size & position
final RenderBox popupButtonObject = popupButtonKey.currentContext.findRenderObject();
// Get the render object of the overlay used in `Navigator` / `MaterialApp`, i.e. screen size reference
final RenderBox overlay = Overlay.of(context).context.findRenderObject();
// Calculate the show-up area for the dropdown using button's size & position based on the `overlay` used as the coordinate space.
final RelativeRect position = RelativeRect.fromRect(
Rect.fromPoints(
popupButtonObject.localToGlobal(Offset.zero, ancestor: overlay),
popupButtonObject.localToGlobal(popupButtonObject.size.bottomRight(Offset.zero), ancestor: overlay),
),
Offset.zero & overlay.size, // same as: new Rect.fromLTWH(0.0, 0.0, overlay.size.width, overlay.size.height)
);
// Finally, show the menu.
showMenu(
context: context,
elevation: 8.0, // default value
items: menuEntries,
initialValue: null,
position: position,
).then((res) {
print(res);
});

how to change the opacity of the snackbar in flutter?

I wish to change the opacity of the SnackBar. It has only the background property. Can it be customized or I have to create the custom widget for snack bar?
Try using the color property of snack bar like this,
backgroundColor: Colors.black.withOpacity(0.5)
This should work as you expected.
You can adjust the opactiy of your backgroundColor with
color.withAlpha(..),
color.withOpacity(..),
using a hexadecimal integer 0x33ffffff (the first pair of digits after the x represents the alpha value),
creating a Color using Color.fromARGB(...)
or by using Color.fromRGBO(...).
You can find information about this on this documentation page about the Color class.
Now, you face the following problem: Your content is not yet translucent.
This is easily adjustable using the Opcacity Widget.
In your Snackbar just surround your actual content with an Opacity Widget:
SnackBar(backgroundColor: Color(0x66bbbbbb),
content: Opacity(opacity: .7,
child: Container(), // your content
),
)
If you are planning to make the background transparent, this may help you.
Mostly you get a black background because of elevation.
SnackBar(
elevation: 0,
backgroundColor: Colors.transparent,
/.......
),