To update the version number, navigate to the pubspec.yaml file and update the following line with the current version string:
version: 1.0.0+1
After the change, run:
flutter pub get
Build and release the iOS app
A detailled description of the whole process is described at docs.flutter.dev.
To release the iOS app, you use Flutter to build a xcarchive file. This build archive can be published the same way you would do it with Xcode by using the archive manager and one of the different Distribution options.
Build the iOS app:
flutter build ipa
The generated xcarchive file is saved to your app directory under:
/build/ios/archive/MyApp.xcarchive
Build and release the Android app
A detailled description of the whole process is described at docs.flutter.dev.
To release the Android app, you use Flutter to build a app bundle aab file. This file can be distributed by using Google Play Console or any other store.
Build the Android app:
flutter build appbundle
The generated aab app bundle file is saved to your app directory under:
You can’t ping ports, as Ping is using ICMP which doesn’t have the concept of ports. Ports belong to the transport layer protocols like TCP and UDP. However, you could use nmap to see whether ports are open or not:
nmap -p 80 example.com
The output will look like this:
nmap -p 80 google.de
Starting Nmap 7.92 ( https://nmap.org ) at 2021-12-08 10:59 CETNmap scan report for google.de (142.250.185.131)Host is up (0.017s latency).rDNS record for 142.250.185.131: fra16s50-in-f3.1e100.netPORT STATE SERVICE80/tcp open httpNmap done: 1 IP address (1 host up) scanned in 0.09 seconds
Recently, my wife needed to create some stacked bar graphs for her publications. She wasn’t able to find a tool on the internet which allowed her to do this in an easy and shareable way. So I used this opportunity to look into Jupyter Notebooks. These notebooks allow you to document and run code and thus computations on a remote server from your browser and display the results directly in your browser as well
Google offers their version of Jupyter as a free service called Colab. Already having a Google account it was an easy choice to start there. But there are other similar services available on the internet and the code should run there as well (with minimal changes).
The file is quite self explanatory and can be saved within your own Google drive for editing. You can find it here.
The Notebook
Horizontal Stacked Bar Graph
This notebook will create a horizontal stacked bar graph within your browser based on the data you enter below. Just edit the data in 1) and execute the “gray blocks” in 1), 2) and 3) by either pressing “Shift + Enter” or the “Play” button in each blocks top left corner. To see the “Play” button you need to move your mouse over the block.
You can change the design of the graph in 2). This includes the unit which should be displayed on the bar. You will moste likely need to change the position of the legend as it depends on the data and size of the graph. To do this, change the x value of FigLegPosOffset slightly.
The code within a block is written in Python. Everything after a # is considered a comment. So you can add your own comments to your data or your changes.
1) Preparing the Data Define your data below and execute the block when done. If everything is correct, your data will be displayed as table below the block.
# importing the functions needed to generate the graph import pandas as pd# Axis captionsFigAxiXCap="Cocktails"FigAxiYCap="Which Cocktail do you want for the Party?"# Data (beware: the first entry will be displayed last)## Data Indexes DataIndexes = ['Caipirinha', 'Piña Colada', 'Cuba Libre', 'Mai Tai', 'Ipanema', 'Caribbean Night']## Data OptionsDataYesPlease = [73.2, 23.8, 24.7, 31.2, 56.6, 68.2]DataSureWhyNot = [20.3, 51.7, 60.3, 19.2, 4.8, 22.3]DataJustNo = [ 6.5, 24.5, 15, 59.6, 38.6, 9.5]## Name of each column (for the legend)df = pd.DataFrame(data={'Yes, please!': DataYesPlease, 'Sure, why not?': DataSureWhyNot, 'Just no!': DataJustNo})#-------------------------------------------------------------------------------#no need to edit below this linedf.index = DataIndexes# print table for convinience/debugging (transposed)df
2) Figure Properties
In the block below you can change the format of the figure. When done (or fine with the defaults) execute it to set all properties.
################## Figure Design ###################Figure## Figure SizeFigSizeX = 20FigSizeY = 5## Figure background color FigBackColor="white"## Axis Caption SizeFigAxiXCapFontSize=45FigAxiYCapFontSize=45## Axis Labels Font SizeFigLabelFontSize=20# Blocks## Colormap of the blocks (all Options: https://matplotlib.org/stable/gallery/color/colormap_reference.html)FigColMap="Pastel2"## Width of bars (everything above 1 will overlap)FigBarsWidth=0.8## FontSize of bar lablesFigBarsFontSize=20# Data and Captions (needs to be defined)## Unit to display within barsFigBarUnit="%"# Legend## Legend Font SizeFigLegFontSize=20## Legend position [best|upper right|upper left|lower left|lower right|right|center left|center right|lower center|upper center|center]FigLegPos="upper center"## Figure OffSet (will move the legend box slightly to match actual figure position)FigLegPosOffset=(1.11, 1.0)## 3) Generate and Display the FigureThe block below will generate the figure. You do not need to change anything here. Just be sure to execute it again **after changing anything above**.# define plot type and layoutax = df.plot(stacked=True, kind='barh', figsize=(FigSizeX, FigSizeY), colormap=FigColMap, width=FigBarsWidth, fontsize=FigBarsFontSize, xlim=[0,100])# Add labels to the bars # Attribution: Trenton McKinney on StackExchange: https://stackoverflow.com/a/60895640/3764407 CC BY-SA 4.0for rect in ax.patches:# Find where everything is located height = rect.get_height() width = rect.get_width() x = rect.get_x() y = rect.get_y()# The width of the bar is the data value and can be used as the label label_text = ""if width > 4: label_text = f'{width:.1f}' + FigBarUnit ##### use {width:.2f} or {width:.3f} to increase precision ##### ax.text(x, y, text) label_x = x + width / 2 label_y = y + height / 2# plot only when height is greater than specified valueif height > 0: ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=FigBarsFontSize)# Set legend position and styleax.legend(bbox_to_anchor=FigLegPosOffset, loc=FigLegPos, borderaxespad=0., fontsize=FigLegFontSize) # Set y labelax.set_ylabel(FigAxiXCap, fontsize=FigAxiXCapFontSize)# Set x labelax.set_xlabel(FigAxiYCap, fontsize=FigAxiYCapFontSize)# Set Background Colorax.set_facecolor(FigBackColor)
3) Generate and Display the Figure The block below will generate the figure. You do not need to change anything here. Just be sure to execute it again after changing anything above.
define plot typeand layoutax = df.plot(stacked=True, kind='barh', figsize=(FigSizeX, FigSizeY), colormap=FigColMap, width=FigBarsWidth, fontsize=FigBarsFontSize, xlim=[0,100])# Add labels to the bars # Attribution: Trenton McKinney on StackExchange: https://stackoverflow.com/a/60895640/3764407 CC BY-SA 4.0for rect in ax.patches:# Find where everything is located height = rect.get_height() width = rect.get_width() x = rect.get_x() y = rect.get_y()# The width of the bar is the data value and can be used as the label label_text = ""if width > 4: label_text = f'{width:.1f}' + FigBarUnit ##### use {width:.2f} or {width:.3f} to increase precision ##### ax.text(x, y, text) label_x = x + width / 2 label_y = y + height / 2# plot only when height is greater than specified valueif height > 0: ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=FigBarsFontSize)# Set legend position and styleax.legend(bbox_to_anchor=FigLegPosOffset, loc=FigLegPos, borderaxespad=0., fontsize=FigLegFontSize) # Set y labelax.set_ylabel(FigAxiXCap, fontsize=FigAxiXCapFontSize)# Set x labelax.set_xlabel(FigAxiYCap, fontsize=FigAxiYCapFontSize)# Set Background Colorax.set_facecolor(FigBackColor)
4) Download the Figure (from Google Colab) To export the generated figure use the following block. You can change the file name and type as well as its resolution (dots per inch/DPI).
# Define the file nameFigureFileName="figure"# Define the type (jpg, png, pdf, svg)FigureFileType="png"# Define DPI (setting this too high might result in long wait times and finally an error)FigureDPI=30# do not edit belowFigFile=FigureFileName + "." + FigureFileTypeax.figure.savefig(FigFile,dpi=FigureDPI,bbox_inches = 'tight')from google.colab import filesfiles.download("/content/" + FigFile )
There are different concepts that improve the data handling in Dart. The following list of snippets is a collection of the most handy once. Warning: this might simplify your code a lot! 😉
The Spread Operator
Dart supports the spread operator, which allows to insert a collection (multiple elements) into a collection:
The code snippet below merges two maps. All (key) values in default are available in the merged map. This snippet only works for single level maps, multidimensional maps are only handled on the first level:
Dart offers an easy way to create dynamic lists by using conditionals (if) and repetition (for):
var nav = ['Home','Furniture','Plants',if (promoActive) 'Outlet'];
var listOfInts = [1, 2, 3];var listOfStrings = ['#0',for (var i in listOfInts) '#$i'];assert(listOfStrings[1] == '#1');
String to Number
var stringValue = "123";var intValue = int.parse(stringValue);print(intValue);// 123 (int)
var stringValue = "123.45";var doubleValue = double.parse(stringValue);print(doubleValue);// 123.45 (double)
Numbers to String
Most of the Dart data types support a toString() method, which allows a conversion to strings. This is very handy for every parameter where a string is needed:
int intValue = 123;var stringValue = intValue.toString();print(stringValue);// "123" (string)
Check if object exists in list
To check if an object is already in a list, you can use the .where() method. It checks and creates a list based on given conditions. So if the result is not empty then that item exists.
var list = List<MyObject>[];var myObject = MyObject();if (list.where((element) => element.optionId == myObject.optionId).isNotEmpty) {print('object exists');} else {print('object does not exist');}
To create a rounded corner image in Flutter, you can use the Container widget and set the decoration property to a BoxDecoration with a borderRadius that defines the rounded corners. Here’s an example:
In this example, the width and height properties of the Container define the size of the image, the DecorationImage property defines the image source and how it should be scaled to fit the container and the borderRadius property is used to create the rounded corners with a Radius.circular(10).
Currently, there are two different version of Java: java and java11. To check the version of both, you can use the following commands:
% brew info javaopenjdk: stable 16.0.1 (bottled) [keg-only]Development kit for the Java programming languagehttps://openjdk.java.net/Not installedFrom: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openjdk.rbLicense: GPL-2.0-only with Classpath-exception-2.0
% brew info java11openjdk@11: stable 11.0.10 (bottled) [keg-only]Development kit for the Java programming languagehttps://openjdk.java.net/Not installedFrom: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openjdk@11.rbLicense: GPL-2.0-only
Depending on your requirements, you can install one of the above. For me, some of the libraries I use in Dart are currently not compatible with the latest Java version (16.0.1), so I decided to install Java 11 with LTS (long term support).
% brew install java11
This will install Java version 11.0.10 as listed in the output above. The output also shows the following hints:
For the system Java wrappers to find this JDK, symlink it with sudo ln -sfn /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdkopenjdk@11 is keg-only, which means it was not symlinked into /usr/local,because this is an alternate version of another formula.If you need to have openjdk@11 first in your PATH, run: echo 'export PATH="/usr/local/opt/openjdk@11/bin:$PATH"' >> ~/.zshrcFor compilers to find openjdk@11 you may need to set: export CPPFLAGS="-I/usr/local/opt/openjdk@11/include"
For me it was necessary to called the specified command, so that the system finds the java binary:
Sometimes it’s necessary to trigger an action for CI/CD, e.g. when you use GitLab. To do this without any changes on the code base, you can create an empty commit. For this, git has a command:
When using nested Scaffolds (e.g. in combination with IndexedStack), the PrimaryScrollController is not usable by default. An IndexedStack will load all subviews so scroll-to-top will change all scrollable views at the same time, even if they are not visible or it simply does not work, because the PrimaryScrollController can only be attached to a single Scaffold.
To overcome this issue, the scrolls_to_top package can be used. This also works for nested Scaffolds. The functionality of the package is described in this post (here is the english translation).
The following code example shows the usage. This is how to use ScrollsToTop within each children of IndexedStack:
final _scrollController = ScrollController();@overrideWidgetbuild(BuildContext context) {returnScaffold( primary: true, body: ScrollsToTop( onScrollsToTop: (event) {// onScrollsToTop will be called on each touch event, so check if the view is currently visibleif (!widget.isOnScreen) return; _scrollController.animateTo( event.to, duration: event.duration, curve: event.curve, ); }, child: ListView.builder( itemBuilder: _itemBuilder, itemCount: 100, controller: _scrollController, ), ), ); }