<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Author at Infinum</title>
		<atom:link href="https://infinum.com/blog/author/josip-krnjic/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Thu, 16 Apr 2026 15:26:52 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>37783https://infinum.com/uploads/2023/04/From-Figma-design-to-Flutter-app_-The-Color-scheme_hero.webp</url>
				</image>
				<title>Color Schemes – Figma to Flutter Design Implementation</title>
				<link>https://infinum.com/blog/flutter-color-schemes/</link>
				<pubDate>Wed, 19 Apr 2023 14:04:17 +0000</pubDate>
				<dc:creator>Josip Krnjić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=37783</guid>
				<description>
					<![CDATA[<p>To create visually stunning and color-consistent apps, designers and developers need to be on the same page about using color schemes in Flutter app design. </p>
<p>The post <a href="https://infinum.com/blog/flutter-color-schemes/">Color Schemes – Figma to Flutter Design Implementation</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-135"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-24-text js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	To create visually stunning and color-consistent apps, designers and developers need to be on the same page about using color schemes in Flutter app design.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	As a Google-made app development framework, Flutter utilizes the power of Google&#8217;s Material Design for its theming capabilities. In this blog post, we’re going to focus specifically on color schemes and what designers and developers can expect when working together on Flutter projects. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	Our approach to implementing colors in Flutter app development can be applied to any kind of design and various use cases. Of course, it is not the only way to go about implementing colors in Flutter, but these suggestions are the result of our experience and come with several benefits:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-102">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-103'
	>
	Streamlining Flutter design implementation</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-105">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-106'
	>
	Providing a standard and expected way of handling colors in Flutter app design</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-108">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-109'
	>
	Solving some common challenges like using light and dark themes and theme changes</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-112"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-18-text-roman js-typography block-highlighted-text__typography'
	data-id='es-111'
	>
	<strong>If you&#8217;re interested in more Flutter content, some of the topics we&#8217;ve already covered include <a href="https://infinum.com/blog/flutter-vs-native/" target="_blank" rel="noreferrer noopener">when to choose Flutter over native</a>, <a href="https://infinum.com/blog/flutter-embedded-device/" target="_blank" rel="noreferrer noopener">using Flutter with embedded devices</a>, <a href="https://infinum.com/blog/charts-in-flutter/" target="_blank" rel="noreferrer noopener">drawing charts in Flutter</a>, and <a href="https://infinum.com/blog/testing-flutter-apps-a-qa-guide/" target="_blank" rel="noreferrer noopener">testing Flutter apps</a>.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-113">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-114'
	>
	Theme widget</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-116">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-117'
	>
	The starting point for tackling Flutter design is the <code>Theme</code> widget and the <code>ThemeData</code> class. The latter is the class that holds all the colors and allows the developer to set around 60 colors.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-119">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-120'
	>
	There are 60 colors available because Flutter supports both old and new coloring systems. Managing them all is somewhat complicated, but luckily, we can create <code>ThemeData</code> from the Material color scheme. This way, we only need to define 10 colors.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-122">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-123'
	>
	<strong>Tip for developers</strong>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	Use <code>ThemeData.from(colorScheme: colorScheme)</code> to construct the ThemeData from the color scheme.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-128">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-129'
	>
	Flutter color scheme</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-131">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-132'
	>
	The colors in Material schemes come in pairs. First, there is the color itself, and then there’s the color of text or other content on that color.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-136"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-137">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-1-mobile.webp				media='(max-width: 699px)'
				type=image/webp								height="1048"
												width="1280"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-1-2400x925.webp				media='(max-width: 1199px)'
				type=image/webp								height="925"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/04/in-article-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1048"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-153"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-139">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-140">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-141'
	>
	The 10 colors used here are not optional. They are the minimum colors required for constructing the Material color scheme in Flutter. Notice that the color names are derived from their purpose and not their specific hue. It is completely normal to have more than one color use the same hex value. In this example, you can see that OnPrimary, Surface, and OnError all use the same white color.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-145"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-143">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-144'
	>
	<strong>Color in bulk</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-148"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-146">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-147'
	>
	Whenever you use a Flutter widget, it will often pull a color from those 60 colors in the theme. This means that if you set <code>ThemeData</code> correctly, a big portion of the app can be colored automatically without the developer needing to specify the color for every possible widget.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-151"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-149">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-150'
	>
	This system will help you streamline the implementation of the design into the app since the app will follow the color scheme from Figma directly.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-154"
	 data-media-type='video'>

	<div class="video__wrapper" data-id="es-155">
		<video
		class="video block-media__video js-video js-block-media-video video--cursor-takeover-use"
		 loop autoplay playsinline muted preload='metadata'>
		<source  src='https://infinum.com/uploads/2023/04/How-it-works.mp4' type='video/mp4' />	</video>
	</div></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-186"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-157">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-160"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-158">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-159'
	>
	Tip for developers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-163"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-161">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-162'
	>
	If you are not an experienced Flutter developer, you might not even know the full scope of Flutter Theme possibilities. From experience, developers don’t tend to rely on Flutter Theme and set all the colors manually through code. Doing this has several disadvantages since Flutter’s system already offers a standard way of solving some app-theming challenges.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-166"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-164">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-165'
	>
	<strong>Why stop at 10 colors in Flutter design?</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-167">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-168'
	>
	Apart from the 10 colors that you’re required to set, you can also define as many additional colors as you want.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-170">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-171'
	>
	<strong>Tip for designers:</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-173">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-174'
	>
	Be mindful when naming the colors. Don’t call your color LightGray if it switches to white in dark theme. Try to use meaningful names that are not connected with the hue.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-176">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-177'
	>
	If you are certain that your color won’t change across themes, then it’s fine to name it <strong>Red10</strong>, <strong>Red20</strong>… or something similar. You should put all these colors in separate Figma pages because that’s what the developer will use when implementing them into the app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-179">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-180'
	>
	<strong>Tip for developers:</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-182">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-183'
	>
	Construct your ColorScheme from that Figma page. Use<a href="https://api.flutter.dev/flutter/material/ThemeExtension-class.html" target="_blank" rel="noreferrer noopener"> ThemeExtensions</a> for any additional colors.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-189"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-187"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-188">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-3-mobile.webp				media='(max-width: 699px)'
				type=image/webp								height="1892"
												width="1588"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-3-2400x1669.webp				media='(max-width: 1199px)'
				type=image/webp								height="1669"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/04/in-article-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1892"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-213"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-190">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-191">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-192'
	>
	<strong>Referring to color names</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-196"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-194">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-195'
	>
	Once a color scheme is defined on a Figma page and implemented in code, we can refer to the colors using their names. You’ll agree that this is much easier than remembering hex codes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-199"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-197">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-198'
	>
	The colors should be added to Figma color styles. And those same colors should be used for all design elements (components, screens, etc.).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-200">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-201'
	>
	Tip for developers: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-203">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-204'
	>
	When implementing s screen, you don’t have to read the hex values. Just look at the name of the color and use it like <code>Theme.of(context).colorScheme.primary</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-206">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-207'
	>
	Important info for designers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-210'
	>
	There should be no unlinked colors in Figma since the developer will not be implementing the hex values directly to the screen. All the colors need to be linked so that the developer can read only the names.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-216"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-214"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-215">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-7-mobile.webp				media='(max-width: 699px)'
				type=image/webp								height="1638"
												width="1144"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-7-2400x925.webp				media='(max-width: 1199px)'
				type=image/webp								height="925"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/04/in-article-7.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1048"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-228"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-217">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-220"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-218">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-219'
	>
	However, there is an exception to this rule, and it involves graphics and assets that are exported as .svg or .png and implemented into the app as such.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-221">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-222'
	>
	Defining multiple themes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-224">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-225'
	>
	If you’ve set up correctly everything covered so far, adding multiple themes should be a walk in the park. Designers should duplicate the color scheme page and change the color values, and developers can then add that scheme as an alternative <code>ThemeData</code>. This means that if we want to implement a dark theme, it’s just a matter of making a simple change in one place, and there’s no need to go through every screen.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-231"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-229"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-230">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-4-mobile-final.webp				media='(max-width: 699px)'
				type=image/webp								height="3876"
												width="1588"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-4-2400x1426.webp				media='(max-width: 1199px)'
				type=image/webp								height="1426"
												width="2400"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-4-3000x1783.webp				media='(max-width: 1999px)'
				type=image/webp								height="1783"
												width="3000"
				 />
												<img
					src="https://infinum.com/uploads/2023/04/in-article-4.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1892"
															width="3184"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-244"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-232">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-235"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-233">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-234'
	>
	Common use cases for alternative themes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-236">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-237'
	>
	There are several common situations that require the use of multiple themes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-239">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-240'
	>
	Dark theme</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-241'
	>
	The most common use case found in many apps.</p>	</div>
</div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-252"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="grid block-grid__grid" data-id="es-251">
	
<div class="block-grid-item" data-id="es-247">
	
<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-245"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-246">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/04/in-article-6.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1280"
															width="720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>
</div>

<div class="block-grid-item" data-id="es-250">
	
<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-248"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-249">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2023/04/in-article-5.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1280"
															width="720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-267"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-253">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-254">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-255'
	>
	Alternative theme</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-256'
	>
	In this case, the user can select different looks for the app. Maybe there’s a special theme that is only live during the Christmas season.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-261"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-258">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-259'
	>
	Whitelabel apps</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-260'
	>
	This is used when an app is exported to multiple clients, and each one of them can personalize it by changing the colors.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-265"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-262">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-263'
	>
	Section themes</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-264'
	>
	It’s possible that an app has a very different color scheme used only with certain screens or flows. If this is a significant part of the app, we recommend creating a new theme for these screens.</p>	</div>
</div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-270"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-268"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-269">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-8-mobile.webp				media='(max-width: 699px)'
				type=image/webp								height="1140"
												width="1190"
				 />
								
			<source
				srcset=https://infinum.com/uploads/2023/04/in-article-8-2400x1235.webp				media='(max-width: 1199px)'
				type=image/webp								height="1235"
												width="2400"
				 />
												<img
					src="https://infinum.com/uploads/2023/04/in-article-8.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1400"
															width="2720"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-315"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-271">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-274"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-272">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-273'
	>
	Tip for designers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-277"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-275">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-276'
	>
	When using multiple themes, the color names should have a common prefix or grouping defined by theme. You can do this in Figma by adding /. For example:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-278">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-279'
	>
	Light/Primary Light/OnPrimary Light/Background</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-283"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-281">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-282'
	>
	Dark/Primary Dark/OnPrimary Dark/Background</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-286"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-284">
	<p	class='typography typography--size-20-text js-typography block-paragraph__paragraph'
	data-id='es-285'
	>
	Tip for developers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-289"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-287">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-288'
	>
	All the separate themes should be implemented in the app, and depending on the use case, it’s all matter of changing the <code>MaterialApp(theme: )</code> with the appropriate one. If you want to change the theme dynamically (while the app is running), we recommend rebuilding the <code>MaterialApp</code> with a different theme using Riverpod, Provider, Bloc, or similar solution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-292"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-290">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-291'
	>
	The Material 2 or Material 3 dilemma</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-295"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-293">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-294'
	>
	This guide is based on a color scheme that’s sometimes referred to as the Material 2 color scheme. The new version of Material design is Material 3 and contains quite a bit more colors. However, it’s still not default.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-296">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-297'
	>
	The reason why I chose to explain the workflow in Material 2, is that this guide is adaptable to any kind of design. In order to use Material 3, a designer will need to understand how Material 3 system works, as there are more colors available, and there are specific tonal relationships between them, which is much more complex than Material 2.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-299">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-300'
	>
	If a designer knows how Material 3 works, there’s no reason against using the Material 3 color scheme. However, having worked on different projects, I can say that the case is rarely that ideal. You have to find a solution that everyone involved can agree on, and the workflow I described can be applied to any project. It usually requires only minor design touch-ups, like renaming the colors.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-302">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-303'
	>
	<strong>Working together to create great Flutter app design</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-305">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-306'
	>
	A well-implemented color scheme can make a big difference in the overall design of a Flutter app. By utilizing Material Design&#8217;s ten-color scheme and Flutter&#8217;s <code>ThemeData</code> class, developers can easily streamline the implementation of the design into the app. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-308">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-309'
	>
	Additionally, the use of multiple themes can offer users more options and allow for personalization. By taking the time to properly define and implement a color scheme, designers and developers can both take the necessary steps to create Flutter apps that are both functional and visually pleasing.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-313"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-311">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-312'
	>
	As mentioned before, the proposed workflow is not the only way to go about implementing color schemes in Flutter. However, it’s tried and tested, and judging by experience, both developers and designers benefit from it.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-316"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-317">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2023/04/Dashatars-1400x760.webp				media='(max-width: 699px)'
				type=image/webp								height="760"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2023/04/Dashatars.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1086"
															width="2000"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			A PM, a designer, and a developer working happily together		</figcaption>
	</figure></div></div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/flutter-color-schemes/">Color Schemes – Figma to Flutter Design Implementation</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>8158https://infinum.com/uploads/2021/12/flutter-embedded-device-0.webp</url>
				</image>
				<title>Are Embedded Devices the Future of Flutter?</title>
				<link>https://infinum.com/blog/flutter-embedded-device/</link>
				<pubDate>Fri, 17 Dec 2021 11:25:00 +0000</pubDate>
				<dc:creator>Josip Krnjić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/flutter-embedded-device/</guid>
				<description>
					<![CDATA[<p>Starting out with just Android, Flutter is now supported on various platforms and embedded devices could be the next milestone.</p>
<p>The post <a href="https://infinum.com/blog/flutter-embedded-device/">Are Embedded Devices the Future of Flutter?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-447"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-319">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-322"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-320">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-321'
	>
	In 2015, the Dart Developer Summit saw the introduction of Sky, an experimental UI framework for writing Android apps using Dart. It started with Android, but the technology was architectured to run on any device – web, desktop, car, refrigerator, anything with a screen.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-325"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-323">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-324'
	>
	Sky was eventually renamed to <a href="https://infinum.com/mobile-web-apps/flutter/">Flutter</a>, and the list of supported platforms gradually expanded to include iOS, web, and desktop. However, this is hardly the end of the road for Flutter, so the question that comes to mind is: what’s next? My guess is embedded devices.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-328"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-326">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-327'
	>
	I will illustrate that by running Flutter on a Raspberry Pi to show some interesting use cases.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-331"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-329">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-330'
	>
	The embedded way</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-334"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-332">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-333'
	>
	The Flutter team started with just Android, but they were able to add support for other platforms by writing the embedder. An embedder is not one program, but rather a whole system consisting of various tasks such as:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-337"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-335">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-336'
	>
	<li>Creating the rendering surface. The Flutter canvas needs to map to the platform canvas, which usually uses some low-level graphical interface like OpenGl, Vulkan, or Metal</li><li>Creating/setting up threads and providing event loop interop since Dart is a single-threaded language</li><li>Communicating user inputs such as touch, pointer, or button press to Flutter</li><li>Communicating system events to Flutter</li><li>Producing binaries that can be used on the platform</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-340"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-338">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-339'
	>
	These tasks require extensive knowledge of the platform we are embedding into. It’s mostly low-level code, not suitable for beginners. Full-fledged embedders have 15-30k lines of source code. You can find more information on <a href="https://flutter.dev/embedded">Flutter’s web page</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-343"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-341">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-342'
	>
	Currently, there are three default embedders written by the Flutter team: Android, iOS, and web, while desktop embedders for Mac, Linux, and Windows are in beta. Anyone can write an embedder, for example desktops started with the unofficial embedder <a href="https://github.com/go-flutter-desktop/go-flutter">go-flutter</a> and the official support was added later.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-346"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-344">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-345'
	>
	An embedded refrigerator?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-349"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-347">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-348'
	>
	Embedded devices is a very broad term, but not every device is suitable for Flutter. First off, a device is not an application, it has both hardware and software. This means that it requires an embedded engineer and someone to design the circuit board.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-352"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-350"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-351">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/flutter-embedded-device-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="349"
															width="587"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			A couple of devices that wouldn&#8217;T be a good fit for flutter		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-355"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-353">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-354'
	>
	When you find an appropriate device and the hardware is ready, you need to build the software to power the UI. With the current state of technology, this is a challenging task. The hardware has limited performance, and the current tools you can use to build UI interfaces have their own drawbacks. This is where Flutter provides a solution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-358"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-356">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-357'
	>
	Flutter + Raspberry Pi</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-361"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-359">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-360'
	>
	I’ve chosen Raspberry Pi for demonstration purposes, although you can use any similar device. Raspberry Pi is a small single-board low-cost computer and running Flutter on it can make for some very interesting use cases.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-364"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-362">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-363'
	>
	We could run Flutter on Raspberry Pi using the default Linux embedder that comes with Flutter because Raspberry Pi can run Linux, but I chose not to do that. The main reason is that the Linux embedder is more suitable for a real desktop experience with multiple windows and different apps, like Windows or Mac. We are going to use <a href="https://github.com/ardera/flutter-pi">flutter-pi</a> which is a light-weight embedder for Raspberry Pi. It doesn’t require a window system or a desktop at all, it will run on no-desktop Raspberry Pi OS Lite.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-367"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-365">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-366'
	>
	Use case #1: Ordering burgers with a real embedded feel</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-370"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-368">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-369'
	>
	In our first use case we will try to make a screen for a fast food restaurant that can be used to order food without interacting with the restaurant personnel. For this we will need a Raspberry and a touchscreen. I used a <a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/">Raspberry Pi 3B+</a> and a <a href="https://www.waveshare.com/7inch-HDMI-LCD-C-with-bicolor-case.htm">7-inch touchscreen</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-373"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-371"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-372">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/flutter-embedded-device-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="507"
															width="699"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-376"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-374">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-375'
	>
	We build a simple Flutter app and follow the flutter-pi instructions to run it on Raspberry Pi. Here is a preview of the app with the whole setup running:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-379"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-377"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-378">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/flutter-embedded-device-3.gif"
					class="image__img block-media__image-img"
					alt=""
										height="338"
															width="600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-382"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-380">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-381'
	>
	With Flutter we are able to create a great-looking app that runs smoothly with all the animations on Raspberry Pi. Flutter-pi gives it a real embedded feel because the user is unable to exit the app, interact with the Linux OS or turn the whole system off.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-385"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-383">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-384'
	>
	Use case #2: Flipping the switch with GPIO</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-388"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-386">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-387'
	>
	The real power of this setup with Raspberry Pi is that you can connect external devices and communicate with them. They can connect with Raspberry Pi over WiFi, Bluetooth, USB or wires (GPIO). To demonstrate, we are going to control a small LED light using Flutter over GPIO.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-391"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-389">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-390'
	>
	There are few ways to control GPIO pins. For this example, I skipped the Python programs and used the simplest way, which is echoing value (0 or 1) into a designated file. There’s one file for each GPIO pin on location with a path like <em>/sys/class/gpio/gpio27/</em>. If we echo 1, it means it will let the power through the pin so the light will turn on, and 0 will cut the power off.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-394"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-392">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-393'
	>
	With that info, we can build an app that will invoke the process command to turn the LED light on or off:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-397"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-395"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-396">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/flutter-embedded-device-4.gif"
					class="image__img block-media__image-img"
					alt=""
										height="268"
															width="600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-400"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-398">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-399'
	>
	We could listen to button presses in the same way, or interact with various sensors, for example a temperature or a distance sensor. We could run a servo motor, printer or whatever, since there is almost no limit with GPIO, it’s just a matter of effort.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-403"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-401">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-402'
	>
	The alternatives</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-406"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-404">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-405'
	>
	Of course, there are other ways to build a product that satisfies the use cases above. Let’s see how they compare with the embedded Flutter solution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-409"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-407">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-408'
	>
	iOS or Android tablet</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-412"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-410">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-411'
	>
	Since we’re using a touchscreen, it might seem a good idea to use an Android or an iOS tablet simply. However, it’s not. Here’s why:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-415"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-413">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-414'
	>
	<li>The users could exit the app. We would need to add workarounds to make the OS and our app behave like a kiosk.</li><li>Tablets don’t have a GPIO interface, so we couldn’t connect to low-level devices easily.</li><li>We don’t control the hardware. For the setup I’ve described we can buy a Raspberry Pi 3 and whatever touchscreen we need separately, for example a big 15″ touchscreen.</li><li>It’s expensive in comparison to buying a chip and a screen.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-418"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-416">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-417'
	>
	Chromium Kiosk mode or the Electron app</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-421"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-419">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-420'
	>
	There are other alternatives that can run on Raspberry Pi, for example the Chromium Kiosk mode or the Electron app. Although the setup is different, both solutions allow you to use popular web technologies (HTML, JS) to build the app. However, the downside is that there’s a lot of overhead when running these, which might impact the performance.<br>For example, in Chromium Kiosk mode you need to run full desktop Linux with the Chromium browser on top. The browser then runs your app, while with flutter-pi your app runs on “bare metal” Linux.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-424"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-422">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-423'
	>
	Another downside is that communication with the native platform and the external devices is limited. For example, communicating from Javascript to the bluetooth module requires complex bridging as Javascript was never intended to perform such things.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-427"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-425">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-426'
	>
	Qt</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-430"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-428">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-429'
	>
	Qt works similar to Flutter, although it’s more focused on desktop and embedded devices. You write Qt apps in C++, which is a less popular and lower level language.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-433"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-431">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-432'
	>
	Qt is better integrated with the platform so it’s somewhat easier to communicate with the native platform and the external devices.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-436"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-434">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-435'
	>
	Other than language, Qt’s downside is that it’s not completely free. Also, it’s much older than Flutter, and Flutter brings some improvements in terms of performance and UI building.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-439"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-437">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-438'
	>
	The future of Flutter</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-442"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-440">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-441'
	>
	When Flutter was first introduced, it could only run on iOS and Android. The first time I tried Flutter for desktop, I used a third-party embedder in a similar way as with Raspberry Pi. Today, Flutter desktop has an official beta release, so we can only expect it to continue to evolve and support embedded platforms in the same way.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-445"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-443">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-444'
	>
	I believe Flutter will become one of the best solutions for embedded devices with a screen. With examples like Toyota’s infotainment systems that <a href="https://twitter.com/flutterdev/status/1367174378387988480?lang=en">will be powered by Flutter</a> and Google’s Nest Hub that comes with <a href="https://9to5google.com/2021/05/25/google-releases-fuchsia-os-nest-hub/">Flutter running on Fuchsia OS</a>, the future’s looking bright.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/flutter-embedded-device/">Are Embedded Devices the Future of Flutter?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7922https://infinum.com/uploads/2020/02/flutter-might-be-your-technology-of-choice-for-mobile-in-2020-0.webp</url>
				</image>
				<title>Flutter Might Be Your Technology of Choice for Mobile in 2020 – Here Is Why</title>
				<link>https://infinum.com/blog/flutter-might-be-your-technology-of-choice-for-mobile-in-2020/</link>
				<pubDate>Mon, 17 Feb 2020 11:35:00 +0000</pubDate>
				<dc:creator>Josip Krnjić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/flutter-might-be-your-technology-of-choice-for-mobile-in-2020/</guid>
				<description>
					<![CDATA[<p>Could the Flutter UI framework finally produce a native look and feel on mobile while writing the code just once?</p>
<p>The post <a href="https://infinum.com/blog/flutter-might-be-your-technology-of-choice-for-mobile-in-2020/">Flutter Might Be Your Technology of Choice for Mobile in 2020 – Here Is Why</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-559"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-448">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-451"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-449">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-450'
	>
	Perhaps you’ve heard about <a href="https://flutter.dev/">Flutter</a> lately. It’s a pretty hot topic in mobile development, specifically cross-platform mobile development.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-454"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-452">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-453'
	>
	“Oh, another cross-platform solution? This is becoming like all those new JS frameworks”, you might think. It was my first reaction and probably the reaction of many others.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-457"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-455">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-456'
	>
	Don’t judge too quickly though because Flutter is not “another solution”.<br><br>It’s a new approach.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-460"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-458">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-459'
	>
	Web-based solutions</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-463"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-461">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-462'
	>
	Let’s take a look at how cross-platform mobile development evolved.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-466"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-464">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-465'
	>
	<strong>Android</strong> and <strong>iOS</strong> SDKs were both published in 2008. Apps developed with these SDKs are usually called “native apps”. Already in 2009, the first cross-platform solution appeared — <a href="https://phonegap.com/">PhoneGap</a>. You might’ve heard of <a href="https://cordova.apache.org/">Cordova</a>, that’s basically the core of PhoneGap that’s open-sourced.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-469"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-467">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-468'
	>
	Making an app with Cordova is like making an app that’s a web browser that only opens your page. It doesn’t deliver the best user experience a native app can do and that’s why both Google and Apple are not really fans of these apps flooding their stores.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-472"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-470">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-471'
	>
	Then there’s <a href="https://ionicframework.com/">Ionic</a>, which uses Cordova as a core. Introduced in 2013, it’s a better, well-rounded solution packed with modern JS frameworks. The downside is that it has the same limitations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-475"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-473">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-474'
	>
	Moving on to…</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-478"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-476">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-477'
	>
	Native-bind solutions: React Native, Xamarin</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-481"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-479">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-480'
	>
	In 2009, we also see the start of a different kind of cross-platform development. Around the same time, a lesser-known solution was introduced – <a href="https://www.appcelerator.com/">Appcelerator Titanium</a>. Instead of just showing everything as a web page, it can show native views just like native apps.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-484"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-482">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-483'
	>
	For example, in Titanium you can write <code>&lt;Label&gt;Hello World&lt;/Label&gt;</code> (yes, you can write in HTMLish) and this would use <code>UILabel</code> on iOS and <code>TextView</code> when running on Android.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-487"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-485">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-486'
	>
	At first, this looked great. You’re writing your code once and it works just like a native application on both platforms. No wonder other solutions decided to use a similar approach.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-490"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-488">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-489'
	>
	The first one to follow into the steps of Titanium was <a href="https://dotnet.microsoft.com/apps/xamarin">Xamarin</a> in 2013 (later acquired by Microsoft). After Xamarin, <a href="https://facebook.github.io/react-native/">React Native</a> came out in 2015. As I write this, React Native is the most popular cross-platform solution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-493"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-491">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-492'
	>
	It’s important to note that React Native still runs JavaScript. This means it needs to be interpreted and data needs to pass the bridge from the JS interpreter to the native environment. This results in lower performance. If you don’t know what you’re doing, you might pass this bridge every frame, which can result in dropped frames and jank.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-498"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-494">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-495'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-496'
	>
	Overall, native-bind solutions didn’t prove they could do what all cross-platform development want to do – write the code once and run it on multiple platforms.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-501"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-499">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-500'
	>
	It <em>can</em> work for simple cases, like the binding of that label in Titanium. But for any real-world app, bindings are not always that straightforward and what you end up with is being able to share only the business logic part of your codebase, and writing separate UI for each platform.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-504"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-502">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-503'
	>
	One example is the good ol’ button. In Android, there is no border property to change it for the button. Instead, you need to use shape XML, so you need reimplemented native views or custom renderers to overcome this limitation. This was really tricky for Xamarin which tried to support all kinds of platforms besides iOS and Android, like Windows Phone and Tizen OS.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-507"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-505">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-506'
	>
	That’s why it is not only difficult but also not advised to write UI for two platforms. React Native has a philosophy of “Learn once, write anywhere,” which means often you’ll write UI part of your code two times for both platforms.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-510"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-508">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-509'
	>
	Xamarin also isn’t advised for advanced apps that require native feel or custom UI:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-513"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-511"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-512">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2020/02/flutter-might-be-your-technology-of-choice-for-mobile-in-2020-1-1400x910.webp				media='(max-width: 699px)'
				type=image/webp								height="910"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2020/02/flutter-might-be-your-technology-of-choice-for-mobile-in-2020-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1040"
															width="1600"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Xamarin.Forms are true hybrid, but only works for the simplest of apps (source: xamarin.com)		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-516"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-514">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-515'
	>
	Flutter – a UI framework not trying to replace native development</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-519"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-517">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-518'
	>
	And then came <strong>Flutter</strong>. Not part of web-based or native-bind solutions, but completely different. For starters, it’s a UI framework and it’s not trying to replace native development. The code is not run by a separate interpreter, as Javascript might do. It’s compiled to machine code, just like the native apps.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-522"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-520">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-521'
	>
	How do native apps draw to screen anyway? Well, they are all just drawing graphic primitives on a canvas – think tiny lines, circles, and rectangles. TextView and UILabel are drawing text on the canvas and extending View or UIView.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-525"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-523">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-524'
	>
	The native-bind solutions (React Native, Xamarin…) have abstraction on the level of view, e.g. Label will be TextView or UILabel. Flutter works on a different level, the canvas is abstracted. When you use Text, that view (or widget as it is called) is rebuilt from the ground up by the Flutter team on this new abstracted canvas. It will look the same in both apps since all canvas operations work the same.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-528"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-526">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-527'
	>
	In fact, every component is rebuilt from the ground up on that new canvas. This was the only way to achieve a true cross-platform way of “writing once, running everywhere”.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-531"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-529">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-530'
	>
	For the Flutter team, this also meant that they need to copy the look and feel of native apps into their new rebuilt components.<br>For example, Android TextView has 14k lines of code and all its behaviors had to be recreated from the clear canvas in this new Text widget. Every component like button, checkbox, switch, app bar and even scroll behaviors are copied down to pixel-perfection.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-534"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-532"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-533">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2020/02/flutter-might-be-your-technology-of-choice-for-mobile-in-2020-2.gif"
					class="image__img block-media__image-img"
					alt=""
										height="336"
															width="600"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Example of an app that’s used by the Flutter team to measure and replicate unique scroll on each platform		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-537"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-535">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-536'
	>
	One might conclude that drawing in Flutter is the same as what the now deprecated Adobe Flash or game engines like Unity are doing. It’s true that they both take the whole canvas and then work in a way that can run the same code and draw to that canvas (whichever platform it is).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-540"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-538">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-539'
	>
	But they were never about mobile phones. Flash performance was notoriously bad so it was restricted on iOS way back in 2010. Unity started on desktop and struggles with resources on mobile.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-543"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-541">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-542'
	>
	The time is right for Flutter</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-546"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-544">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-545'
	>
	Flutter came just at the right time. The idea of <a href="https://flutter.dev/docs/resources/faq#run-android">compilation to ARM and machine code</a>, <a href="https://llvm.org/">LLVM compiler</a>, and using the Dart engine with all the performance optimizations and memory management makes it possible to finally achieve a native look and feel on mobile while writing once.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-549"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-547">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-548'
	>
	It has been in development for a few years now – in December 2018, it hit 1.0. The only thing that’s missing now is wide adoption.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-554"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-550">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-551'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-552'
	>
	Almost all developers have heard about React Native, but not that many have heard of Flutter.</p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-557"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-555">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-556'
	>
	The difference is even bigger for non-developers, like business stakeholders. Since the industry is talking about native and React Native, they can see Flutter as a risky new technology. But bear in mind, React Native was once also in this state. In case you need more than a hunch to believe 2020 could be the year when Flutter takes off, here’s a bone to chew on – it has already <a href="https://hasflutterpassedreactnativeyet.surge.sh/">passed React Native</a> in stars on Github, signaling strong popularity.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/flutter-might-be-your-technology-of-choice-for-mobile-in-2020/">Flutter Might Be Your Technology of Choice for Mobile in 2020 – Here Is Why</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7887https://infinum.com/uploads/2019/11/creating-custom-markers-on-google-maps-in-flutter-apps-0.webp</url>
				</image>
				<title>Creating Custom Markers on Google Maps in Flutter Apps</title>
				<link>https://infinum.com/blog/creating-custom-markers-on-google-maps-in-flutter-apps/</link>
				<pubDate>Tue, 26 Nov 2019 13:45:00 +0000</pubDate>
				<dc:creator>Josip Krnjić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/creating-custom-markers-on-google-maps-in-flutter-apps/</guid>
				<description>
					<![CDATA[<p>When you are trying to show maps in your Flutter application, you can either use flutter_map or google_maps_flutter.</p>
<p>The post <a href="https://infinum.com/blog/creating-custom-markers-on-google-maps-in-flutter-apps/">Creating Custom Markers on Google Maps in Flutter Apps</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-658"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-560">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-563"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-561">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-562'
	>
	When it comes to showing maps in your Flutter application, there are two main options. You can either use <a href="https://pub.dev/packages/flutter_map"><code>flutter_map</code></a> which is a Leaflet implementation for Flutter and will work with a number of free and paid map providers, or use <a href="https://pub.dev/packages/google_maps_flutter"><code>google_maps_flutter</code></a> if you want the more popular Google Maps.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-566"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-564">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-565'
	>
	For this blog post, I will be using <code>google_maps_flutter</code>, which is made and maintained by the Flutter team at Google.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-569"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-567">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-568'
	>
	If this is your first time using Google Maps I recommend checking out Google <a href="https://codelabs.developers.google.com/codelabs/google-maps-in-flutter/">codelab</a> for maps in Flutter. What I needed was to draw some custom markers like those in the image below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-572"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-570"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-auto" data-id="es-571">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/creating-custom-markers-on-google-maps-in-flutter-apps-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="349"
															width="464"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			Example of what we are trying to achieve		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-575"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-573">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-574'
	>
	You would expect that you could pass a <code>Widget</code> for marker, just like when using anything else in Flutter. But it’s not that easy as <code>Marker</code> accepts <code>BitmapDescriptor</code> for the icon. I’m going to explain how you can achieve that.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-578"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-576">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-577'
	>
	The Native way</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-581"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-579">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-580'
	>
	What is the <a href="https://developers.google.com/android/reference/com/google/android/gms/maps/model/BitmapDescriptor"><code>BitmapDescriptor</code></a>? If you’ve ever worked with iOS or Android native Google Maps SDK this will not surprise you.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-584"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-582">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-583'
	>
	<code>BitmapDescriptor</code> is an object that defines bitmap which can then be used by Google Maps to draw it on a map. It is used in both platforms and it’s the only way you can add custom icons for markers. So, this limitation comes from the native Google Maps SDK which <code>google_maps_flutter</code> uses, as there is no full flutter implementation for a complex widget like maps yet.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-587"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-585">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-586'
	>
	<code>BitmapDescriptor</code> will accept an asset image or a bitmap. For our case, marker text is dynamic, so static asset image is not a good fit. As for a bitmap, in native Android/iOS there’s a way to convert your <code>View</code> to <code>Bitmap</code> (or <code>UIView</code> to <code>UIImage</code>) and you can pass that to <code>BitmapDescriptor</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-590"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-588">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-589'
	>
	The Flutter way</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-593"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-591">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-592'
	>
	You can do it the same way in the Flutter, but it’s a bit trickier. Mostly because you cannot inflate/load a widget somewhere on the side and convert that to bitmap. You need to draw a widget in the screen view hierarchy and then fetch its painted bitmap.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-596"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-594">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-595'
	>
	The key thing you need to know is that each <code>Widget</code> is more like data class and you access bitmap in its associated <a href="https://api.flutter.dev/flutter/rendering/RenderObject-class.html"><code>RenderObject</code></a>, which gets created during the build phase.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-599"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-597">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-598'
	>
	1. Getting the <code>RenderObject</code></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-602"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-600">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-601'
	>
	Draw your widget to the screen. This is from some widgets build method that will inflate our markers. We use <a href="https://api.flutter.dev/flutter/widgets/GlobalKey-class.html"><code>GlobalKey</code></a> so we have reference to this widget after it’s built.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-604"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">final</span><span class="token"> markerKey </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">GlobalKey</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">RepaintBoundary</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">  key</span><span class="token" style="color: #d73a49;">:</span><span class="token"> markerKey</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">  child</span><span class="token" style="color: #d73a49;">:</span><span class="token"> customMarkerWidget</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-605">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-606'
	>
	Now you can put that <code>GlobalKey</code> to use after the widget is built:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-609"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">markerKey</span><span class="token">.</span><span class="token" style="color: #24292e;">currentContext</span><span class="token">.</span><span class="token" style="color: #6f42c1;">findRenderObject</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-612"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-610">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-611'
	>
	2. Converting to Uint8List</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-615"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-613">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-614'
	>
	<a href="https://api.dartlang.org/stable/2.6.1/dart-typed_data/Uint8List-class.html"><code>Uint8List</code></a> is basically a list of unsigned integers that represents bitmap in this case as there is no special Bitmap class in the dart. <code>BitmapDescriptor</code> will also accept <code>Uint8List</code> so we need to do some converting to get from <code>RenderObject</code> to <code>Uint8List</code>. I have all that in the following method:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-617"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">Future</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">Uint8List</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #6f42c1;">getUint8List</span><span class="token">(</span><span class="token" style="color: #24292e;">GlobalKey</span><span class="token"> markerKey</span><span class="token">)</span><span class="token"> async </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #24292e;">RenderRepaintBoundary</span><span class="token"> </span><span class="token" style="color: #24292e;">boundary</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #24292e;">markerKey</span><span class="token">.</span><span class="token" style="color: #24292e;">currentContext</span><span class="token">.</span><span class="token" style="color: #6f42c1;">findRenderObject</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #24292e;">image</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> await </span><span class="token" style="color: #24292e;">boundary</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toImage</span><span class="token">(</span><span class="token">pixelRatio</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #005cc5;">2.0</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #24292e;">ByteData</span><span class="token"> </span><span class="token" style="color: #24292e;">byteData</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> await </span><span class="token" style="color: #24292e;">image</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toByteData</span><span class="token">(</span><span class="token">format</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">ui</span><span class="token">.</span><span class="token" style="color: #24292e;">ImageByteFormat</span><span class="token">.</span><span class="token" style="color: #24292e;">png</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #24292e;">byteData</span><span class="token">.</span><span class="token" style="color: #24292e;">buffer</span><span class="token">.</span><span class="token" style="color: #6f42c1;">asUint8List</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-620"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-618">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-619'
	>
	3. When is widget finished with the build?</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-623"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-621">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-622'
	>
	I’ve shown you how to get <code>RenderObject</code> and convert it to <code>Uint8List</code>, but when do you call this method?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-626"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-624">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-625'
	>
	We need to get our bitmaps right after they are drawn. There are multiple ways to do this, I use tiny <code>AfterLayoutMixin</code> available <a href="https://pub.dev/packages/after_layout">here</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-628"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">override</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">void</span><span class="token"> </span><span class="token" style="color: #6f42c1;">afterFirstLayout</span><span class="token">(</span><span class="token" style="color: #24292e;">BuildContext</span><span class="token"> context</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">getUint8List</span><span class="token">(</span><span class="token">markerKey</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">then</span><span class="token">(</span><span class="token">(</span><span class="token">markerBitmap</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Set state and use your markerBitmap</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">  </span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-631"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-629">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-630'
	>
	4. Create the Marker</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-634"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-632">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-633'
	>
	There you have it. Create the <code>Marker</code> with <code>Uint8List</code> and plug it into the Google Map:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-636"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">Marker</span><span class="token">(</span><span class="token">
</span></span><span class="line"><span class="token">    position</span><span class="token" style="color: #d73a49;">:</span><span class="token"> position</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    icon</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">BitmapDescriptor</span><span class="token">.</span><span class="token" style="color: #6f42c1;">fromBytes</span><span class="token">(</span><span class="token">markerUint8List</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-639"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-637">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-638'
	>
	You should end up with something like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-642"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-640"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-auto" data-id="es-641">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/12/creating-custom-markers-on-google-maps-in-flutter-apps-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="568"
															width="670"
										loading="lazy"
					 />
					</picture>

			<figcaption class="image__figcaption block-media__image-figcaption">
			That looks like a fun roadtrip		</figcaption>
	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-645"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-643">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-644'
	>
	I have extracted all this in one simple-to-use class <code>MarkerGenerator</code>. It’s a bit more advanced than the guide explained here. It uses an <a href="https://api.flutter.dev/flutter/widgets/Overlay-class.html"><code>overlay</code></a> to build marker widgets and provide <code>List&lt;Uint8List&gt;</code> through the callback. The gist is available <a href="https://gist.github.com/itsJoKr/ce5ec57bd6dedf74d1737c1f39481913">here</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-648"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-646">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-647'
	>
	Copy it to your project. Then you use <code>MarkerGenerator</code> this way:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-650"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">override</span><span class="token">  </span><span class="token" style="color: #d73a49;">void</span><span class="token"> </span><span class="token" style="color: #6f42c1;">initState</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">super</span><span class="token">.</span><span class="token" style="color: #6f42c1;">initState</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">     
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">MarkerGenerator</span><span class="token">(</span><span class="token">markerWidgets</span><span class="token">,</span><span class="token"> </span><span class="token">(</span><span class="token">bitmaps</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">      
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">setState</span><span class="token">(</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">        
</span></span><span class="line"><span class="token">            markers </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">mapBitmapsToMarkers</span><span class="token">(</span><span class="token">bitmaps</span><span class="token">)</span><span class="token">;</span><span class="token">      
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">generate</span><span class="token">(</span><span class="token">context</span><span class="token">)</span><span class="token">;</span><span class="token">  
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-653"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-651">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-652'
	>
	Time flies, Flutter saves it</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-656"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-654">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-655'
	>
	When working in Flutter, some things take more time as opposed to writing them in native Android/iOS, as it happened this time with custom map markers. But overall, I believe that Flutter is definitely a timesaver and a great choice for most apps.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/creating-custom-markers-on-google-maps-in-flutter-apps/">Creating Custom Markers on Google Maps in Flutter Apps</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>7915https://infinum.com/uploads/2019/07/bitrise-vs-circleci-for-android-in-a-head-to-head-battle-0.webp</url>
				</image>
				<title>Bitrise vs. CircleCI for Android in a Head-to-Head Battle</title>
				<link>https://infinum.com/blog/bitrise-vs-circleci-for-android-in-a-head-to-head-battle/</link>
				<pubDate>Tue, 06 Aug 2019 10:45:00 +0000</pubDate>
				<dc:creator>Josip Krnjić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/bitrise-vs-circleci-for-android-in-a-head-to-head-battle/</guid>
				<description>
					<![CDATA[<p>The best CI is the one that engineers waste the least time on so they can focus on development more. Is Bitrise it?</p>
<p>The post <a href="https://infinum.com/blog/bitrise-vs-circleci-for-android-in-a-head-to-head-battle/">Bitrise vs. CircleCI for Android in a Head-to-Head Battle</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-775"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-659">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-662"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-660">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-661'
	>
	In mobile development, usually, developers are the ones who will set up and maintain CI/CD. In that sense, the best CI is the one they waste the least time on so they can focus on development more.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-665"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-663">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-664'
	>
	The Android team here at Infinum have been using CircleCI for a few years and <strong>recently migrated the majority of projects to Bitrise</strong>—a newer continuous integration and delivery (CI/CD) service made for mobile apps. This means that it’s focused just on that and provides great service in that field.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-668"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-666">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-667'
	>
	On the other hand, while <strong>CircleCI</strong> provides a more generic solution suitable for any type of project, it might require just a bit more configuration.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-671"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-669">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-670'
	>
	Pricing</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-674"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-672">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-673'
	>
	In CircleCI’s free option you get one container with 1000 build minutes per month. Meanwhile, the free option in Bitrise features somewhat limiting 10 minutes per build.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-677"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-675">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-676'
	>
	For concurrencies, both Bitrise and Circle have similar pricing:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-680"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-678"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-679">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2019/07/bitrise-vs-circleci-for-android-in-a-head-to-head-battle-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="786"
															width="1150"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-683"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-681">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-682'
	>
	If you need 2 or 3 concurrencies, you might want to consider the difference in the pricing, as Circle can be cheaper. Otherwise, both are in the similar price range so that shouldn’t be the deciding factor.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-686"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-684">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-685'
	>
	Performance</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-689"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-687">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-688'
	>
	There’s no point in comparing the pricing without looking at what you get for the money.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-692"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-690">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-691'
	>
	Both machines have similar Intel Xeon and you’ll get 2 vCPU. The only difference is that on Bitrise you’re getting 8GB of RAM compared to Circle 4GB, which can be a big deal. These are the standard options and you can pay for additional ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-695"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-693">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-694'
	>
	Need more power? Bitrise standard option with 8GB of RAM should be enough for most projects. If you need more power, you can get elite machines which are pretty much double the resources (4 vCPU, 16GB RAM) for double the money.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-698"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-696">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-697'
	>
	This doesn’t mean that your build times will be two times as fast. Gradle tasks don’t fully utilize all the resources and multithreading so from our experience you can expect about 20% faster builds.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-701"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-699">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-700'
	>
	On CircleCI, the standard option with 4GB might just not be enough for some bigger projects. Unlike Bitrise that has only 2 options (standard and elite), CircleCI has 5 resource classes:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-704"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-702">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-703'
	>
	<li>Small: 1vCPU and 2GB RAM</li><li>Medium (default): 2 vCPU and 4GB RAM</li><li>Medium+: 3 vCPU and 6GB RAM</li><li>Large: 4 vCPU and 8GB RAM</li><li>XLarge: 8 vCPU and 16GB RAM</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-707"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-705">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-706'
	>
	Something you should be aware of is that there is no public pricing for CircleCI resource classes. You need to personally contact them to gain access. In our case, we got them for free for a limited time but then got unpleasantly surprised with the full price of the extra resources.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-710"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-708">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-709'
	>
	Ease of use</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-713"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-711">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-712'
	>
	The way CI was setup usually involved writing configuration files in JSON or YAML notation. For bigger projects, this config file would grow to levels that are hard to maintain.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-716"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-714">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-715'
	>
	Bitrise has a somewhat different approach to configuration. To start with, you don’t need to have a configuration file in your repo—you can just hold it in their web app. But Bitrise’s edge is the visual configuration editor which makes the whole setup much easier.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-719"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-717">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-718'
	>
	Each step is represented as one block in the editor. And with this, you don’t need to edit configuration files directly, you can just click through the visual editor. This is also much easier for developers who have never worked with a CI before. It takes time to learn how to read and write configuration file, and the editor is self-explanatory. Some of my colleagues didn’t like this editor as they were used to handwriting YAML files and didn’t want to switch. They can still continue to write files without using the visual editor.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-722"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-720"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-721">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2019/07/bitrise-vs-circleci-for-android-in-a-head-to-head-battle-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="777"
															width="1364"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-725"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-723">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-724'
	>
	Bitrise comes with the library of steps which contains a lot of predefined steps you might need, like Install missing Android dependencies, Android Build, Android Lint, etc. You can write your own step and open a request to merge it into the library.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-728"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-726">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-727'
	>
	Similar to the Bitrise library of steps are the CircleCI orbs. You have a public registry of orbs. Orbs are part of CircleCI 2.1, so they are a pretty recent thing. The problem I see here is that users don’t really need orbs and don’t want to bother updating to 2.1, so the adoption of orbs is low. Currently, there is just one useful orb for Android while on Bitrise there already are a lot of useful steps, with new ones coming regularly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-731"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-729">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-730'
	>
	One thing I would like to see is the possibility to write and share a step internally within the organization, which currently isn’t possible on either Bitrise or CircleCI.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-734"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-732">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-733'
	>
	Parallelism</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-737"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-735">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-736'
	>
	For some projects, we need to build several flavors of application. For these, we use parallel builds. Both Bitrise and CircleCI support parallel builds and are easy to set up. For Bitrise, you would have one workflow that initiates all the parallel workflows and waits for them to finish. This way, one container will always be used just to wait for others, which is not the case on CircleCI. That’s a plus for Circle!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-740"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-738">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-739'
	>
	UI Testing</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-743"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-741">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-742'
	>
	UI testing has always been one of the trickier things to set up on your CI/CD servers. A few years back, you had to create emulator image and start it, run UI tests, and then read text reports and somehow fetch that result back into the CI report.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-746"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-744">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-745'
	>
	There was a lot of room for this process to fail just because something went wrong while starting an emulator, and then your tests would be reported as failed. Plus, running emulator required a lot of resources on the build server.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-749"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-747">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-748'
	>
	In 2016, Firebase Test Lab was announced, which made things easier because it eliminated the need to work with an emulator. Still, it continued to be a pretty lengthy setup. There were multiple requirements—a Firebase project, hooking up the Google Cloud keys (for remote access to your project), and then running a few commands to send apk and run tests. This was the standard procedure in CircleCI, and this alone would add 30 lines to your .yml configuration.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-752"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-750">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-751'
	>
	With Bitrise, setting up UI testing is simple as it gets. There are two steps ready: “Android Build for UI Testing” and “[BETA] Virtual Device Testing”. You add these and that’s it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-755"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-753"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-auto" data-id="es-754">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2019/07/bitrise-vs-circleci-for-android-in-a-head-to-head-battle-3.webp"
					class="image__img block-media__image-img"
					alt=""
										height="194"
															width="470"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-758"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-756">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-757'
	>
	Google Play Deploy</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-761"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-759">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-760'
	>
	If you want to fully automate the whole process, you will probably want to deploy directly to Play Store from your build server. Using CircleCI, the best approach would be either to use fastlane or some bash script you can find online that does all the communication with Play Store to publish the .apk.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-764"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-762">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-763'
	>
	This is simplified on Bitrise with Google Play Deploy step. It accepts .apk or .aab and Play Store Service Account JSON (which is required for any remote access to the Play Store). So there’s another plus for Bitrise!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-767"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-765">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-766'
	>
	And the winner is…</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-770"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-768">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-769'
	>
	Bitrise workflow editor is a really innovative approach that saves us from .yml files and brings a simple interface that I enjoy using. The focus on mobile development is a big advantage and I can see this paying off even more in the future.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-773"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-771">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-772'
	>
	CircleCI looks to be taking a different approach. With 2.x, there are some changes that you really don’t need but can be very helpful in complex environments. Finally, if you don’t have a CI/CD and you are doing mobile development, Bitrise should be your first choice.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/bitrise-vs-circleci-for-android-in-a-head-to-head-battle/">Bitrise vs. CircleCI for Android in a Head-to-Head Battle</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>