<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>android Archives - CodeJourney.net</title>
	<atom:link href="https://www.codejourney.net/tag/android/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codejourney.net/tag/android/</link>
	<description>Become a better .NET full stack web developer</description>
	<lastBuildDate>Thu, 16 Jan 2020 04:15:19 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://i0.wp.com/www.codejourney.net/wp-content/uploads/2018/10/cropped-512px-na-512px-JPEG-BEZ-NAPISU-1.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>android Archives - CodeJourney.net</title>
	<link>https://www.codejourney.net/tag/android/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">123174533</site>	<item>
		<title>Basics of Flutter Widgets</title>
		<link>https://www.codejourney.net/basics-of-flutter-widgets/</link>
					<comments>https://www.codejourney.net/basics-of-flutter-widgets/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Thu, 16 Jan 2020 16:00:59 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[flutter]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3715</guid>

					<description><![CDATA[<p>What is a widget? If you ever worked with a web framework like React, you should know the concept of components. Flutter widgets are directly inspired by this idea. Widget is a reusable piece of code, which describes how your application&#8217;s UI looks like. Widgets define the user interface by their state. In some cases,&#8230;</p>
<p>The post <a href="https://www.codejourney.net/basics-of-flutter-widgets/">Basics of Flutter Widgets</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>After <a href="https://www.codejourney.net/2019/12/your-first-flutter-app-in-30-minutes/" target="_blank" rel="noopener noreferrer">writing our first Flutter app in less than 30 minutes</a>, today we&#8217;re taking a look at Flutter widgets. If you want to know what is a widget in Flutter, what are widgets types and how to use them &#8211; this article is for you <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-3715"></span>



<h2 class="wp-block-heading">What is a widget?</h2>



<p>If you ever worked with a web framework like <a rel="noreferrer noopener" aria-label="React (opens in a new tab)" href="https://reactjs.org/" target="_blank">React</a>, you should know the concept of <em>components</em>. Flutter widgets are directly inspired by this idea. Widget is a <strong>reusable piece of code, which describes how your application&#8217;s UI looks like</strong>. Widgets define the user interface by their <strong>state</strong>. In some cases, the state can be static and not change over time &#8211; see the <a href="#flutter-widget-types">section below about Flutter widget types</a> for details.</p>



<p>As soon as a widget&#8217;s state changes, Flutter rebuilds its outlook and in effect re-renders the GUI. The framework is said to do it efficiently by measuring what has changed in the widgets tree since the last rendering and re-paints only what&#8217;s necessary.</p>



<p>The most basic Flutter app might look as follows:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist100539783" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-main_simplest_app-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main_simplest_app.dart content, created by dsibinski on 02:13AM on January 13, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main_simplest_app.dart">
        <tr>
          <td id="file-main_simplest_app-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main_simplest_app-dart-LC1" class="blob-code blob-code-inner js-file-line">import &#39;package:flutter/material.dart&#39;;</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main_simplest_app-dart-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main_simplest_app-dart-LC3" class="blob-code blob-code-inner js-file-line">void main() =&gt; runApp(</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main_simplest_app-dart-LC4" class="blob-code blob-code-inner js-file-line">      Center(</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main_simplest_app-dart-LC5" class="blob-code blob-code-inner js-file-line">          child: Text(</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main_simplest_app-dart-LC6" class="blob-code blob-code-inner js-file-line">        &quot;Hello Flutter!&quot;,</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main_simplest_app-dart-LC7" class="blob-code blob-code-inner js-file-line">        textDirection: TextDirection.ltr,</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main_simplest_app-dart-LC8" class="blob-code blob-code-inner js-file-line">      )),</td>
        </tr>
        <tr>
          <td id="file-main_simplest_app-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main_simplest_app-dart-LC9" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
  </table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/e950a3cd710a539359a855752900c295/raw/23a6fec940a3c5e420ab9483a585f9ea495345d4/main_simplest_app.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/e950a3cd710a539359a855752900c295#file-main_simplest_app-dart" class="Link--inTextBlock">
          main_simplest_app.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>The<span style="color:#bb9d1b" class="tadv-color"> </span><span style="color:#f7bb1e" class="tadv-color">runApp()</span> method takes a <span style="color:#f7bb1e" class="tadv-color">Widget</span> as its argument. In our case, it takes a <span style="color:#f7bb1e" class="tadv-color">Center</span> widget, which has one child &#8211; a <span style="color:#f7bb1e" class="tadv-color">Text</span> widget. As expected, such a simple Flutter app shows a &#8220;Hello Flutter!&#8221; text at the center of the screen.</p>



<p>This simple example shows us a few interesting facts:</p>



<ul class="wp-block-list"><li>there are <strong>many built-in widgets</strong>, like <span style="color:#f7bb1e" class="tadv-color">Center</span> and <span style="color:#f7bb1e" class="tadv-color">Text</span></li><li><strong>widgets can have a child or children</strong> &#8211; this is <em>widgets nesting</em> and it happens all the time and can be very deep</li><li>Flutter <strong>widgets can have their own properties</strong>, like <span style="color:#f7bb1e" class="tadv-color">textDirection</span>.</li></ul>



<p>Widgets nesting sometimes makes simple Flutter apps having a lot of source code inside a single file. However, as I mentioned in <a rel="noreferrer noopener" aria-label="the previous post (opens in a new tab)" href="https://www.codejourney.net/2019/12/your-first-flutter-app-in-30-minutes/" target="_blank">the previous post</a>, don&#8217;t get discouraged by that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Actually, <strong>having a lot of nested widgets in Flutter is a good practice</strong>. If you have a few huge widgets without much nesting instead, it means that there&#8217;s something wrong with your implementation. Flutter widgets &#8211; as all reusable pieces of code &#8211; should not have too many responsibilities. <a rel="noreferrer noopener" aria-label="SOLID (opens in a new tab)" href="https://en.wikipedia.org/wiki/SOLID" target="_blank">SOLID</a> also applies here <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Viewing Flutter widgets with Flutter Inspector</h2>



<p>As widgets tree may get big and quite heavily nested, there&#8217;s a very useful tool to easily view and explore it. This tool is called <a rel="noreferrer noopener" aria-label="Flutter Inspector (opens in a new tab)" href="https://flutter.dev/docs/development/tools/devtools/inspector" target="_blank">Flutter Inspector</a>.</p>



<p>While in debug mode in Visual Studio Code, you can launch it by clicking the blue magnifier icon:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="866" height="174" data-attachment-id="3727" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/image/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?fit=866%2C174&amp;ssl=1" data-orig-size="866,174" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?fit=300%2C60&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?fit=866%2C174&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=866%2C174&#038;ssl=1" alt="Flutter Widgets: blue magnifier button in VS Code which opens the widgets inspector" class="wp-image-3727" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?w=866&amp;ssl=1 866w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=300%2C60&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=768%2C154&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image.png?resize=676%2C136&amp;ssl=1 676w" sizes="(max-width: 866px) 100vw, 866px" /><figcaption>A button for opening Flutter Widgets Inspector from VS Code</figcaption></figure>



<p>It opens in a web browser and allows you to see the whole widgets tree in your app:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" decoding="async" width="950" height="1025" data-attachment-id="3728" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/image-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?fit=950%2C1025&amp;ssl=1" data-orig-size="950,1025" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image-1" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?fit=278%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?fit=950%2C1025&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=950%2C1025&#038;ssl=1" alt="Flutter Widgets: Dart DevTools widgets inspector" class="wp-image-3728" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?w=950&amp;ssl=1 950w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=278%2C300&amp;ssl=1 278w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=768%2C829&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/image-1.png?resize=676%2C729&amp;ssl=1 676w" sizes="(max-width: 950px) 100vw, 950px" /><figcaption>Flutter Inspector (part of Dart DevTools)</figcaption></figure>



<p>There&#8217;s a very handy feature &#8220;Select Widget Mode&#8221; which, when enabled, lets you select the widgets directly in your emulator or phone. After doing this, you can see the selected widget&#8217;s properties in the inspector.</p>



<h2 class="wp-block-heading" id="flutter-widget-types">Types of Flutter widgets</h2>



<p>In Flutter, you can &#8211; and will &#8211; create your own widgets. Widget is just a Dart class which extends a proper base class. Depending on whether your widget actually manages any state and changes over time, you have two types of base classes to inherit from &#8211; <a rel="noreferrer noopener" aria-label="StatelessWidget (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html" target="_blank">StatelessWidget</a> or <a rel="noreferrer noopener" aria-label="StatefulWidget (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html" target="_blank">StatefulWidget</a>.</p>



<p>The main purpose of each type of widget is to provide an implementation of a <span style="color:#f7bb1e" class="tadv-color">build() </span>method which returns a <span style="color:#f7bb1e" class="tadv-color">Widget</span> object. However, each widget type does it a bit differently. Let&#8217;s see this in action.</p>



<h3 class="wp-block-heading">StatelessWidgets</h3>



<p>The simplest widget you can create is a stateless widget. You create it by simply creating a class extending <a rel="noreferrer noopener" href="https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html" target="_blank">StatelessWidget</a>.  Here&#8217;s the sample source code and a view it generates:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-embed alignwide"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist100563362" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-main_stateless_widget-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main_stateless_widget.dart content, created by dsibinski on 03:36AM on January 14, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main_stateless_widget.dart">
        <tr>
          <td id="file-main_stateless_widget-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main_stateless_widget-dart-LC1" class="blob-code blob-code-inner js-file-line">import &#39;package:flutter/material.dart&#39;;</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main_stateless_widget-dart-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main_stateless_widget-dart-LC3" class="blob-code blob-code-inner js-file-line">void main() =&gt; runApp(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main_stateless_widget-dart-LC4" class="blob-code blob-code-inner js-file-line">      MaterialApp(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main_stateless_widget-dart-LC5" class="blob-code blob-code-inner js-file-line">        title: &quot;My CodeJourney Flutter app&quot;,</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main_stateless_widget-dart-LC6" class="blob-code blob-code-inner js-file-line">        home: Scaffold(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main_stateless_widget-dart-LC7" class="blob-code blob-code-inner js-file-line">          appBar: AppBar(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main_stateless_widget-dart-LC8" class="blob-code blob-code-inner js-file-line">            title: Text(&quot;My First App&quot;),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main_stateless_widget-dart-LC9" class="blob-code blob-code-inner js-file-line">          ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-main_stateless_widget-dart-LC10" class="blob-code blob-code-inner js-file-line">          body: MyFirstWidget(),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-main_stateless_widget-dart-LC11" class="blob-code blob-code-inner js-file-line">        ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-main_stateless_widget-dart-LC12" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-main_stateless_widget-dart-LC13" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-main_stateless_widget-dart-LC14" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-main_stateless_widget-dart-LC15" class="blob-code blob-code-inner js-file-line">class MyFirstWidget extends StatelessWidget {</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-main_stateless_widget-dart-LC16" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-main_stateless_widget-dart-LC17" class="blob-code blob-code-inner js-file-line">  Widget build(BuildContext context) {</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-main_stateless_widget-dart-LC18" class="blob-code blob-code-inner js-file-line">    return Container(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-main_stateless_widget-dart-LC19" class="blob-code blob-code-inner js-file-line">      padding: EdgeInsets.all(8.0),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-main_stateless_widget-dart-LC20" class="blob-code blob-code-inner js-file-line">      child: Text(</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-main_stateless_widget-dart-LC21" class="blob-code blob-code-inner js-file-line">        &quot;Hello MyFirstWidget!&quot;,</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-main_stateless_widget-dart-LC22" class="blob-code blob-code-inner js-file-line">        style: TextStyle(color: Colors.green),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-main_stateless_widget-dart-LC23" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-main_stateless_widget-dart-LC24" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-main_stateless_widget-dart-LC25" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main_stateless_widget-dart-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-main_stateless_widget-dart-LC26" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1a26fa1e212adbb858230f62183f7109/raw/28bd7f47b938fc6d295f3700c2550c5efe902b44/main_stateless_widget.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/1a26fa1e212adbb858230f62183f7109#file-main_stateless_widget-dart" class="Link--inTextBlock">
          main_stateless_widget.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

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



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image alignwide size-large"><img decoding="async" width="1080" height="1920" data-attachment-id="3731" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_statelesswidget/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_statelessWidget" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=576%2C1024&amp;ssl=1" src="https://i1.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?fit=576%2C1024&amp;ssl=1" alt="" class="wp-image-3731" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=864%2C1536&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statelessWidget.png?resize=676%2C1202&amp;ssl=1 676w" sizes="(max-width: 1080px) 100vw, 1080px" /></figure>


</div>
</div>



<p>You can play with it yourself <a rel="noreferrer noopener" aria-label="in the DartPad (opens in a new tab)" href="https://dartpad.dev/1a26fa1e212adbb858230f62183f7109" target="_blank">in the DartPad</a>.</p>



<p>There are quite a few new things in the source code. Let&#8217;s point them out:</p>



<ul class="wp-block-list"><li>as our main widget, we used <span style="color:#f7bb1e" class="tadv-color">MaterialApp</span> and provided it to <span style="color:#f7bb1e" class="tadv-color">runApp()</span> method. MaterialApp widget gives us material design for our app out of the box. As soon as you use it, you can nest more material widgets from the <a rel="noreferrer noopener" aria-label="widgets library (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets/material" target="_blank">widgets library</a>. There&#8217;s a similar widget for Apple-oriented widgets called <a rel="noreferrer noopener" aria-label="CupertinoApp (opens in a new tab)" href="https://api.flutter.dev/flutter/cupertino/CupertinoApp-class.html" target="_blank">CupertinoApp</a>, which allows using <a rel="noreferrer noopener" aria-label="Cupertino widgets (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets/cupertino" target="_blank">Cupertino widgets</a></li><li>we used another material widget &#8211; a <span style="color:#f7bb1e" class="tadv-color">Scaffold</span>. It provides us with an <span style="color:#f7bb1e" class="tadv-color">appBar</span> and <span style="color:#f7bb1e" class="tadv-color">body</span> properties &#8211; setting them we&#8217;re getting this nice-looking application&#8217;s skeleton with entitled app bar and home for our widget. Scaffold also gives us many things &#8220;for free&#8221;, e.g.  <a rel="noreferrer noopener" href="https://api.flutter.dev/flutter/material/FloatingActionButton-class.html" target="_blank">FloatingActionButton</a></li><li><span style="color:#f7bb1e" class="tadv-color">body</span> of our <span style="color:#f7bb1e" class="tadv-color">Scaffold</span> is our first own stateless widget &#8211; <span style="color:#f7bb1e" class="tadv-color">MyFirstWidget</span>. As mentioned before, it overrides the <span style="color:#f7bb1e" class="tadv-color">build()</span> method, which simply returns another widget tree. Notice the usage of a <span style="color:#f7bb1e" class="tadv-color">Container</span> widget, which is very useful for grouping other widgets.</li></ul>



<p>StatelessWidget is simple, works and is just there <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Let&#8217;s see something more interesting now &#8211; StatefulWidgets.</p>



<h3 class="wp-block-heading">StatefulWidgets</h3>



<p>When you want your widget to change over time and maintain its state (in most cases you do), you can create a stateful widget. You do it by creating a Dart class extending <a rel="noreferrer noopener" aria-label="StatefulWidget (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html" target="_blank">StatefulWidget</a>. Unlike StatelessWidgets, StatefulWidget doesn&#8217;t override the <span style="color:#f7bb1e" class="tadv-color">build()</span> method. Instead, it implements a <span style="color:#f7bb1e" class="tadv-color">createState()</span> method, which creates the initial widget&#8217;s state (see below).</p>



<p>Apart from the main widget class, which itself is still &#8220;final&#8221; (or better said &#8211; immutable), you create a class extending <a rel="noreferrer noopener" aria-label="State (opens in a new tab)" href="https://api.flutter.dev/flutter/widgets/State-class.html" target="_blank">State</a>. This class maintains the actual state and it is now who provides the <span style="color:#f7bb1e" class="tadv-color">build()</span> method&#8217;s implementation.</p>



<p>Let&#8217;s see the sample code and produced GUI:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<figure class="wp-block-embed alignwide"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist100605434" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-main_stateful_widget-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main_stateful_widget.dart content, created by dsibinski on 11:31PM on January 15, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main_stateful_widget.dart">
        <tr>
          <td id="file-main_stateful_widget-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main_stateful_widget-dart-LC1" class="blob-code blob-code-inner js-file-line">class MySecondWidget extends StatefulWidget {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main_stateful_widget-dart-LC2" class="blob-code blob-code-inner js-file-line">  MySecondWidget({Key key}) : super(key: key);</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main_stateful_widget-dart-LC3" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main_stateful_widget-dart-LC4" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main_stateful_widget-dart-LC5" class="blob-code blob-code-inner js-file-line">  _MySecondWidgetState createState() =&gt; </td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main_stateful_widget-dart-LC6" class="blob-code blob-code-inner js-file-line">                _MySecondWidgetState();</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main_stateful_widget-dart-LC7" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main_stateful_widget-dart-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main_stateful_widget-dart-LC9" class="blob-code blob-code-inner js-file-line">class _MySecondWidgetState extends State&lt;MySecondWidget&gt; {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-main_stateful_widget-dart-LC10" class="blob-code blob-code-inner js-file-line">  int _clickCount = 0;</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-main_stateful_widget-dart-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-main_stateful_widget-dart-LC12" class="blob-code blob-code-inner js-file-line">  void incrementClickCount() {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-main_stateful_widget-dart-LC13" class="blob-code blob-code-inner js-file-line">    setState(() {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-main_stateful_widget-dart-LC14" class="blob-code blob-code-inner js-file-line">      this._clickCount++;</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-main_stateful_widget-dart-LC15" class="blob-code blob-code-inner js-file-line">    });</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-main_stateful_widget-dart-LC16" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-main_stateful_widget-dart-LC17" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-main_stateful_widget-dart-LC18" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-main_stateful_widget-dart-LC19" class="blob-code blob-code-inner js-file-line">  Widget build(BuildContext context) {</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-main_stateful_widget-dart-LC20" class="blob-code blob-code-inner js-file-line">    return Scaffold(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-main_stateful_widget-dart-LC21" class="blob-code blob-code-inner js-file-line">      appBar: AppBar(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-main_stateful_widget-dart-LC22" class="blob-code blob-code-inner js-file-line">        title: Text(&quot;My First App&quot;),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-main_stateful_widget-dart-LC23" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-main_stateful_widget-dart-LC24" class="blob-code blob-code-inner js-file-line">      body: Container(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-main_stateful_widget-dart-LC25" class="blob-code blob-code-inner js-file-line">        padding: EdgeInsets.all(8.0),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-main_stateful_widget-dart-LC26" class="blob-code blob-code-inner js-file-line">        child: Text(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-main_stateful_widget-dart-LC27" class="blob-code blob-code-inner js-file-line">          &quot;Hello! Times clicked: &quot; </td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-main_stateful_widget-dart-LC28" class="blob-code blob-code-inner js-file-line">                + this._clickCount.toString(),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-main_stateful_widget-dart-LC29" class="blob-code blob-code-inner js-file-line">          style: TextStyle(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-main_stateful_widget-dart-LC30" class="blob-code blob-code-inner js-file-line">            color: Colors.green, </td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-main_stateful_widget-dart-LC31" class="blob-code blob-code-inner js-file-line">            fontSize: 20.0),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-main_stateful_widget-dart-LC32" class="blob-code blob-code-inner js-file-line">        ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-main_stateful_widget-dart-LC33" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-main_stateful_widget-dart-LC34" class="blob-code blob-code-inner js-file-line">      floatingActionButton: FloatingActionButton(</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-main_stateful_widget-dart-LC35" class="blob-code blob-code-inner js-file-line">        child: Icon(Icons.add),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-main_stateful_widget-dart-LC36" class="blob-code blob-code-inner js-file-line">        onPressed: this.incrementClickCount,</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-main_stateful_widget-dart-LC37" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-main_stateful_widget-dart-LC38" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-main_stateful_widget-dart-LC39" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main_stateful_widget-dart-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-main_stateful_widget-dart-LC40" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/74e2318c87f611ce3b8e2f0dab817567/raw/55cbf4b0cf9f29e6f855c04d36a5a361bad588fc/main_stateful_widget.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/74e2318c87f611ce3b8e2f0dab817567#file-main_stateful_widget-dart" class="Link--inTextBlock">
          main_stateful_widget.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

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



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image alignwide size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="576" height="1024" data-attachment-id="3745" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_statefulwidget-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_statefulWidget-1" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?fit=576%2C1024&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=576%2C1024&#038;ssl=1" alt="" class="wp-image-3745" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=864%2C1536&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?resize=676%2C1202&amp;ssl=1 676w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_statefulWidget-1.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 576px) 100vw, 576px" /></figure>
</div>
</div>



<p>The full code you can play with is available <a rel="noreferrer noopener" aria-label="in the DartPad (opens in a new tab)" href="https://dartpad.dev/6a140d19910f60d03e8752b1a3b7f083" target="_blank">in the DartPad</a>.</p>



<p>Now some comments about the StatefulWidget code:</p>



<ul class="wp-block-list"><li>notice how <span style="color:#f7bb1e" class="tadv-color">MySecondWidget</span> class passes a <span style="color:#f7bb1e" class="tadv-color">key</span> to its superclass. Concept of Flutter widgets keys is interesting and we&#8217;ll dig into it in a separate post. For now, just treat it as a convention to always accept a <span style="color:#f7bb1e" class="tadv-color">key</span> as a named argument and pass it to the base class</li><li>as said before, in this simple example, <span style="color:#f7bb1e" class="tadv-color">MySecondWidget</span> only creates the initial state by instantiating <span style="color:#f7bb1e" class="tadv-color">_MySecondWidgetState</span></li><li>you&#8217;re already familiar with most of the code in <span style="color:#f7bb1e" class="tadv-color">_MySecondWidgetState</span>, but notice the usage of <span style="color:#f7bb1e" class="tadv-color">setState()</span> in <span style="color:#f7bb1e" class="tadv-color">incrementClickCount()</span> function. It tells Flutter that the state has changed, so the framework can re-render the UI. If you directly change the value of <span style="color:#f7bb1e" class="tadv-color">this._clickCount</span> without calling <span style="color:#f7bb1e" class="tadv-color">setState()</span>, GUI will not be updated until <span style="color:#f7bb1e" class="tadv-color">setState()</span> is called in some other place. We&#8217;ll talk more about state management techniques in Flutter in the future articles</li><li>note how easy it is to add a <span style="color:#f7bb1e" class="tadv-color">FloatingActionButton</span> thanks to using <a rel="noreferrer noopener" aria-label="Scaffold (opens in a new tab)" href="https://api.flutter.dev/flutter/material/Scaffold-class.html" target="_blank">Scaffold</a> material widget.</li></ul>



<p>That was easy and works nicely! You now know how to use both Flutter widget types <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4aa.png" alt="💪" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Flutter quick actions in VS Code</h2>



<p>I&#8217;d like to share with you two easy tips for working with Flutter in Visual Studio Code. Both speed up the development nicely. It assumes that you configured VS Code properly (if not read <a href="https://www.codejourney.net/2019/12/your-first-flutter-app-in-30-minutes/" target="_blank" rel="noreferrer noopener" aria-label="this article (opens in a new tab)">this article</a>) and have Flutter extension installed.</p>



<h3 class="wp-block-heading">Ctrl + .</h3>



<p>First important keyboard shortcut is <em>Ctrl</em>+<em>.</em> (<em>Cmd</em>+<em>.</em> on Mac). It allows you to perform many element-contextual actions. For me it&#8217;s most useful for removing widgets or wrapping widgets with other ones:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="3760" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_quickactions/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?fit=418%2C409&amp;ssl=1" data-orig-size="418,409" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_quickActions" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?fit=300%2C294&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?fit=418%2C409&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?resize=314%2C307&#038;ssl=1" alt="" class="wp-image-3760" width="314" height="307" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?w=418&amp;ssl=1 418w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_quickActions.png?resize=300%2C294&amp;ssl=1 300w" sizes="auto, (max-width: 314px) 100vw, 314px" /><figcaption>Quick Flutter actions in VS Code (Ctrl+.)</figcaption></figure></div>



<h3 class="wp-block-heading">Snippets for widgets creation</h3>



<p>Another useful feature are code snippets for creating widgets. You use them by starting to type their acronym in your <em>.dart</em> file. There are two acronyms for widgets creation &#8211; <em>stless</em> for <span style="color:#f7bb1e" class="tadv-color">StatelessWidget</span> and <em>stful</em> for <span style="color:#f7bb1e" class="tadv-color">StatefulWidget</span> scaffolding. The usage looks as follows:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="909" height="327" data-attachment-id="3763" data-permalink="https://www.codejourney.net/basics-of-flutter-widgets/flutter_snippets/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?fit=909%2C327&amp;ssl=1" data-orig-size="909,327" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_snippets" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?fit=300%2C108&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?fit=909%2C327&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=909%2C327&#038;ssl=1" alt="" class="wp-image-3763" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?w=909&amp;ssl=1 909w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=300%2C108&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=768%2C276&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/01/Flutter_snippets.png?resize=676%2C243&amp;ssl=1 676w" sizes="auto, (max-width: 909px) 100vw, 909px" /><figcaption>Visual Studio Code &#8211; using Flutter snippets</figcaption></figure></div>



<h2 class="wp-block-heading">Most popular Flutter widgets</h2>



<p>I wanted to list you here some most popular Flutter widgets, but they are quite well described <a rel="noreferrer noopener" aria-label="here (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets-intro#basic-widgets" target="_blank">here</a>. You can also search through the <a rel="noreferrer noopener" aria-label="widgets library (opens in a new tab)" href="https://flutter.dev/docs/reference/widgets" target="_blank">widgets library</a>. We&#8217;ve also used quite few of them in our examples above <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Community widgets</h2>



<p>Many more people are starting to use Flutter and they also create a lot of community widgets. You can find the Dart packages for Flutter on <a rel="noreferrer noopener" aria-label="pub.dev (opens in a new tab)" href="https://pub.dev/" target="_blank">pub.dev</a>. I also recommend checking the <a rel="noreferrer noopener" aria-label="Flutter Awesome website (opens in a new tab)" href="https://flutterawesome.com/" target="_blank">Flutter Awesome website</a> where the best Flutter widgets, libraries and other extensions are listed.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>That&#8217;s it! You&#8217;ve just learned how to use stateless and stateful widgets in Flutter. We&#8217;ve also seen what&#8217;s the difference between them and what are some basic conventions in creating them. There&#8217;s a lot more to Flutter widgets and related topics, but these are topics for separate posts. I hope to publish more of them soon <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>In my opinion, bringing components into the mobile world in the form of widgets is a very nice idea. They give quite a good separation of logic and GUI management. For sure it&#8217;s a fresh start, totally changing the way in which we think about mobile apps development. Components have done their job in the web world, so why would widgets not succeed in mobile apps? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> We&#8217;ll see!</p>



<p>What do you think? If you are interested in some particular topics related to Flutter &#8211; let me know! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<p>The post <a href="https://www.codejourney.net/basics-of-flutter-widgets/">Basics of Flutter Widgets</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/basics-of-flutter-widgets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3715</post-id>	</item>
		<item>
		<title>Your First Flutter App in 30 Minutes</title>
		<link>https://www.codejourney.net/your-first-flutter-app-in-30-minutes/</link>
					<comments>https://www.codejourney.net/your-first-flutter-app-in-30-minutes/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 04 Dec 2019 17:26:31 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dart]]></category>
		<category><![CDATA[flutter]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3652</guid>

					<description><![CDATA[<p>You may know my past affair with Xamarin, which somehow died a natural death. In today&#8217;s post, we&#8217;re taking a look at Flutter. If you want to know what is Flutter and how to build your first Flutter app in less than 30 minutes (including installation time) &#8211; let&#8217;s jump right into it 😉 What&#8230;</p>
<p>The post <a href="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/">Your First Flutter App in 30 Minutes</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[


<p>You may know my past <a rel="noreferrer noopener" aria-label="affair with Xamarin (opens in a new tab)" href="https://www.codejourney.net/xamarin/" target="_blank">affair with Xamarin</a>, which somehow died a natural death. In today&#8217;s post, we&#8217;re taking a look at Flutter. If you want to know what is Flutter and how to build your first Flutter app in less than 30 minutes (including installation time) &#8211; let&#8217;s jump right into it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-3652"></span>



<h2 class="wp-block-heading">What is Flutter?</h2>



<p>Flutter is an <strong>open-source</strong> platform and development kit created by Google. You can use it to create <strong>mobile (Android, iOS), desktop (Windows, Mac, Linux)</strong> and recently also <strong>web applications</strong>.</p>



<p>Flutter is quite new, as it&#8217;s <strong>first official version 1.0 was released in December 2018</strong>. Before, it was developed and used internally by Google for a few years.</p>



<p>Since this time, countless Flutter apps have been published. You can find their list for instance <a rel="noreferrer noopener" aria-label="here (opens in a new tab)" href="https://itsallwidgets.com/" target="_blank">here</a>. One of the most well-known Flutter apps is <a href="https://youtu.be/jtYk3gWRSw0" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Xianyu app created by Alibaba</a> and used by 50M+ people.</p>



<p>The main purposes of Flutter are claimed to be <strong>fast development</strong>, <strong>beautiful and consistent UIs</strong> and <strong>native performance on each platform</strong>.</p>



<h2 class="wp-block-heading">Dart as a programming language</h2>



<p>Flutter uses <strong><a rel="noreferrer noopener" aria-label="Dart (opens in a new tab)" href="https://dart.dev/" target="_blank">Dart</a> as a programming language</strong>. Why is that? Well, of course, Dart is also developed by Google <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> However, one of the real reasons is believed to be performance. </p>



<p>As you probably know, Flutter is not the first (and not the last) cross-platform mobile development platform. Its main competitor is <a rel="noreferrer noopener" aria-label="React Native (opens in a new tab)" href="https://facebook.github.io/react-native/" target="_blank">React Native</a>, which uses JavaScript. Dart <strong>compiles to the given platform&#8217;s native machine code</strong>. Thanks to that, it doesn&#8217;t have to use a <a rel="noreferrer noopener" aria-label="JavaScript bridge (opens in a new tab)" href="https://hackernoon.com/understanding-react-native-bridge-concept-e9526066ddb8" target="_blank">JavaScript bridge</a> to interact with native components that React Native apps have to do. I don&#8217;t know how true this is in real life and how it helps with performance, but that is one of the reasons for using Dart as a programming language for Flutter apps.</p>



<p>Dart is a <strong>UI-oriented language</strong>. For C/C#/Java developers, Dart&#8217;s syntax will be rather familiar and easy to learn. It&#8217;s <strong>object-oriented</strong>, including support for classes and interfaces. The language is <strong>type-safe</strong>, meaning it combines static and runtime types checking.</p>



<p>Dart is supported by its <strong>virtual machine</strong>, which also provides &#8211; amongst others &#8211; a <strong>garbage collector</strong> (if you don&#8217;t know what the GC is, check out <a rel="noreferrer noopener" aria-label="this post (opens in a new tab)" href="https://www.codejourney.net/2018/08/net-internals-04-what-is-garbage-collection-memory-allocation-in-net/" target="_blank">this post</a>).</p>



<p>Here&#8217;s a simple program written in Dart:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist99841306" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-main-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="main.dart content, created by dsibinski on 02:03AM on December 04, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="main.dart">
        <tr>
          <td id="file-main-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main-dart-LC1" class="blob-code blob-code-inner js-file-line">main() {</td>
        </tr>
        <tr>
          <td id="file-main-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main-dart-LC2" class="blob-code blob-code-inner js-file-line">  var myCar = new Car(&quot;Cybertruck&quot;, new DateTime(2021, 01, 01));</td>
        </tr>
        <tr>
          <td id="file-main-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main-dart-LC3" class="blob-code blob-code-inner js-file-line">  myCar.describe();</td>
        </tr>
        <tr>
          <td id="file-main-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main-dart-LC4" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main-dart-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main-dart-LC6" class="blob-code blob-code-inner js-file-line">class Car {</td>
        </tr>
        <tr>
          <td id="file-main-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main-dart-LC7" class="blob-code blob-code-inner js-file-line">  String model;</td>
        </tr>
        <tr>
          <td id="file-main-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main-dart-LC8" class="blob-code blob-code-inner js-file-line">  DateTime productionDate;</td>
        </tr>
        <tr>
          <td id="file-main-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main-dart-LC9" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-dart-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-main-dart-LC10" class="blob-code blob-code-inner js-file-line">  // Ctor: notice the syntactic sugar members&#39; assignment</td>
        </tr>
        <tr>
          <td id="file-main-dart-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-main-dart-LC11" class="blob-code blob-code-inner js-file-line">  Car(this.model, this.productionDate) {</td>
        </tr>
        <tr>
          <td id="file-main-dart-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-main-dart-LC12" class="blob-code blob-code-inner js-file-line">    // Some other ctor init code here</td>
        </tr>
        <tr>
          <td id="file-main-dart-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-main-dart-LC13" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main-dart-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-main-dart-LC14" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-dart-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-main-dart-LC15" class="blob-code blob-code-inner js-file-line">  int get productionYear =&gt;</td>
        </tr>
        <tr>
          <td id="file-main-dart-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-main-dart-LC16" class="blob-code blob-code-inner js-file-line">      productionDate?.year;</td>
        </tr>
        <tr>
          <td id="file-main-dart-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-main-dart-LC17" class="blob-code blob-code-inner js-file-line">  </td>
        </tr>
        <tr>
          <td id="file-main-dart-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-main-dart-LC18" class="blob-code blob-code-inner js-file-line">  void describe() {</td>
        </tr>
        <tr>
          <td id="file-main-dart-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-main-dart-LC19" class="blob-code blob-code-inner js-file-line">    print(&#39;Car: $model, produced in $productionYear&#39;);</td>
        </tr>
        <tr>
          <td id="file-main-dart-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-main-dart-LC20" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-main-dart-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-main-dart-LC21" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/62f21a6a9e62af732b28fceec1310f9c/raw/4cbb0678c4f0c12be9ea22990e08f9f4c481da3d/main.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/62f21a6a9e62af732b28fceec1310f9c#file-main-dart" class="Link--inTextBlock">
          main.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>You can play with the code yourself <a rel="noreferrer noopener" aria-label="in the DartPad (opens in a new tab)" href="https://dartpad.dev/62f21a6a9e62af732b28fceec1310f9c" target="_blank">in the DartPad</a>.</p>



<p>Another interesting feature that is possible thanks to Dart is the <em>hot reload</em>. We&#8217;ll explore it later, but it significantly speeds up the development and testing time.</p>



<p>If you want to learn more about Dart, check out <a rel="noreferrer noopener" aria-label="the official docs (opens in a new tab)" href="https://dart.dev/tutorials" target="_blank">the official docs</a>.</p>



<h2 class="wp-block-heading">Everything as a widget</h2>



<p>The main concept in building Flutter apps are <strong>widgets</strong>. In Flutter, <strong>everything is a widget</strong> &#8211; buttons, texts, menus, colors, themes, spacings and paddings. Even your Flutter app is a widget.</p>



<p>What&#8217;s very interesting is that Flutter doesn&#8217;t use platform native widgets. Instead, it <strong>provides its own set of widgets for each platform</strong>, e.g. <a rel="noreferrer noopener" aria-label="Material Design (opens in a new tab)" href="https://material.io/develop/flutter/" target="_blank">Material Design</a> for Android and <a rel="noreferrer noopener" aria-label="Cupertino widgets (opens in a new tab)" href="https://flutter.dev/docs/development/ui/widgets/cupertino" target="_blank">Cupertino widgets</a> for iOS. Additionally, as a programmer, <strong>you can create your own widgets</strong>. Thanks to that, all Flutter apps look pretty much the same on every Android/iOS version. You don&#8217;t need to worry about some UI elements changes between OS releases. At the same time, an app built using these widgets looks like native GUI.</p>



<p>Thanks to the widgets concept, <strong>Flutter apps can be easily personalized and branded</strong>. <a rel="noreferrer noopener" aria-label="Recent researches show (opens in a new tab)" href="https://learn.g2.com/mobile-app-development-trends" target="_blank">Recent researches show</a> that customers are now starting to prefer more specific-looking apps to standard and boring native-designed UIs.</p>



<p>The drawback which I see about widgets is that <strong>there&#8217;s normally A LOT of source code in Flutter apps</strong>. Don&#8217;t get confused straightaway <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Installation and configuration</h2>



<p>Now, let&#8217;s get into the real work. It surprised me how easy it is to start working with Flutter. As you&#8217;ll see in a moment, you can build quite a nice-looking mobile app with Flutter in less than 30 minutes!</p>



<p>There are several possibilities to work with Flutter. You can easily <a rel="noreferrer noopener" aria-label="set up Android Studio or IntelliJ (opens in a new tab)" href="https://flutter.dev/docs/get-started/editor?tab=androidstudio" target="_blank">set up Android Studio or IntelliJ</a>. For example purposes, we&#8217;ll focus on <strong>running and debugging an Android application on Windows PC using Visual Studio Code</strong>. If you&#8217;re on Mac or Linux, check out a corresponding <a rel="noreferrer noopener" aria-label="official installation guide (opens in a new tab)" href="https://flutter.dev/docs/get-started/install" target="_blank">official installation guide</a>.</p>



<h3 class="wp-block-heading">Install Flutter and Android SDK</h3>



<p>The installation process is quite easy. Initially I wanted to describe it here for you, but actually the <a rel="noreferrer noopener" aria-label="official installation docs (opens in a new tab)" href="https://flutter.dev/docs/get-started/install" target="_blank">official installation docs</a> do it pretty well <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I&#8217;ll just guide you through the steps below with links to the official installation guide.</p>



<p><strong>Install Flutter SDK</strong> <strong>and Android Studio</strong></p>



<p>First of all, install Flutter SDK and Android Studio (which is required for Android SDK) following <a rel="noreferrer noopener" aria-label="this installation guide (opens in a new tab)" href="https://flutter.dev/docs/get-started/install/windows" target="_blank">this installation guide</a>. The process is fairly easy and should not take more than 15 minutes. Remember about using <em>flutter doctor</em> command to verify if everything is installed correctly &#8211; it gives very clear messages. In the end, using VS Code and having Android phone connected in USB Debugging mode, your <em>flutter doctor</em> command should have an output similar to mine:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="867" height="240" data-attachment-id="3669" data-permalink="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/flutterdoctor_vscode_ok/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?fit=867%2C240&amp;ssl=1" data-orig-size="867,240" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="FlutterDoctor_VSCode_OK" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?fit=300%2C83&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?fit=867%2C240&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?resize=867%2C240&#038;ssl=1" alt="Flutter App - flutter doctor proper result" class="wp-image-3669" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?w=867&amp;ssl=1 867w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?resize=300%2C83&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?resize=768%2C213&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/FlutterDoctor_VSCode_OK.png?resize=676%2C187&amp;ssl=1 676w" sizes="auto, (max-width: 867px) 100vw, 867px" /><figcaption>The correct output of <strong>flutter doctor</strong> command for VS Code (not Android Studio) development and Android phone connected in USB Debugging mode</figcaption></figure>



<h3 class="wp-block-heading">Configure Visual Studio Code</h3>



<p>The next step is to configure Visual Studio Code to be able to develop, compile, run and debug Flutter apps. You only need to install the Flutter extension, which is very well described <a rel="noreferrer noopener" aria-label="here (opens in a new tab)" href="https://flutter.dev/docs/get-started/editor?tab=vscode" target="_blank">here</a>. It should also automatically install the <a rel="noreferrer noopener" aria-label="Dart VS Code extension (opens in a new tab)" href="https://marketplace.visualstudio.com/items?itemName=Dart-Code.dart-code" target="_blank">Dart VS Code extension</a> which adds Dart language support to VS Code.</p>



<h2 class="wp-block-heading">Your first Flutter app</h2>



<p>Now let&#8217;s finally create this first Flutter Android application <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> It&#8217;s probably gonna be the quickest part!</p>



<h3 class="wp-block-heading">Create and run a sample app</h3>



<p>First of all, open Visual Studio Code. Use <em>Ctrl+Shift+P</em> to open a Command Palette. Start typing &#8220;Flutter&#8221; and select <em>Flutter: New Project</em>:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="831" height="252" data-attachment-id="3671" data-permalink="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/flutter_newproject_vscode/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?fit=831%2C252&amp;ssl=1" data-orig-size="831,252" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_NewProject_VSCode" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?fit=300%2C91&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?fit=831%2C252&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?resize=831%2C252&#038;ssl=1" alt="Flutter App - New Project creation in VS Code" class="wp-image-3671" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?w=831&amp;ssl=1 831w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?resize=300%2C91&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?resize=768%2C233&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_NewProject_VSCode.png?resize=676%2C205&amp;ssl=1 676w" sizes="auto, (max-width: 831px) 100vw, 831px" /></figure>



<p>In two next steps specify your project&#8217;s name (e.g. &#8220;hello_flutter&#8221;) and choose a location where the template should be generated.</p>



<p>Wait until VS Code generates the whole project and you see <em>main.dart</em> file in <em>lib</em> folder:</p>



<div class="wp-block-image"><figure class="aligncenter size-medium"><img data-recalc-dims="1" loading="lazy" decoding="async" width="159" height="300" data-attachment-id="3678" data-permalink="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/flutter_maindartfile-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_maindartfile-1.png?fit=221%2C416&amp;ssl=1" data-orig-size="221,416" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_maindartfile-1" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_maindartfile-1.png?fit=159%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_maindartfile-1.png?fit=221%2C416&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_maindartfile-1.png?resize=159%2C300&#038;ssl=1" alt="Flutter App - files structure of a template project with main.dart file" class="wp-image-3678" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_maindartfile-1.png?resize=159%2C300&amp;ssl=1 159w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_maindartfile-1.png?w=221&amp;ssl=1 221w" sizes="auto, (max-width: 159px) 100vw, 159px" /></figure></div>



<p>Open the <em>main.dart</em> file and replace its contents with the following, a bit cleaned-up code:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist99854969" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-flutter_demo_main-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="flutter_demo_main.dart content, created by dsibinski on 03:25PM on December 04, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="flutter_demo_main.dart">
        <tr>
          <td id="file-flutter_demo_main-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-flutter_demo_main-dart-LC1" class="blob-code blob-code-inner js-file-line">import &#39;package:flutter/material.dart&#39;;</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-flutter_demo_main-dart-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-flutter_demo_main-dart-LC3" class="blob-code blob-code-inner js-file-line">void main() =&gt; runApp(HelloFlutterApp());</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-flutter_demo_main-dart-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-flutter_demo_main-dart-LC5" class="blob-code blob-code-inner js-file-line">class HelloFlutterApp extends StatelessWidget {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-flutter_demo_main-dart-LC6" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-flutter_demo_main-dart-LC7" class="blob-code blob-code-inner js-file-line">  Widget build(BuildContext context) {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-flutter_demo_main-dart-LC8" class="blob-code blob-code-inner js-file-line">    return MaterialApp(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-flutter_demo_main-dart-LC9" class="blob-code blob-code-inner js-file-line">      title: &#39;HelloFlutter&#39;,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-flutter_demo_main-dart-LC10" class="blob-code blob-code-inner js-file-line">      theme: ThemeData(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-flutter_demo_main-dart-LC11" class="blob-code blob-code-inner js-file-line">        primarySwatch: Colors.lightGreen,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-flutter_demo_main-dart-LC12" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-flutter_demo_main-dart-LC13" class="blob-code blob-code-inner js-file-line">      home: MyHomePage(title: &#39;Hello Flutter!&#39;),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-flutter_demo_main-dart-LC14" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-flutter_demo_main-dart-LC15" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-flutter_demo_main-dart-LC16" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-flutter_demo_main-dart-LC17" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-flutter_demo_main-dart-LC18" class="blob-code blob-code-inner js-file-line">class MyHomePage extends StatefulWidget {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-flutter_demo_main-dart-LC19" class="blob-code blob-code-inner js-file-line">  MyHomePage({Key key, this.title}) : super(key: key);</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-flutter_demo_main-dart-LC20" class="blob-code blob-code-inner js-file-line">  final String title;</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-flutter_demo_main-dart-LC21" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-flutter_demo_main-dart-LC22" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-flutter_demo_main-dart-LC23" class="blob-code blob-code-inner js-file-line">  _MyHomePageState createState() =&gt; _MyHomePageState();</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-flutter_demo_main-dart-LC24" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-flutter_demo_main-dart-LC25" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-flutter_demo_main-dart-LC26" class="blob-code blob-code-inner js-file-line">class _MyHomePageState extends State&lt;MyHomePage&gt; {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-flutter_demo_main-dart-LC27" class="blob-code blob-code-inner js-file-line">  int _counter = 0;</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-flutter_demo_main-dart-LC28" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-flutter_demo_main-dart-LC29" class="blob-code blob-code-inner js-file-line">  void _incrementCounter() {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-flutter_demo_main-dart-LC30" class="blob-code blob-code-inner js-file-line">    setState(() {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-flutter_demo_main-dart-LC31" class="blob-code blob-code-inner js-file-line">      _counter++;</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-flutter_demo_main-dart-LC32" class="blob-code blob-code-inner js-file-line">    });</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-flutter_demo_main-dart-LC33" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-flutter_demo_main-dart-LC34" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-flutter_demo_main-dart-LC35" class="blob-code blob-code-inner js-file-line">  @override</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-flutter_demo_main-dart-LC36" class="blob-code blob-code-inner js-file-line">  Widget build(BuildContext context) {</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-flutter_demo_main-dart-LC37" class="blob-code blob-code-inner js-file-line">    return Scaffold(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-flutter_demo_main-dart-LC38" class="blob-code blob-code-inner js-file-line">      appBar: AppBar(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-flutter_demo_main-dart-LC39" class="blob-code blob-code-inner js-file-line">        title: Text(widget.title),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-flutter_demo_main-dart-LC40" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L41" class="blob-num js-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-flutter_demo_main-dart-LC41" class="blob-code blob-code-inner js-file-line">      body: Center(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L42" class="blob-num js-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-flutter_demo_main-dart-LC42" class="blob-code blob-code-inner js-file-line">        child: Column(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L43" class="blob-num js-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-flutter_demo_main-dart-LC43" class="blob-code blob-code-inner js-file-line">          mainAxisAlignment: MainAxisAlignment.center,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L44" class="blob-num js-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-flutter_demo_main-dart-LC44" class="blob-code blob-code-inner js-file-line">          children: &lt;Widget&gt;[</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L45" class="blob-num js-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-flutter_demo_main-dart-LC45" class="blob-code blob-code-inner js-file-line">            Text(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L46" class="blob-num js-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-flutter_demo_main-dart-LC46" class="blob-code blob-code-inner js-file-line">              &#39;You have pushed the button this many times: &#39;,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L47" class="blob-num js-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-flutter_demo_main-dart-LC47" class="blob-code blob-code-inner js-file-line">            ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L48" class="blob-num js-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-flutter_demo_main-dart-LC48" class="blob-code blob-code-inner js-file-line">            Text(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L49" class="blob-num js-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-flutter_demo_main-dart-LC49" class="blob-code blob-code-inner js-file-line">              &#39;$_counter&#39;,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L50" class="blob-num js-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-flutter_demo_main-dart-LC50" class="blob-code blob-code-inner js-file-line">              style: TextStyle(color: Colors.green, fontSize: 25),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L51" class="blob-num js-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-flutter_demo_main-dart-LC51" class="blob-code blob-code-inner js-file-line">            ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L52" class="blob-num js-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-flutter_demo_main-dart-LC52" class="blob-code blob-code-inner js-file-line">          ],</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L53" class="blob-num js-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-flutter_demo_main-dart-LC53" class="blob-code blob-code-inner js-file-line">        ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L54" class="blob-num js-line-number js-blob-rnum" data-line-number="54"></td>
          <td id="file-flutter_demo_main-dart-LC54" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L55" class="blob-num js-line-number js-blob-rnum" data-line-number="55"></td>
          <td id="file-flutter_demo_main-dart-LC55" class="blob-code blob-code-inner js-file-line">      floatingActionButton: FloatingActionButton(</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L56" class="blob-num js-line-number js-blob-rnum" data-line-number="56"></td>
          <td id="file-flutter_demo_main-dart-LC56" class="blob-code blob-code-inner js-file-line">        onPressed: _incrementCounter,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L57" class="blob-num js-line-number js-blob-rnum" data-line-number="57"></td>
          <td id="file-flutter_demo_main-dart-LC57" class="blob-code blob-code-inner js-file-line">        tooltip: &#39;Increment&#39;,</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L58" class="blob-num js-line-number js-blob-rnum" data-line-number="58"></td>
          <td id="file-flutter_demo_main-dart-LC58" class="blob-code blob-code-inner js-file-line">        child: Icon(Icons.add),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L59" class="blob-num js-line-number js-blob-rnum" data-line-number="59"></td>
          <td id="file-flutter_demo_main-dart-LC59" class="blob-code blob-code-inner js-file-line">      ),</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L60" class="blob-num js-line-number js-blob-rnum" data-line-number="60"></td>
          <td id="file-flutter_demo_main-dart-LC60" class="blob-code blob-code-inner js-file-line">    );</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L61" class="blob-num js-line-number js-blob-rnum" data-line-number="61"></td>
          <td id="file-flutter_demo_main-dart-LC61" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-flutter_demo_main-dart-L62" class="blob-num js-line-number js-blob-rnum" data-line-number="62"></td>
          <td id="file-flutter_demo_main-dart-LC62" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/9b10fa31f0d050979a03404eb7a75c73/raw/baea3b034734c06fb994663d8716e594d24b7194/flutter_demo_main.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/9b10fa31f0d050979a03404eb7a75c73#file-flutter_demo_main-dart" class="Link--inTextBlock">
          flutter_demo_main.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>We won&#8217;t focus on the source code here &#8211; I hope to dig more in the coming posts <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Just notice there are quite a few widgets &#8211; can you count them all? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I found at least 12 different widgets used in this small template code.</p>



<p>Now the best part &#8211; having your Android phone connected (you should see it in the right-bottom corner of VS Code) press F5 to run the application. After a few seconds (usually longer for the first time) you should see this beautiful application on your smartphone&#8217;s screen:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="3679" data-permalink="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/flutter-firstandroidapp/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?fit=1080%2C2280&amp;ssl=1" data-orig-size="1080,2280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter-FirstAndroidApp" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?fit=142%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?fit=485%2C1024&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=364%2C768&#038;ssl=1" alt="Flutter App - first Flutter app (Android)" class="wp-image-3679" width="364" height="768" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=485%2C1024&amp;ssl=1 485w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=142%2C300&amp;ssl=1 142w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=768%2C1621&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=728%2C1536&amp;ssl=1 728w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=970%2C2048&amp;ssl=1 970w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?resize=676%2C1427&amp;ssl=1 676w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter-FirstAndroidApp.jpg?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 364px) 100vw, 364px" /></figure></div>



<p>As soon as you press the &#8220;+&#8221; button the green counter increments. Yaaaaay! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Debug your Flutter app</h3>



<p>Now, try putting a breakpoint in <em>main.dart</em> file at line 30 (beginning of <em>_incrementCounter()</em> function). When you click the &#8220;+&#8221; button next time, VS Code should stop at the breakpoint:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="867" height="306" data-attachment-id="3686" data-permalink="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/flutter_vscode_debug/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?fit=867%2C306&amp;ssl=1" data-orig-size="867,306" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_VSCode_Debug" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?fit=300%2C106&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?fit=867%2C306&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?resize=867%2C306&#038;ssl=1" alt="Dart's breakpoint hit in VS Code" class="wp-image-3686" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?w=867&amp;ssl=1 867w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?resize=300%2C106&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?resize=768%2C271&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_VSCode_Debug.png?resize=676%2C239&amp;ssl=1 676w" sizes="auto, (max-width: 867px) 100vw, 867px" /></figure>



<h3 class="wp-block-heading">Try hot reload</h3>



<p>The best for the end. As I mentioned before, Flutter lets you use a <a rel="noreferrer noopener" aria-label="hot reload (opens in a new tab)" href="https://flutter.dev/docs/development/tools/hot-reload" target="_blank">hot reload</a>. It lets you <strong>change the code while running the app and see the changes immediately</strong> after saving the source code file. I love it especially because it&#8217;s a <strong>stateful hot reload</strong>, meaning that except UI the state is also reloaded (or rather kept).</p>



<p>With your Flutter app running in debug mode, click the &#8220;+&#8221; button several times so the counter has value &gt; 0. Then go directly into VS Code and modify line 50 by changing the counter text color from <em>Colors.green</em> to  <em>Colors.red</em>. Line 50 should now look as follows:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist99855426" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-flutter_demo_main_line50_color-dart" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-dart  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="flutter_demo_main_line50_color.dart content, created by dsibinski on 03:50PM on December 04, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="flutter_demo_main_line50_color.dart">
        <tr>
          <td id="file-flutter_demo_main_line50_color-dart-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-flutter_demo_main_line50_color-dart-LC1" class="blob-code blob-code-inner js-file-line">style: TextStyle(color: Colors.red, fontSize: 25),</td>
        </tr>
  </table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1a2cc4d1a176a22531807e87261dd6ea/raw/39a2c2aa97e5b3f34a9be63f7cef83c4eac5be06/flutter_demo_main_line50_color.dart" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/1a2cc4d1a176a22531807e87261dd6ea#file-flutter_demo_main_line50_color-dart" class="Link--inTextBlock">
          flutter_demo_main_line50_color.dart
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>Save <em>main.dart</em> file by pressing Ctrl+S. Take a look at your smartphone and see the magic:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" data-attachment-id="3689" data-permalink="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/flutter_hotreload-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?fit=1080%2C2280&amp;ssl=1" data-orig-size="1080,2280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Flutter_HotReload-1" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?fit=142%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?fit=485%2C1024&amp;ssl=1" src="https://i1.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?fit=485%2C1024&amp;ssl=1" alt="Flutteer's hot reload in action" class="wp-image-3689" width="364" height="768" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?resize=142%2C300&amp;ssl=1 142w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?resize=485%2C1024&amp;ssl=1 485w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?resize=768%2C1621&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?resize=728%2C1536&amp;ssl=1 728w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?resize=970%2C2048&amp;ssl=1 970w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/12/Flutter_HotReload-1.jpg?resize=676%2C1427&amp;ssl=1 676w" sizes="auto, (max-width: 364px) 100vw, 364px" /></figure></div>



<p>Notice how the color of number &#8220;7&#8221; (counter value) changed to red while its value remains untouched. Quite a nice feature for quick development <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p>I noticed that sometimes it doesn&#8217;t work that smoothly and you need to restart the app to see the changes. However, it happens only with some bigger code changes. Flutter quite young SDK and tools are still developing quickly so I hope such drawbacks will be eliminated soon.</p>



<h2 class="wp-block-heading">Summary</h2>



<p>Today we&#8217;ve seen how easy it is to start working with Flutter. We got familiar with basic Flutter concepts like widgets. We&#8217;ve also created our first Flutter app and debugged it. Finally, we&#8217;ve seen the very cool hot reload feature in action <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4aa.png" alt="💪" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>For me, Flutter looks promising. After my adventures with <a rel="noreferrer noopener" aria-label="Xamarin (opens in a new tab)" href="https://www.codejourney.net/xamarin/" target="_blank">Xamarin</a>, which mostly felt like changing Java to C# and Android Studio to Visual Studio, I&#8217;m excited to try something fresh and totally different.</p>



<p>I know this was just a simple introduction to Flutter, but there&#8217;s more coming! I hope to publish the next articles about Flutter as I continue playing with it. If you&#8217;ve ever used Flutter and have some good sources to recommend &#8211; let me know in the comments!</p>



<p>Stay tuned!</p>


<p>The post <a href="https://www.codejourney.net/your-first-flutter-app-in-30-minutes/">Your First Flutter App in 30 Minutes</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/your-first-flutter-app-in-30-minutes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3652</post-id>	</item>
		<item>
		<title>Xamarin.Android &#8211; ASP.NET web api synchronization &#8211; research</title>
		<link>https://www.codejourney.net/xamarin-android-asp-net-web-api-synchronization-research/</link>
					<comments>https://www.codejourney.net/xamarin-android-asp-net-web-api-synchronization-research/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 27 Sep 2017 06:00:45 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[asp-net-core]]></category>
		<category><![CDATA[moneyback]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2345</guid>

					<description><![CDATA[<p>As you may know, in my MoneyBack Xamarin.Android application I&#8217;ve used SQLite as the local db management system. Recently I&#8217;ve added an ASP.NET Core web solution to my GitHub repository in order to create back-end API for my mobile app. I wanted to have database hosted on a remote server and Android application to synchronize its data&#8230;</p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-asp-net-web-api-synchronization-research/">Xamarin.Android &#8211; ASP.NET web api synchronization &#8211; research</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>As you may know, in my <a href="https://github.com/dsibinski/MoneyBack" target="_blank" rel="noopener noreferrer">MoneyBack</a> Xamarin.Android application I&#8217;ve used <a href="https://www.codejourney.net/2017/03/using-sqlite-database-in-xamarin-android/" target="_blank" rel="noopener noreferrer">SQLite</a> as the local db management system. Recently I&#8217;ve added an <a href="https://github.com/dsibinski/MoneyBack.Web" target="_blank" rel="noopener noreferrer">ASP.NET Core web solution to my GitHub repository</a> in order to create back-end API for my mobile app. I wanted to have database hosted on a remote server and Android application to synchronize its data with it.<br />
Then I started wondering&#8230; and decided to make a deeper research first. As I wrote in <a href="https://www.codejourney.net/2017/05/dajsiepoznac2017-summary/" target="_blank" rel="noopener noreferrer">my post summing up DajSiePoznac2017 competition</a>, &#8220;before using a particular solution for an issue&#8221; we should &#8220;better examine the other possibilities&#8221; first. So I do <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />
<span id="more-2345"></span></p>
<h2>Why to synchronize with remote database?</h2>
<p>First question to ask is <strong>why to synchronize with a remote database at all</strong>?</p>
<h6>There are a few obvious advantages:</h6>
</p>
<p><strong>(+)</strong> users&#8217; data is stored &#8220;in a cloud&#8221; and can be accessed from any device</p>
<p><strong>(+)</strong> users don&#8217;t need to worry about backing-up their data</p>
<p><strong>(+)</strong> data storage logic is moved to the web part of the system and with API exposed it can be easier to port it to other platforms</p>
<p><strong>(+)</strong> having web API, a web client can be easily added to the system.</p>
<h6>However, there are also some harms:</h6>
<p><strong>(-)</strong> synchronization of local and remote data (online and offline) must be handled</p>
<p><strong>(-)</strong> synchronization uses some network data and battery of a mobile device</p>
<p><strong>(-) </strong>web API must be maintained and after each change in it mobile app must be adjusted.</p>
<p>Despite all these aspects I&#8217;ve been wondering to implement a web API for few different reasons. First of all this could be a great programming experience, very interesting from architectural point of view. Secondly, I think this is a bit old-fashioned and messy that a user needs to export some database/app files backup to his GDrive in order to not lose his data.</p>
<p>Frankly, I just want to have some fun with ASP.NET Core, implement a web API and make <a href="https://github.com/dsibinski/MoneyBack" target="_blank" rel="noopener noreferrer">MoneyBack</a> working with it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Maybe some Linux deployment after all? Let&#8217;s create some nice programming playground <a href="https://github.com/dsibinski/MoneyBack/tree/master/Web" target="_blank" rel="noopener noreferrer">here</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h2>How to synchronize with web API?</h2>
<p>That&#8217;s the question I&#8217;ve been searching an answer for recently. Long story short, the idea is to have a <strong>back-end database management system hosted on a web server</strong> and mobile app having its own local &#8220;mirror&#8221; of the database, <strong>bidirectionally synchronizing local data with remote database through web API</strong>. Mobile app should work in <strong>offline-first</strong> mode, which means that all operations must be possible to be done locally and potential (not mandatory) synchronization to happen as soon as it&#8217;s possible (user is connected to WiFi, has mobile network access etc.)</p>
<p>There are various possibilities and solutions to handle synchronization of mobile app&#8217;s data and remote database storage, from synchronization system built from scratch to Azure cloud hosting.</p>
<h4>Custom synchronization mechanism</h4>
<p>We could of course implement our own data synchronization mechanism. There are many tutorials available, including for instance <a href="https://xamarinhelp.com/mobile-database-bi-directional-synchronization-rest-api/" target="_blank" rel="noopener noreferrer">this one</a>, which describes all the contents quite nicely and I recommend reading it even if you don&#8217;t want to implement sync on your own &#8211; it helps understanding all the concepts.</p>
<p>Custom synchronization can be a lot of fun, but&#8230; why to reinvent the wheel?</p>
<h4>Azure Mobile App Service</h4>
<p><a href="https://azure.microsoft.com/en-us/services/app-service/mobile/" target="_blank" rel="noopener noreferrer">Microsoft&#8217;s Azure Mobile App Service</a> is recommended almost everywhere &#8211; <a href="https://stackoverflow.com/questions/33224792/using-xamarin-android-i-want-to-sync-sqlite-with-sql-server" target="_blank" rel="noopener noreferrer">on StackOverflow</a>, in the official <a href="https://developer.xamarin.com/guides/xamarin-forms/cloud-services/sync/" target="_blank" rel="noopener noreferrer">Xamarin documentation</a> and on a lot of blogs, but its free plan seems to not be worth using (except of performing some simple tests) while paid plans are more <em>enterprisy</em>. It seems great, but for my playground I neither want to pay nor use free plan which may become unusable after re-implementing the whole back-end.</p>
<h4>Realm.io</h4>
<p>Finally, out of a sudden, I found it. <a href="https://realm.io/docs/get-started/overview/" target="_blank" rel="noopener noreferrer">Realm.io</a> is a totally separate database system built especially for mobile solutions. Its <a href="https://realm.io/products/realm-mobile-database/" target="_blank" rel="noopener noreferrer">Mobile Database</a> may be used as the db framework for a mobile app (<a href="https://realm.io/docs/xamarin/latest/" target="_blank" rel="noopener noreferrer">Xamarin is also supported</a>), replacing for instance <a href="https://www.codejourney.net/2017/03/using-sqlite-database-in-xamarin-android/" target="_blank" rel="noopener noreferrer">SQLite</a>. After all, <a href="https://realm.io/products/realm-mobile-platform/" target="_blank" rel="noopener noreferrer">Realm Mobile Platform</a> can be used on a server-side handling mobile/web APIs and data synchronization &#8211; documentation says it supports .NET Core 1.1. Let&#8217;s hope they add support for 2.0 soon.</p>
<p>What&#8217;s more it&#8217;s all open-source and provides <a href="https://realm.io/pricing/" target="_blank" rel="noopener noreferrer">really nice free plans</a>.</p>
<p>Realm.io looks very promising. I&#8217;m just a bit worried it&#8217;s almost never recommended on the web &#8211; is there something wrong with it? Maybe it&#8217;s a new stuff? Where&#8217;s a catch? Let me know if you&#8217;ve had any experience with it.</p>
<h4>SQLite-sync.com</h4>
<p>Last but maybe not least, I found <a href="http://sqlite-sync.com/" target="_blank" rel="noopener noreferrer">SQLite-sync.com</a>. The idea seems to be similar to Realm.io, however this product looks less mature. Not even 100 commits <a href="https://github.com/sqlite-sync/SQLite-sync.com/commits/master" target="_blank" rel="noopener noreferrer">on their GitHub</a> with just few contributors. Looking poor compared to <a href="https://github.com/realm/realm-dotnet" target="_blank" rel="noopener noreferrer">Realm.io&#8217;s GitHub</a> with more than 2.5k commits only for its .NET component.</p>
<p>The main (and the only?) benefit of using it would be the possibility to keep SQLite database in Xamarin.Android app. Apart from that, I don&#8217;t see any dominance over Realm.io.</p>
<h2>Summary</h2>
<p>As my research shows there are a lot of existing frameworks that help keeping data synchronized between mobile app and a remote back-end, allowing Xamarin app to work in offline-first approach. Microsoft offers great stuff in Azure, but in my opinion it&#8217;s not worth investing money for small <em>playground</em> apps.</p>
<p>For the moment I&#8217;m for Realm.io. It seems to provide very extended free plan, there&#8217;s a lot of resources on the web, folks talk about it on SO&#8230;</p>
<p>So now I&#8217;m asking you &#8211; <span style="text-decoration: underline;"><strong>do you have any experience with data sync in Xamarin apps? If yes, please share your insights and help me to choose the best approach <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></span></p>
<p>I&#8217;d be grateful for any suggestions!</p>
<p>After the framework is chosen, I will try to design the whole synchronization system and share it with you here.</p></p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-asp-net-web-api-synchronization-research/">Xamarin.Android &#8211; ASP.NET web api synchronization &#8211; research</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/xamarin-android-asp-net-web-api-synchronization-research/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2345</post-id>	</item>
		<item>
		<title>Xamarin.Android &#8211; debugging via WiFi</title>
		<link>https://www.codejourney.net/xamarin-android-debugging-via-wifi/</link>
					<comments>https://www.codejourney.net/xamarin-android-debugging-via-wifi/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 30 May 2017 21:08:38 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2296</guid>

					<description><![CDATA[<p>In this short post, I&#8217;m going to show you a very handy feature of Android Debug Bridge (adb) &#8211; possibility to debug Xamarin.Android apps in Visual Studio via WiFi connection. Using ADB to debug Android apps By default, adb is configured to &#8220;map&#8221; Android devices connected via USB ports to the computer as debug devices, which are then&#8230;</p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-debugging-via-wifi/">Xamarin.Android &#8211; debugging via WiFi</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this short post, I&#8217;m going to show you a very handy feature of <a href="https://developer.android.com/studio/command-line/adb.html" target="_blank" rel="noopener noreferrer">Android Debug Bridge</a> (<em>adb</em>) &#8211; possibility to debug Xamarin.Android apps in Visual Studio via WiFi connection.<br />
<span id="more-2296"></span></p>
<h2>Using ADB to debug Android apps</h2>
<p>By default, <em>adb</em> is configured to &#8220;map&#8221; Android devices connected via USB ports to the computer as <em>debug devices</em>, which are then available e.g. in Visual Studio as the device on which our app can be deployed and debugged. In may cases we debug apps on Android emulators, which is frequently fair enough, but at some point we need to make our tests on a physical device.</p>
<p>It may not be very comfortable to have the phone connected using USB cable all the time, especially when testing some physical sensors like accelerometer or gyroscope. For such purposes, ADB gives us the possibility to connect Android devices via WiFi instead of USB. Let&#8217;s see how to configure it.</p>
<h2>Configure ADB to work on WiFi</h2>
<p>The first requirement is &#8211; obviously &#8211; that both our development PC and Android device must be connected to the same WiFi network. Then we need to find out what is the IP address of our Android device &#8211; it can be checked by going to <strong>Settings -&gt; WiFi -&gt; Menu &#8211; Advanced settings </strong>(Android 6.0):</p>
<p><figure id="attachment_2297" aria-describedby="caption-attachment-2297" style="width: 222px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2297" data-permalink="https://www.codejourney.net/xamarin-android-debugging-via-wifi/huaweip8_ip/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="HuaweiP8_IP" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?fit=576%2C1024&amp;ssl=1" class="wp-image-2297" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?resize=222%2C394&#038;ssl=1" alt="" width="222" height="394" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?resize=720%2C1280&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/HuaweiP8_IP.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 222px) 100vw, 222px" /></a><figcaption id="caption-attachment-2297" class="wp-caption-text">Android 6.0 &#8211; IP address</figcaption></figure></p>
<p>As soon as you have IP address of the device noted, <strong>connect it to the computer via USB port</strong>.</p>
<p>Now we need to use <em>adb.exe</em> to configure it for connecting with the device via WiFi. You can either add system environmental variable pointing to where the <em>adb.exe</em> is stored or just open <em>cmd</em>, go to the catalogue where it&#8217;s located (<em>Android\platform-tools\</em>) and execute the following commands:</p>
<ol>
<li>Change ADB to listen on TCP port:</li>
</ol>
<pre><pre class="brush: bash; title: ; notranslate">adb tcpip 5555</pre>
<p>This will make ADB listening on TCP port 5555 instead of USB ports (<strong>NOTE</strong>: since now the computer won&#8217;t listen to any devices connected by USB ports):</p>
<p><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2307" data-permalink="https://www.codejourney.net/xamarin-android-debugging-via-wifi/cmd_1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?fit=553%2C58&amp;ssl=1" data-orig-size="553,58" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cmd_1" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?fit=300%2C31&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?fit=553%2C58&amp;ssl=1" class="aligncenter wp-image-2307" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?resize=319%2C33&#038;ssl=1" alt="" width="319" height="33" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?resize=300%2C31&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_1.png?w=553&amp;ssl=1 553w" sizes="auto, (max-width: 319px) 100vw, 319px" /></a></p>
<p>Now,<strong> disconnect the Android device from USB port</strong>.</p>
<p>2. Make ADB connect to your Android device:</p>
<pre><pre class="brush: bash; title: ; notranslate">adb connect 192.168.0.101:5555</pre>
<p>This command is used to connect to Android device (of course IP address must be changed with your device&#8217;s one) on port 5555 using WiFi:</p>
<p><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2308" data-permalink="https://www.codejourney.net/xamarin-android-debugging-via-wifi/cmd_2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?fit=723%2C55&amp;ssl=1" data-orig-size="723,55" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cmd_2" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?fit=300%2C23&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?fit=723%2C55&amp;ssl=1" class="aligncenter wp-image-2308" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?resize=430%2C33&#038;ssl=1" alt="" width="430" height="33" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?resize=300%2C23&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?resize=720%2C55&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/cmd_2.png?w=723&amp;ssl=1 723w" sizes="auto, (max-width: 430px) 100vw, 430px" /></a></p>
<p>
3. Since now you should see the device in Visual Studio connected using WiFi connection:</p>
<p><figure id="attachment_2309" aria-describedby="caption-attachment-2309" style="width: 671px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2309" data-permalink="https://www.codejourney.net/xamarin-android-debugging-via-wifi/huawei_connectedwifi/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?fit=1150%2C65&amp;ssl=1" data-orig-size="1150,65" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Huawei_connectedWifi" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?fit=300%2C17&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?fit=1024%2C58&amp;ssl=1" class="wp-image-2309" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?resize=671%2C38&#038;ssl=1" alt="" width="671" height="38" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?resize=300%2C17&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?resize=768%2C43&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?resize=1024%2C58&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?resize=720%2C41&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Huawei_connectedWifi.png?w=1150&amp;ssl=1 1150w" sizes="auto, (max-width: 671px) 100vw, 671px" /></a><figcaption id="caption-attachment-2309" class="wp-caption-text">WiFi Android device visible in Visual Studio</figcaption></figure></p>
<p>and you can of course deploy the app remotely on the device and debug it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>4. As soon as you&#8217;re done with WiFi debugging, run the following command:</p>
<pre><pre class="brush: bash; title: ; notranslate">adb usb</pre>
<p>It will make ADB listening for USB devices again:</p>
<p><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2310" data-permalink="https://www.codejourney.net/xamarin-android-debugging-via-wifi/commands_usbrestored/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?fit=479%2C55&amp;ssl=1" data-orig-size="479,55" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1496180723&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="Commands_UsbRestored" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?fit=300%2C34&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?fit=479%2C55&amp;ssl=1" class="aligncenter wp-image-2310" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?resize=353%2C40&#038;ssl=1" alt="" width="353" height="40" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?resize=300%2C34&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Commands_UsbRestored.jpg?w=479&amp;ssl=1 479w" sizes="auto, (max-width: 353px) 100vw, 353px" /></a></p>
<p><strong>TIP</strong>: if during performing any <em>cmd</em> commands <em>adb.exe </em>is stuck or not reacting, try plugging out and re-plugging in your Android device to USB port.</p>
<h2>Summary</h2>
<p>This post described how to use remote debugging on Android devices using WiFi connection.</p>
<p>I hope you&#8217;ll find it useful <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-debugging-via-wifi/">Xamarin.Android &#8211; debugging via WiFi</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/xamarin-android-debugging-via-wifi/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2296</post-id>	</item>
		<item>
		<title>Managing Activity state changes using Bundle</title>
		<link>https://www.codejourney.net/managing-activity-state-changes-using-bundle/</link>
					<comments>https://www.codejourney.net/managing-activity-state-changes-using-bundle/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 29 May 2017 21:28:42 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[moneyback]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2281</guid>

					<description><![CDATA[<p>Today we&#8217;re going to see how to manage (keep and restore) state of Activities in Xamarin.Android application in order to keep the app consistent and reactive for configuration/state changes. Why to keep and restore Activity&#8217;s state? As I already described in my post about Android Activities, the OS may react to some &#8220;constant&#8221; state changes&#8230;</p>
<p>The post <a href="https://www.codejourney.net/managing-activity-state-changes-using-bundle/">Managing Activity state changes using Bundle</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Today we&#8217;re going to see how to manage (keep and restore) state of <a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener noreferrer">Activities</a> in Xamarin.Android application in order to keep the app consistent and reactive for configuration/state changes.<br />
<span id="more-2281"></span></p>
<h2>Why to keep and restore Activity&#8217;s state?</h2>
<p>As I already described in <a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener noreferrer">my post about Android Activities</a>, the OS may react to some &#8220;constant&#8221; state changes by calling lifecycle methods during Activity&#8217;s life, which may be overridden by the programmer in order to take some additional actions. However, there are some behaviors in Android apps that may change its configuration, after which the state of the Activity (for instance: arrangement or some UI elements or checkboxes&#8217; selections) may be lost if not handled properly.</p>
<p>To give you a real example: in <em>MoneyBack</em> application there is a main screen with two tabs. I noticed that when the second tab is selected:</p>
<p><figure id="attachment_2282" aria-describedby="caption-attachment-2282" style="width: 229px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2282" data-permalink="https://www.codejourney.net/managing-activity-state-changes-using-bundle/moneyback_secondtab/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_SecondTab" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?fit=576%2C1024&amp;ssl=1" class="wp-image-2282" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?resize=229%2C406&#038;ssl=1" alt="" width="229" height="406" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?resize=720%2C1280&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_SecondTab.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 229px) 100vw, 229px" /></a><figcaption id="caption-attachment-2282" class="wp-caption-text"><em>MoneyBack</em> &#8211; 2nd tab selected</figcaption></figure></p>
<p>and the device is rotated:</p>
<p><figure id="attachment_2283" aria-describedby="caption-attachment-2283" style="width: 478px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2283" data-permalink="https://www.codejourney.net/managing-activity-state-changes-using-bundle/moneyback_afterrotatefirsttab/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?fit=1920%2C1080&amp;ssl=1" data-orig-size="1920,1080" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_AfterRotateFirstTab" data-image-description="" data-image-caption="&lt;p&gt;MoneyBack &amp;#8211; 1st tab selected after rotating&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?fit=300%2C169&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?fit=1024%2C576&amp;ssl=1" class="wp-image-2283" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?resize=478%2C269&#038;ssl=1" alt="" width="478" height="269" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?resize=300%2C169&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?resize=768%2C432&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?resize=1024%2C576&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?resize=720%2C405&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_AfterRotateFirstTab.png?w=1920&amp;ssl=1 1920w" sizes="auto, (max-width: 478px) 100vw, 478px" /></a><figcaption id="caption-attachment-2283" class="wp-caption-text"><em>MoneyBack</em> &#8211; 1st tab selected after rotating</figcaption></figure></p>
<p><strong>first tab becomes selected</strong>. User is losing his input (selection of the 2nd tab).</p>
<p>Screen orientation change is one of the reasons why we should care about saving and restoring Activities&#8217; states.</p>
<h2>Keeping state changes &#8211; OnSaveInstanceState()</h2>
<p>Each Activity allows us to override <span style="color: #ff9900;">OnSaveInstanceState(<span style="color: #ff6600;">Bundle</span> outState)</span> method, which is called when the current Activity is to be killed (e.g. when device&#8217;s screen orientation is changing or the Activity needs to be killed by Android in order to release some resources).</p>
<p><strong>Please don&#8217;t confuse it with Activity Lifecycle Methods</strong> (which I already described <a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener noreferrer">here</a>), like <span style="color: #ff9900;">OnPause()</span> or <span style="color: #ff9900;">OnStop()</span> which are always called by the OS when particular action occurs. <span style="color: #ff9900;">OnSaveInstanceState()</span> method is <strong>generally</strong> called after <span style="color: #ff9900;">OnPause()</span> and before <span style="color: #ff9900;">OnStop()</span>, but <strong>it&#8217;s not always the case</strong>. For instance, it won&#8217;t be called at all when user navigates back from <em>ActivityB</em> to <em>ActivityA</em>, as in this case <em>ActivityB</em> will never be killed. More details can be found in <a href="https://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState%28android.os.Bundle%29" target="_blank" rel="noopener noreferrer">official Android documentation</a>.</p>
<p><span style="color: #ff9900;">OnSaveInstanceState()</span> is called with <span style="color: #ff9900;">Bundle</span> parameter provided. It represents a simple key-value dictionary, which is additionally serialized, so it should be used for storing simple values like strings, integers etc. There are other structures and techniques for storing more complex data on state changes events (see the link in &#8220;Summary&#8221; section of this post).</p>
<p>In order to save currently selected tab, we can implement the method as follows:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist48172254" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-onsaveinstancestate-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="OnSaveInstanceState.cs content, created by dsibinski on 08:28PM on May 29, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="OnSaveInstanceState.cs">
<tr>
<td id="file-onsaveinstancestate-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-onsaveinstancestate-cs-LC1" class="blob-code blob-code-inner js-file-line">  protected override void OnSaveInstanceState(Bundle outState)</td>
</tr>
<tr>
<td id="file-onsaveinstancestate-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-onsaveinstancestate-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-onsaveinstancestate-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-onsaveinstancestate-cs-LC3" class="blob-code blob-code-inner js-file-line">      var tabSelectedPosition = this.ActionBar.SelectedNavigationIndex;</td>
</tr>
<tr>
<td id="file-onsaveinstancestate-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-onsaveinstancestate-cs-LC4" class="blob-code blob-code-inner js-file-line">      outState.PutInt(&quot;selectedTabPosition&quot;, tabSelectedPosition);</td>
</tr>
<tr>
<td id="file-onsaveinstancestate-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-onsaveinstancestate-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onsaveinstancestate-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-onsaveinstancestate-cs-LC6" class="blob-code blob-code-inner js-file-line">      base.OnSaveInstanceState(outState);</td>
</tr>
<tr>
<td id="file-onsaveinstancestate-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-onsaveinstancestate-cs-LC7" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/58260052f1fd8a7daffe99d4c63d634c/raw/1b9d19cc7369122ea997616b929899480521dc1e/OnSaveInstanceState.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/58260052f1fd8a7daffe99d4c63d634c#file-onsaveinstancestate-cs" class="Link--inTextBlock"><br />
          OnSaveInstanceState.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>Now, each screen orientation change will make this method called and the index of selected tab will be saved into <span style="color: #ff9900;">Bundle</span> <span style="color: #ff9900;">outState</span> dictionary under <em>&#8220;selectedTabPosition&#8221;</em> key.</p>
<h2>Restoring state changes &#8211; OnRestoreInstanceState()</h2>
<p>As soon as the Activity considered backs to life (is being resumed), <span style="color: #ff9900;">OnRestoreInstanceState(<span style="color: #ff6600;">Bundle</span> savedInstanceState)</span> method is called by the OS. <strong>It will only be called if there is a saved instance kept by calling <span style="color: #ff9900;">OnSaveInstanceState()</span> method before</strong>. As you can see, this method also comes with a <span style="color: #ff9900;">Bundle</span> parameter, which is the same key-value serialized dictionary we used for saving the Activity&#8217;s state.</p>
<p>In case of tabs selection restoring, we can implement this method as the following code presents:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist48172407" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-onrestoreinstancestate-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="OnRestoreInstanceState.cs content, created by dsibinski on 08:34PM on May 29, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="OnRestoreInstanceState.cs">
<tr>
<td id="file-onrestoreinstancestate-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-onrestoreinstancestate-cs-LC1" class="blob-code blob-code-inner js-file-line">  protected override void OnRestoreInstanceState(Bundle savedInstanceState)</td>
</tr>
<tr>
<td id="file-onrestoreinstancestate-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-onrestoreinstancestate-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-onrestoreinstancestate-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-onrestoreinstancestate-cs-LC3" class="blob-code blob-code-inner js-file-line">      base.OnRestoreInstanceState(savedInstanceState);</td>
</tr>
<tr>
<td id="file-onrestoreinstancestate-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-onrestoreinstancestate-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onrestoreinstancestate-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-onrestoreinstancestate-cs-LC5" class="blob-code blob-code-inner js-file-line">      var previouslySelectedTabPosition = savedInstanceState.GetInt(&quot;selectedTabPosition&quot;, 0);</td>
</tr>
<tr>
<td id="file-onrestoreinstancestate-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-onrestoreinstancestate-cs-LC6" class="blob-code blob-code-inner js-file-line">      this.ActionBar.SetSelectedNavigationItem(previouslySelectedTabPosition);</td>
</tr>
<tr>
<td id="file-onrestoreinstancestate-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-onrestoreinstancestate-cs-LC7" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/f620e7ae733cda6333cddd9abeced90c/raw/066fc7034dadbcfef47a358ec1c86bbb9a31b7f2/OnRestoreInstanceState.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/f620e7ae733cda6333cddd9abeced90c#file-onrestoreinstancestate-cs" class="Link--inTextBlock"><br />
          OnRestoreInstanceState.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p><span style="color: #ff9900;">previouslySelectedTabPosition </span>variable will be initialized with integer value from <span style="color: #ff9900;">Bundle</span> dictionary saved under <em>&#8220;selectedTabPosition&#8221;</em> key, or default value (<em>0</em>) if nothing saved for the key is found.</p>
<p><strong>NOTE</strong>: <span style="color: #ff9900;">Bundle</span> parameter provided in <span style="color: #ff9900;">OnRestoreInstanceState()</span> is exactly the same, as the one available in <span style="color: #ff9900;">OnCreate(<span style="color: #ff6600;">Bundle</span> bundle)</span> method called on Activity&#8217;s creation. We could actually also retrieve our saved value there, but in many cases restoring the state (like selecting previously selected tab) requires some UI elements to be already initialized, which should be handled within <span style="color: #ff9900;">OnCreate()</span> method before. Because of that, I&#8217;d rather suggest to restore Activity&#8217;s state using <span style="color: #ff9900;">OnRestoreInstanceState()</span> as a general rule (of course there may be some exceptional cases <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ). <span style="color: #ff9900;">OnRestoreInstanceState()</span> will always be called <strong>after</strong> <span style="color: #ff9900;">OnCreate()</span>.</p>
<p>Moreover, if we wanted to use <span style="color: #ff9900;">Bundle</span> parameter in <span style="color: #ff9900;">OnCreate()</span> method, we&#8217;d need to check each time if <span style="color: #ff9900;">bundle</span> is not NULL (as we don&#8217;t know whether <span style="color: #ff9900;">OnSaveInstanceState()</span> had been called before).</p>
<p>As a result, the same tab as previously is selected even after rotating the device on <em>MoneyBack</em>&#8216;s <span style="color: #ff9900;">MainActivity</span>:</p>
<p><figure id="attachment_2287" aria-describedby="caption-attachment-2287" style="width: 826px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2287" data-permalink="https://www.codejourney.net/managing-activity-state-changes-using-bundle/moneyback_rotate2-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?fit=4052%2C1968&amp;ssl=1" data-orig-size="4052,1968" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_rotate2" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?fit=300%2C146&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?fit=1024%2C497&amp;ssl=1" class="wp-image-2287" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?resize=826%2C402&#038;ssl=1" alt="" width="826" height="402" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?resize=300%2C146&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?resize=768%2C373&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?resize=1024%2C497&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?resize=720%2C350&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?w=2280&amp;ssl=1 2280w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/MoneyBack_rotate2-1.png?w=3420&amp;ssl=1 3420w" sizes="auto, (max-width: 826px) 100vw, 826px" /></a><figcaption id="caption-attachment-2287" class="wp-caption-text"><em>MoneyBack</em> &#8211; keeping tab selected when rotating</figcaption></figure></p>
<h2>&#8220;Automatic&#8221; state changes handled by Android OS</h2>
<p>Maybe you noticed in your Android application, that not every UI element needs to be handled &#8220;manually&#8221; by implementing the above-mentioned methods in order to save its state. Android performs some kind of &#8220;automatic&#8221; saving and restoration of basic UI elements&#8217; states.</p>
<p>The rule here is that as long as UI element (like <span style="color: #ff9900;">TextView</span> or <span style="color: #ff9900;">Button</span>) has its <span style="color: #ff9900;">android:id</span> set in <em>.axml</em> layout file, OS will automatically manage those elements&#8217; states (e.g. text entered into <span style="color: #ff9900;">EditText</span>).</p>
<p>For example, for <span style="color: #ff9900;">EditText</span> declared like that:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist48172903" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-edittext-axml" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-xml  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="EditText.axml content, created by dsibinski on 08:51PM on May 29, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="EditText.axml">
<tr>
<td id="file-edittext-axml-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-edittext-axml-LC1" class="blob-code blob-code-inner js-file-line">  &lt;EditText</td>
</tr>
<tr>
<td id="file-edittext-axml-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-edittext-axml-LC2" class="blob-code blob-code-inner js-file-line">  android:layout_width=&quot;match_parent&quot;</td>
</tr>
<tr>
<td id="file-edittext-axml-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-edittext-axml-LC3" class="blob-code blob-code-inner js-file-line">  android:layout_height=&quot;wrap_content&quot;</td>
</tr>
<tr>
<td id="file-edittext-axml-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-edittext-axml-LC4" class="blob-code blob-code-inner js-file-line">  android:id=&quot;@+id/inputEventName&quot;</td>
</tr>
<tr>
<td id="file-edittext-axml-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-edittext-axml-LC5" class="blob-code blob-code-inner js-file-line">  android:fadingEdge=&quot;none&quot; /&gt;</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/0b3920ba34d87ac7b8d70bab199dd430/raw/c41dc4d096994c0be50c064a2f3331c7e7a710d3/EditText.axml" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/0b3920ba34d87ac7b8d70bab199dd430#file-edittext-axml" class="Link--inTextBlock"><br />
          EditText.axml<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>its properties (especially its <strong>Text</strong> property) will be automatically saved and restored on screen orientation changes.</p>
<h2>Summary</h2>
<p>We&#8217;ve seen how to handle Android Activities&#8217; state changes caused by configuration modification (e.g. screen orientation change, Activity being killed by the OS in order to free some resources etc.) by implementing <span style="color: #ff9900;">OnSaveInstanceState()</span> and <span style="color: #ff9900;">OnRestoreInstanceState()</span>, where we added and retrieved key-value data to/from <span style="color: #ff9900;">Bundle</span> serialized dictionary. We just need to remember that those methods are not always called (e.g. when navigating between Activities using &#8220;back&#8221; button), so these should be used only for certain kind of state changes.</p>
<p>We&#8217;ve also seen that UI controls with their <span style="color: #ff9900;">android:id</span> defined in layout files have their states <em>resistant</em> for configuration changes (handled automatically by Android OS).</p>
<p><span style="color: #ff9900;">Bundle</span> dictionary is serialized for better performance and memory utilization, so only simple-typed values should be stored in it (like strings or integers). In order to store more complex data, Android provides different possibilities of managing it (e.g. using <a href="https://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance()" target="_blank" rel="noopener noreferrer">OnRetainNonConfigurationInstance</a>).</p>
<p>The post <a href="https://www.codejourney.net/managing-activity-state-changes-using-bundle/">Managing Activity state changes using Bundle</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/managing-activity-state-changes-using-bundle/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2281</post-id>	</item>
		<item>
		<title>Date selection using DatePickerDialog in Xamarin.Android</title>
		<link>https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/</link>
					<comments>https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 27 May 2017 13:19:47 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[moneyback]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2266</guid>

					<description><![CDATA[<p>In this post, we&#8217;re going to see how to provide a nice Android UI control for selecting the date using DatePickerDialog. The dialog looks as follows: It may be opened e.g. when clicking on a button in the app, as I used it in MoneyBack. Creating DatePickerFragment First of all, we will implement the dialog to be displayed&#8230;</p>
<p>The post <a href="https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/">Date selection using DatePickerDialog in Xamarin.Android</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this post, we&#8217;re going to see how to provide a nice Android UI control for selecting the date using <span style="color: #ff9900;">DatePickerDialog</span>.<br />
<span id="more-2266"></span></p>
<p>The dialog looks as follows:</p>
<p><figure id="attachment_2267" aria-describedby="caption-attachment-2267" style="width: 238px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2267" data-permalink="https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/event_datepicker/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Event_DatePicker" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?fit=576%2C1024&amp;ssl=1" class="wp-image-2267 " src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?resize=238%2C423&#038;ssl=1" alt="" width="238" height="423" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?resize=720%2C1280&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DatePicker.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 238px) 100vw, 238px" /></a><figcaption id="caption-attachment-2267" class="wp-caption-text">DatePickerDialog</figcaption></figure></p>
<p>It may be opened e.g. when clicking on a button in the app, as I used it in <em>MoneyBack</em>.</p>
<h2>Creating DatePickerFragment</h2>
<p>First of all, we will implement the dialog to be displayed within <span style="color: #ff6600;">DialogFragment.</span> Doing that our dialog will be able to be displayed as independent piece of UI on the top of any Activity.</p>
<p>The second requirement is to implement <span style="color: #ff6600;">IOnDateSetListener</span> interface (coming from Java/Android), which provides a callback on date selection action done by the user.</p>
<p>The <span style="color: #ff6600;">DatePickerFragment</span> meeting those two requirements may look as follows:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist48103396" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-datepickerfragment-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="DatePickerFragment.cs content, created by dsibinski on 12:35PM on May 27, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="DatePickerFragment.cs">
<tr>
<td id="file-datepickerfragment-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-datepickerfragment-cs-LC1" class="blob-code blob-code-inner js-file-line">  public class DatePickerFragment : DialogFragment, DatePickerDialog.IOnDateSetListener</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-datepickerfragment-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-datepickerfragment-cs-LC3" class="blob-code blob-code-inner js-file-line">      public static readonly string TAG = &quot;X:&quot; + typeof(DatePickerFragment).Name.ToUpper();</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-datepickerfragment-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-datepickerfragment-cs-LC5" class="blob-code blob-code-inner js-file-line">      Action&lt;DateTime&gt; _dateSelectedHandler = delegate { };</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-datepickerfragment-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-datepickerfragment-cs-LC7" class="blob-code blob-code-inner js-file-line">      public DatePickerFragment(Action&lt;DateTime&gt; onDateSelected)</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-datepickerfragment-cs-LC8" class="blob-code blob-code-inner js-file-line">      {</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-datepickerfragment-cs-LC9" class="blob-code blob-code-inner js-file-line">          _dateSelectedHandler = onDateSelected;</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-datepickerfragment-cs-LC10" class="blob-code blob-code-inner js-file-line">      }</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-datepickerfragment-cs-LC11" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-datepickerfragment-cs-LC12" class="blob-code blob-code-inner js-file-line">      public override Dialog OnCreateDialog(Bundle savedInstanceState)</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-datepickerfragment-cs-LC13" class="blob-code blob-code-inner js-file-line">      {</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-datepickerfragment-cs-LC14" class="blob-code blob-code-inner js-file-line">          DateTime now = DateTime.Now;</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-datepickerfragment-cs-LC15" class="blob-code blob-code-inner js-file-line">          return new DatePickerDialog(Activity, </td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-datepickerfragment-cs-LC16" class="blob-code blob-code-inner js-file-line">              this,</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-datepickerfragment-cs-LC17" class="blob-code blob-code-inner js-file-line">              now.Year,</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-datepickerfragment-cs-LC18" class="blob-code blob-code-inner js-file-line">              now.Month,</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-datepickerfragment-cs-LC19" class="blob-code blob-code-inner js-file-line">              now.Day);</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-datepickerfragment-cs-LC20" class="blob-code blob-code-inner js-file-line">      }</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-datepickerfragment-cs-LC21" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-datepickerfragment-cs-LC22" class="blob-code blob-code-inner js-file-line">      public void OnDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-datepickerfragment-cs-LC23" class="blob-code blob-code-inner js-file-line">      {</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-datepickerfragment-cs-LC24" class="blob-code blob-code-inner js-file-line">          DateTime selectedDate = new DateTime(year, monthOfYear + 1, dayOfMonth);</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-datepickerfragment-cs-LC25" class="blob-code blob-code-inner js-file-line">          _dateSelectedHandler(selectedDate);</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
<td id="file-datepickerfragment-cs-LC26" class="blob-code blob-code-inner js-file-line">      }</td>
</tr>
<tr>
<td id="file-datepickerfragment-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
<td id="file-datepickerfragment-cs-LC27" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/6bddb5f760a83b1d190d7d20362f1546/raw/eb5d54ac22e31860c2925eaa58ec078d545d43d2/DatePickerFragment.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/6bddb5f760a83b1d190d7d20362f1546#file-datepickerfragment-cs" class="Link--inTextBlock"><br />
          DatePickerFragment.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>There are few crucial parts in above-listed class:</p>
<ul>
<li>Line 1: as said before, the class derives from <span style="color: #ff6600;">DialogFragment</span> and implements <span style="color: #ff6600;">IOnDateSetListener</span> interface</li>
<li>Line 3: here we have <span style="color: #ff6600;">public static readonly string TAG</span> variable defined &#8211; it is used as a unique identifier of the <span style="color: #ff6600;">Fragment</span>; in some cases, <span style="color: #ff6600;">Fragments</span> can be displayed without any UI &#8211; in such case the only possibility to identify and get the <span style="color: #ff6600;">Fragment</span> is by using <a href="https://developer.android.com/reference/android/app/FragmentManager.html#findFragmentByTag(java.lang.String)" target="_blank" rel="noopener noreferrer">findFragmentByTag()</a> method</li>
<li>Lines 5-10: define <span style="color: #ff6600;">_dateSelectedHandler</span> delegate which may be provided to the constructor of our <span style="color: #ff6600;">DatePickerFragment</span> with the method to be called-back when user selects a date</li>
<li>Lines 12-20: inheriting from <span style="color: #ff6600;">DialogFragment</span> allows us to override its <a href="https://developer.android.com/reference/android/app/DialogFragment.html#Lifecycle" target="_blank" rel="noopener noreferrer">lifecycle methods</a> &#8211; one of them is <span style="color: #ff6600;">Dialog <span style="color: #993300;">OnCreateDialog</span>(Bundle <span style="color: #993300;">savedInstanceState</span>)</span>, in which we actually create the <span style="color: #ff6600;">Dialog</span>-inheriting class &#8211; in our case &#8211; <span style="color: #ff6600;">DatePickerDialog</span> &#8211; with initially selected date (set to current date in the provided example)</li>
<li>Lines 22-26: implementing <span style="color: #ff9900;">IOnDateSetListener </span>interface requires to implement <span style="color: #ff9900;">OnDateSet</span> method, which is called when the user selects the date and clicks &#8220;OK&#8221; button;<b><br />
NOTE</b>: one of this method&#8217;s arguments is <span style="color: #ff9900;">monthOfYear</span> integer value, which contains month number expressed as values 0-11 (NOT 1-12) for compatibility with <a href="https://developer.android.com/reference/java/util/Calendar.html#MONTH" target="_blank" rel="noopener noreferrer">java.util.Calendar.MONTH</a></li>
</ul>
<h2>Using DatePickerFragment</h2>
<p>In <em>MoneyBack</em> application I&#8217;ve used <span style="color: #ff9900;">DatePickerFragment</span> on creating/modifying an event, when user needs to select its date:</p>
<p><figure id="attachment_2275" aria-describedby="caption-attachment-2275" style="width: 223px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2275" data-permalink="https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/event_dateselection/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Event_DateSelection" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?fit=576%2C1024&amp;ssl=1" class="wp-image-2275" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?resize=223%2C396&#038;ssl=1" alt="" width="223" height="396" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?resize=720%2C1280&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/Event_DateSelection.png?w=1080&amp;ssl=1 1080w" sizes="auto, (max-width: 223px) 100vw, 223px" /></a><figcaption id="caption-attachment-2275" class="wp-caption-text"><em>MoneyBack</em> &#8211; event&#8217;s date selection</figcaption></figure></p>
<p>As soon as the button is clicked, the following code executes:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist48103872" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-eventdetailsactivity_dateclick-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="EventDetailsActivity_DateClick.cs content, created by dsibinski on 12:57PM on May 27, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="EventDetailsActivity_DateClick.cs">
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC1" class="blob-code blob-code-inner js-file-line">  private void _btnSelectDate_Click(object sender, EventArgs e)</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC3" class="blob-code blob-code-inner js-file-line">      new DatePickerFragment(delegate(DateTime time)</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC4" class="blob-code blob-code-inner js-file-line">          {</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC5" class="blob-code blob-code-inner js-file-line">              _selectedDate = time;</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC6" class="blob-code blob-code-inner js-file-line">              _btnSelectDate.Text = _selectedDate.ToLongDateString();</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC7" class="blob-code blob-code-inner js-file-line">          })</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC8" class="blob-code blob-code-inner js-file-line">          .Show(FragmentManager, DatePickerFragment.TAG);</td>
</tr>
<tr>
<td id="file-eventdetailsactivity_dateclick-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-eventdetailsactivity_dateclick-cs-LC9" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/930a05f6a51752d773651941b1dd5135/raw/4ef6b702c3c5ee9580a66ee6aef6310772856ad7/EventDetailsActivity_DateClick.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/930a05f6a51752d773651941b1dd5135#file-eventdetailsactivity_dateclick-cs" class="Link--inTextBlock"><br />
          EventDetailsActivity_DateClick.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>As you can see, to <span style="color: #ff9900;">DatePickerFragment</span>&#8216;s constructor I&#8217;m providing the delegate with a method to be called when the date is selected by the user (setting <span style="color: #ff9900;">_selectedDate</span> property with selected <span style="color: #ff9900;">time</span> and putting the date in short format as button&#8217;s <span style="color: #ff9900;">Text</span>).</p>
<p>In order to display a dialog, <a href="https://developer.android.com/reference/android/app/DialogFragment.html#show(android.app.FragmentManager, java.lang.String)" target="_blank" rel="noopener noreferrer">Show</a> method is called, taking current <span style="color: #ff9900;">FragmentManager</span> and already mentioned per-Fragment-unique <span style="color: #ff9900;">tag string</span>, defined statically in <span style="color: #ff9900;">DatePickerFragment</span> class.</p>
<h2>Summary</h2>
<p>Today&#8217;s short post presented how to easily create a <span style="color: #ff9900;">DialogFragment</span> showing <span style="color: #ff9900;">DatePickerDialog</span> for date selection, which allows to provide any method to be called-back when the date is selected by the user.</p>
<p>I hope you&#8217;ll find it useful <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/">Date selection using DatePickerDialog in Xamarin.Android</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/date-selection-using-datepickerdialog-in-xamarin-android/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2266</post-id>	</item>
		<item>
		<title>SQLite-Net Extensions – one-to-many relationships</title>
		<link>https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/</link>
					<comments>https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 22 May 2017 22:01:46 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[sqlite-net-extensions]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2251</guid>

					<description><![CDATA[<p>In the 3rd post from SQLite-Net Extensions series we are covering the last type of relationship &#8211; one-to-many (and the opposite &#8211; many-to-one). One-to-many, many-to-one One-to-many relationships are used in general for parent-children or whole-elements relations. Classic examples are: bus and passengers, document and elements etc. One-to-many relationship means that the one-end entity knows about its&#8230;</p>
<p>The post <a href="https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/">SQLite-Net Extensions – one-to-many relationships</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In the 3rd post from <a href="https://www.codejourney.net/tag/sqlite-net-extensions/" target="_blank" rel="noopener noreferrer">SQLite-Net Extensions series</a> we are covering the last type of relationship &#8211; <em>one-to-many</em> (and the opposite &#8211; <em>many-to-one</em>).<br />
<span id="more-2251"></span></p>
<h2>One-to-many, many-to-one</h2>
<p><strong>One-to-many</strong> relationships are used in general for <em>parent-children</em> or <em>whole-elements</em> relations. Classic examples are: bus and passengers, document and elements etc.</p>
<p>One-to-many relationship means that the <em>one-end</em> entity knows about its children and <em>many-end</em> entity has a reference (foreign key) to its parent (but not necessarily <span style="text-decoration: underline;">knows</span> about it).</p>
<p>On the other hand, the opposite relationship to one-to-many is <strong>many-to-one</strong>. In that case, <em>many-end</em> entity has a reference to its parent and <span style="text-decoration: underline;">knows </span>about it, but the <em>one-end</em> entity doesn&#8217;t necessarily <span style="text-decoration: underline;">know</span> about its children (at least not directly).</p>
<p>I used a verb <span style="text-decoration: underline;">to know</span> several times &#8211; so it&#8217;s time to explain it 🙂 By &#8220;knowing&#8221; about the other end of a relationship I understand <span style="text-decoration: underline;">having a reference to it</span>. It means that, for instance, in many-to-one relationship, the one-end of it doesn&#8217;t have a reference to its children.</p>
<p>However in most cases what we&#8217;d like to have is a <strong>hybrid of one-to-many and many-to-one relationships</strong>. I will call it <strong>one-to-many with inversion</strong>. We want both parent to know about its children, and each children to know about its parent.</p>
<p>In this post we&#8217;ll cover one-to-many with no reversion and one-to-many with reversion, as it also includes many-to-one relationship so you can have a comprehensive overview. We are going to see it on the example of <strong>Employee</strong> and <strong>Duty*</strong> entities. Each employee has a list of his duties, whilst each single duty is assigned to only one employee.</p>
<p><span style="font-size: 10pt;">* &#8220;Task&#8221; would probably be a better name, but I didn&#8217;t want to make it confused with <a href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx" target="_blank" rel="noopener noreferrer">.NET Tasks</a> 🙂</span></p>
<h2>One-to-many with no inversion</h2>
<p>Firstly, let&#8217;s model this kind of relationship:</p>
<p><figure id="attachment_2252" aria-describedby="caption-attachment-2252" style="width: 485px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2252" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/1tm_noinv_uml/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?fit=783%2C149&amp;ssl=1" data-orig-size="783,149" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1495493793&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1tm_noInv_UML" data-image-description="" data-image-caption="&lt;p&gt;One-to-many with no inversion &amp;#8211; class diagram&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?fit=300%2C57&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?fit=783%2C149&amp;ssl=1" class="wp-image-2252" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?resize=485%2C92&#038;ssl=1" alt="" width="485" height="92" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?resize=300%2C57&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?resize=768%2C146&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?resize=720%2C137&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_noInv_UML.jpg?w=783&amp;ssl=1 783w" sizes="auto, (max-width: 485px) 100vw, 485px" /></a><figcaption id="caption-attachment-2252" class="wp-caption-text">One-to-many with no inversion &#8211; class diagram</figcaption></figure></p>
<p>Now we can transform it into C# classes:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47944669" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-employee-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Employee.cs content, created by dsibinski on 08:58PM on May 22, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Employee.cs">
<tr>
<td id="file-employee-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-employee-cs-LC1" class="blob-code blob-code-inner js-file-line">    [Table(&quot;Employees&quot;)]</td>
</tr>
<tr>
<td id="file-employee-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-employee-cs-LC2" class="blob-code blob-code-inner js-file-line">    public class Employee</td>
</tr>
<tr>
<td id="file-employee-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-employee-cs-LC3" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-employee-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-employee-cs-LC4" class="blob-code blob-code-inner js-file-line">        [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-employee-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-employee-cs-LC5" class="blob-code blob-code-inner js-file-line">        public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-employee-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-employee-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employee-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-employee-cs-LC7" class="blob-code blob-code-inner js-file-line">        public string Name { get; set; }</td>
</tr>
<tr>
<td id="file-employee-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-employee-cs-LC8" class="blob-code blob-code-inner js-file-line">        public string LastName { get; set; }</td>
</tr>
<tr>
<td id="file-employee-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-employee-cs-LC9" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employee-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-employee-cs-LC10" class="blob-code blob-code-inner js-file-line">        [OneToMany]</td>
</tr>
<tr>
<td id="file-employee-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-employee-cs-LC11" class="blob-code blob-code-inner js-file-line">        public List&lt;Duty&gt; Duties { get; set; }</td>
</tr>
<tr>
<td id="file-employee-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-employee-cs-LC12" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/7a4bba5b4769a57e286b951d7d830965/raw/5eea39ad5f5ed9597cad5cd3c3677da964b7e42f/Employee.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/7a4bba5b4769a57e286b951d7d830965#file-employee-cs" class="Link--inTextBlock"><br />
          Employee.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>In the <span style="color: #ff6600;">Employee</span> class (parent, one-end of the relationship) we define the collection of children, decorated with <span style="color: #ff6600;">OneToManyAttribute</span>. Collections types supported as for the time of writing this post by SQLite-Net Extensions are <a href="https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx" target="_blank" rel="noopener noreferrer">List</a> and <a href="https://msdn.microsoft.com/en-us/library/system.array(v=vs.110).aspx" target="_blank" rel="noopener noreferrer">Array</a> and can be used as you prefer.</p>
<p>Let&#8217;s now see how the child entity (<span style="color: #ff6600;">Duty</span>) looks like:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47944678" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-duty-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Duty.cs content, created by dsibinski on 08:59PM on May 22, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Duty.cs">
<tr>
<td id="file-duty-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-duty-cs-LC1" class="blob-code blob-code-inner js-file-line">    [Table(&quot;Duties&quot;)]</td>
</tr>
<tr>
<td id="file-duty-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-duty-cs-LC2" class="blob-code blob-code-inner js-file-line">    public class Duty</td>
</tr>
<tr>
<td id="file-duty-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-duty-cs-LC3" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-duty-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-duty-cs-LC4" class="blob-code blob-code-inner js-file-line">        [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-duty-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-duty-cs-LC5" class="blob-code blob-code-inner js-file-line">        public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-duty-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-duty-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-duty-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-duty-cs-LC7" class="blob-code blob-code-inner js-file-line">        public string Description { get; set; }</td>
</tr>
<tr>
<td id="file-duty-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-duty-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-duty-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-duty-cs-LC9" class="blob-code blob-code-inner js-file-line">        public DateTime Deadline { get; set; }</td>
</tr>
<tr>
<td id="file-duty-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-duty-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-duty-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-duty-cs-LC11" class="blob-code blob-code-inner js-file-line">        [ForeignKey(typeof(Employee))]</td>
</tr>
<tr>
<td id="file-duty-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-duty-cs-LC12" class="blob-code blob-code-inner js-file-line">        public int EmployeeId { get; set; }</td>
</tr>
<tr>
<td id="file-duty-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-duty-cs-LC13" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/194a755eb249ea9b4b2a2957c8a5bdbd/raw/b482ad831f693d7d06db28e89c462c3fe3f055d9/Duty.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/194a755eb249ea9b4b2a2957c8a5bdbd#file-duty-cs" class="Link--inTextBlock"><br />
          Duty.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>In the <span style="color: #ff6600;">Duty</span> class (child, many-end of the relationship) we need to have a foreign key to parent entity defined. For that purpose, we create a property representing it (<span style="color: #ff6600;">EmployeeId</span>), decorating it with <span style="color: #ff6600;">ForeignKeyAttribute</span>, additionally specifying the type of parent referenced (<span style="color: #ff6600;">Employee</span>).</p>
<p>That&#8217;s it. We can already use it in our code:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47944855" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-employeeduty_noinv-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="EmployeeDuty_noInv.cs content, created by dsibinski on 09:05PM on May 22, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="EmployeeDuty_noInv.cs">
<tr>
<td id="file-employeeduty_noinv-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-employeeduty_noinv-cs-LC1" class="blob-code blob-code-inner js-file-line">  var db = new SQLiteConnection(new SQLitePlatformAndroid(), Constants.DbFilePath);</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-employeeduty_noinv-cs-LC2" class="blob-code blob-code-inner js-file-line">  db.CreateTable&lt;Employee&gt;();</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-employeeduty_noinv-cs-LC3" class="blob-code blob-code-inner js-file-line">  db.CreateTable&lt;Duty&gt;();</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-employeeduty_noinv-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-employeeduty_noinv-cs-LC5" class="blob-code blob-code-inner js-file-line">  var employee = new Employee</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-employeeduty_noinv-cs-LC6" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-employeeduty_noinv-cs-LC7" class="blob-code blob-code-inner js-file-line">      Name = &quot;Andrew&quot;,</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-employeeduty_noinv-cs-LC8" class="blob-code blob-code-inner js-file-line">      LastName = &quot;Programmer&quot;</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-employeeduty_noinv-cs-LC9" class="blob-code blob-code-inner js-file-line">  };</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-employeeduty_noinv-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-employeeduty_noinv-cs-LC11" class="blob-code blob-code-inner js-file-line">  var duty1 = new Duty()</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-employeeduty_noinv-cs-LC12" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-employeeduty_noinv-cs-LC13" class="blob-code blob-code-inner js-file-line">      Description = &quot;Project A Management&quot;,</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-employeeduty_noinv-cs-LC14" class="blob-code blob-code-inner js-file-line">      Deadline = new DateTime(2017, 10, 31)</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-employeeduty_noinv-cs-LC15" class="blob-code blob-code-inner js-file-line">  };</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-employeeduty_noinv-cs-LC16" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-employeeduty_noinv-cs-LC17" class="blob-code blob-code-inner js-file-line">  var duty2 = new Duty()</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-employeeduty_noinv-cs-LC18" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-employeeduty_noinv-cs-LC19" class="blob-code blob-code-inner js-file-line">      Description = &quot;Reporting work time&quot;,</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-employeeduty_noinv-cs-LC20" class="blob-code blob-code-inner js-file-line">      Deadline = new DateTime(2022, 12, 31)</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-employeeduty_noinv-cs-LC21" class="blob-code blob-code-inner js-file-line">  };</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-employeeduty_noinv-cs-LC22" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-employeeduty_noinv-cs-LC23" class="blob-code blob-code-inner js-file-line">  db.Insert(employee);</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-employeeduty_noinv-cs-LC24" class="blob-code blob-code-inner js-file-line">  db.Insert(duty1);</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-employeeduty_noinv-cs-LC25" class="blob-code blob-code-inner js-file-line">  db.Insert(duty2);</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
<td id="file-employeeduty_noinv-cs-LC26" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
<td id="file-employeeduty_noinv-cs-LC27" class="blob-code blob-code-inner js-file-line">  employee.Duties = new List&lt;Duty&gt; {duty1, duty2};</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
<td id="file-employeeduty_noinv-cs-LC28" class="blob-code blob-code-inner js-file-line">  db.UpdateWithChildren(employee);</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
<td id="file-employeeduty_noinv-cs-LC29" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employeeduty_noinv-cs-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
<td id="file-employeeduty_noinv-cs-LC30" class="blob-code blob-code-inner js-file-line">  var employeeStored = db.GetWithChildren&lt;Employee&gt;(employee.Id);</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/75df037ed90ffab99e5bb313241e8e3c/raw/b24fce0392c8be8078423f1d4c472ced73eef96a/EmployeeDuty_noInv.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/75df037ed90ffab99e5bb313241e8e3c#file-employeeduty_noinv-cs" class="Link--inTextBlock"><br />
          EmployeeDuty_noInv.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>No rocket-science here. What&#8217;s interesting for us it how <span style="color: #ff6600;">employeeStored</span> looks in the end:</p>
<p><figure id="attachment_2260" aria-describedby="caption-attachment-2260" style="width: 468px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2260" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/1tm_noinv_debug-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?fit=478%2C171&amp;ssl=1" data-orig-size="478,171" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1tM_noInv_debug" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?fit=300%2C107&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?fit=478%2C171&amp;ssl=1" class="wp-image-2260" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?resize=468%2C167&#038;ssl=1" alt="" width="468" height="167" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?resize=300%2C107&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_noInv_debug-1.png?w=478&amp;ssl=1 478w" sizes="auto, (max-width: 468px) 100vw, 468px" /></a><figcaption id="caption-attachment-2260" class="wp-caption-text">One-to-many with no inversion</figcaption></figure></p>
<p>As you can see, <span style="color: #ff6600;">GetWithChildren</span> method returned object of type <span style="color: #ff6600;">Employee</span> with its <span style="color: #ff6600;">Duties</span> collection properly retrieved (containing two duties assigned to the employee before). Moreover, each children has its foreign key (<span style="color: #ff6600;">EmployeeId</span>) automatically retrieved from the DB &#8211; there is no overhead here, this is simply foreign key field stored in the same SQLite database table (<em>Duties</em>).</p>
<h2>One-to-many with inversion (one-to-many + many-to-one)</h2>
<p>As previously, let&#8217;s first see how the class diagram changes after adding inversion:</p>
<p><figure id="attachment_2259" aria-describedby="caption-attachment-2259" style="width: 504px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2259" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/1tm_withinv_uml/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?fit=790%2C156&amp;ssl=1" data-orig-size="790,156" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1495493850&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1tm_withInv_UML" data-image-description="" data-image-caption="&lt;p&gt;One-to-many with inversion&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?fit=300%2C59&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?fit=790%2C156&amp;ssl=1" class="wp-image-2259" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?resize=504%2C99&#038;ssl=1" alt="" width="504" height="99" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?resize=300%2C59&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?resize=768%2C152&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?resize=720%2C142&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tm_withInv_UML.jpg?w=790&amp;ssl=1 790w" sizes="auto, (max-width: 504px) 100vw, 504px" /></a><figcaption id="caption-attachment-2259" class="wp-caption-text">One-to-many with inversion &#8211; class diagram</figcaption></figure></p>
<p>What changed is that now each <span style="color: #ff6600;">Duty</span> has a property of type <span style="color: #ff6600;">Employee</span>.</p>
<p>To realize the above class diagram and make each children (each <span style="color: #ff6600;">Duty</span> in our case) knowing about its parent (having a reference to responsible <span style="color: #ff6600;">Employee</span>), the only thing we need to do is to add the following property to <span style="color: #ff6600;">Duty</span> model class:</p>
<pre><pre class="brush: csharp; title: ; notranslate">&#x5B;ManyToOne]
public Employee Employee { get; set; }</pre>
<p>so the model class finally looks as follows:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47945603" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-employee_withinv-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Employee_withInv.cs content, created by dsibinski on 09:34PM on May 22, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Employee_withInv.cs">
<tr>
<td id="file-employee_withinv-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-employee_withinv-cs-LC1" class="blob-code blob-code-inner js-file-line">  [Table(&quot;Duties&quot;)]</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-employee_withinv-cs-LC2" class="blob-code blob-code-inner js-file-line">  public class Duty</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-employee_withinv-cs-LC3" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-employee_withinv-cs-LC4" class="blob-code blob-code-inner js-file-line">      [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-employee_withinv-cs-LC5" class="blob-code blob-code-inner js-file-line">      public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-employee_withinv-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-employee_withinv-cs-LC7" class="blob-code blob-code-inner js-file-line">      public string Description { get; set; }</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-employee_withinv-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-employee_withinv-cs-LC9" class="blob-code blob-code-inner js-file-line">      public DateTime Deadline { get; set; }</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-employee_withinv-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-employee_withinv-cs-LC11" class="blob-code blob-code-inner js-file-line">      [ForeignKey(typeof(Employee))]</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-employee_withinv-cs-LC12" class="blob-code blob-code-inner js-file-line">      public int EmployeeId { get; set; }</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-employee_withinv-cs-LC13" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-employee_withinv-cs-LC14" class="blob-code blob-code-inner js-file-line">      [ManyToOne]</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-employee_withinv-cs-LC15" class="blob-code blob-code-inner js-file-line">      public Employee Employee { get; set; }</td>
</tr>
<tr>
<td id="file-employee_withinv-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-employee_withinv-cs-LC16" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/270d672a47715a6f0e76ce4747048b3d/raw/fdc1e5a1af839cc859d2b706018f45af64335501/Employee_withInv.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/270d672a47715a6f0e76ce4747048b3d#file-employee_withinv-cs" class="Link--inTextBlock"><br />
          Employee_withInv.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>As you can see, we have just created many-to-one relationship by using <span style="color: #ff6600;">ManyToOneAttribute</span>. So currently we have the hybrid of both types of relationships within out two models.</p>
<p>The usage in our code doesn&#8217;t need to be changed at all. Now, <span style="color: #ff6600;">employeeStored</span> entity after being initialized by the same <span style="color: #ff6600;">GetWithChildren</span> method as previously, for each <span style="color: #ff6600;">Duty</span> in addition to <span style="color: #ff6600;">EmployeeId</span> field also contains <span style="color: #ff6600;">Employee</span> property properly retrieved by SQLite-Net Extensions:</p>
<p><figure id="attachment_2261" aria-describedby="caption-attachment-2261" style="width: 469px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2261" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/1tm_withinv_debug/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?fit=475%2C160&amp;ssl=1" data-orig-size="475,160" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1tM_withInv_debug" data-image-description="" data-image-caption="&lt;p&gt;One-to-many with inversion&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?fit=300%2C101&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?fit=475%2C160&amp;ssl=1" class="wp-image-2261" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?resize=469%2C158&#038;ssl=1" alt="" width="469" height="158" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?resize=300%2C101&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1tM_withInv_debug.png?w=475&amp;ssl=1 475w" sizes="auto, (max-width: 469px) 100vw, 469px" /></a><figcaption id="caption-attachment-2261" class="wp-caption-text">One-to-many with inversion</figcaption></figure></p>
<p>Again, there is no db overhead here, because when retrieving <span style="color: #ff6600;">Employee</span> entity from the database we already have it, so the operation of initializing the <span style="color: #ff6600;">Employee</span> entity in each <span style="color: #ff6600;">Duty</span> contained within <span style="color: #ff6600;">Duties</span> collection doesn&#8217;t require any more database querying.</p>
<h2>Summary</h2>
<p>Today we&#8217;ve seen how to model and use one-to-many (with and without inversion) relationships in SQLite database with the usage of SQLite-Net Extensions. The automatic initialization of one-end or many-end entities by the ORM is extremely helpful when dealing with such kind of objects in our app. The amount of code to be written is also minimal.</p>
<p>We&#8217;ve covered one-to-many and a hybrid of one-to-many + many-to-one relationships, but of course you can also define just many-to-one relationship &#8211; the models would then look <a href="https://gist.github.com/dsibinski/9d4f47a85d4944fb55a888aff57a84a3" target="_blank" rel="noopener noreferrer">as in this Gist</a>. For me, it makes very limited sense, but maybe can be useful in some specific situations.</p>
<p>I invite you to read <a href="https://www.codejourney.net/tag/sqlite-net-extensions/" target="_blank" rel="noopener noreferrer">my other posts about SQLite-Net Extensions ORM</a>, where we also covered the other types of relationships that can be modeled using this library.</p>
<p>As this is already the third post from this series, I&#8217;d like to ask you: <span style="text-decoration: underline;"><strong>what do you think about SQLite-Net Extensions ORM? Do you find it useful? Do you use it in your apps? Can you can recommend some other libraries/ORMs to use with SQLite database that allow to model different kind of relationships?</strong></span></p>
<p>The post <a href="https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/">SQLite-Net Extensions – one-to-many relationships</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/sqlite-net-extensions-one-to-many-relationships/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2251</post-id>	</item>
		<item>
		<title>SQLite-Net Extensions – one-to-one relationships</title>
		<link>https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/</link>
					<comments>https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 21 May 2017 10:18:15 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[sqlite-net-extensions]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2238</guid>

					<description><![CDATA[<p>In this second short post from SQLite-Net Extensions series, we&#8217;re going to see how to create one-to-one relationships using this tiny ORM. One-To-One This is the simplest type of database relationship. An example could be vehicle and registration certificate &#8211; each vehicle has one and only one registration certificate, and one registration certificate is associated&#8230;</p>
<p>The post <a href="https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/">SQLite-Net Extensions – one-to-one relationships</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this second short post from <a href="https://www.codejourney.net/tag/sqlite-net-extensions/" target="_blank" rel="noopener noreferrer">SQLite-Net Extensions</a> series, we&#8217;re going to see how to create one-to-one relationships using this tiny ORM.<br />
<span id="more-2238"></span></p>
<h2>One-To-One</h2>
<p>This is the simplest type of database relationship. An example could be <strong>vehicle</strong> and <strong>registration certificate</strong> &#8211; each vehicle has <em>one and only one</em> registration certificate, and one registration certificate is associated with <em>one and only one</em> vehicle (excluding some extraordinary law rules in other countries that I don&#8217;t know <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ).</p>
<p>We can model it in two ways:</p>
<ul>
<li>as a <strong>one-way</strong> relationship &#8211; in this case only one of the relationship&#8217;s ends knows about the other one</li>
<li>as a <strong>both-ways</strong> (with inversion) relationship &#8211; both relationship&#8217;s ends know about each other.</li>
</ul>
<h4>One-To-One with no inversion (one-way)</h4>
<p>This kind of relationship looks as follows:</p>
<p><figure id="attachment_2240" aria-describedby="caption-attachment-2240" style="width: 490px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2240" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/1t1_norec/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?fit=550%2C135&amp;ssl=1" data-orig-size="550,135" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1495366304&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1t1_noRec" data-image-description="" data-image-caption="&lt;p&gt;One-To-One &amp;#8211; no &lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?fit=300%2C74&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?fit=550%2C135&amp;ssl=1" class="wp-image-2240" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?resize=490%2C121&#038;ssl=1" alt="" width="490" height="121" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?resize=300%2C74&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRec.jpg?w=550&amp;ssl=1 550w" sizes="auto, (max-width: 490px) 100vw, 490px" /></a><figcaption id="caption-attachment-2240" class="wp-caption-text">One-To-One &#8211; one-way &#8211; class diagram</figcaption></figure></p>
<p>We use it when we assume it&#8217;s enough that <span style="color: #ff9900;">Vehicle</span> knows about <span style="color: #ff9900;">RegistrationCertificate</span>, but the document doesn&#8217;t necessarily need to know which car/motor it&#8217;s associated with (at least directly).</p>
<p>In the code, we then create two model classes using SQLite-Net Extensions:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47893553" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-registrationcertificate-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="RegistrationCertificate.cs content, created by dsibinski on 09:36AM on May 21, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="RegistrationCertificate.cs">
<tr>
<td id="file-registrationcertificate-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-registrationcertificate-cs-LC1" class="blob-code blob-code-inner js-file-line">    [Table(&quot;RegistrationCertificates&quot;)]</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-registrationcertificate-cs-LC2" class="blob-code blob-code-inner js-file-line">    public class RegistrationCertificate</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-registrationcertificate-cs-LC3" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-registrationcertificate-cs-LC4" class="blob-code blob-code-inner js-file-line">        [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-registrationcertificate-cs-LC5" class="blob-code blob-code-inner js-file-line">        public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-registrationcertificate-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-registrationcertificate-cs-LC7" class="blob-code blob-code-inner js-file-line">        public string RegistrationNumber { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-registrationcertificate-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-registrationcertificate-cs-LC9" class="blob-code blob-code-inner js-file-line">        public string VIN { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-registrationcertificate-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-registrationcertificate-cs-LC11" class="blob-code blob-code-inner js-file-line">        public string OwnerData { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-registrationcertificate-cs-LC12" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/4970ea35805b27453dc55aa0d5688e5f/raw/f344b75b2d1e98f63d6190c90a8e3221bd5bcb51/RegistrationCertificate.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/4970ea35805b27453dc55aa0d5688e5f#file-registrationcertificate-cs" class="Link--inTextBlock"><br />
          RegistrationCertificate.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47893558" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-vehicle-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Vehicle.cs content, created by dsibinski on 09:37AM on May 21, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Vehicle.cs">
<tr>
<td id="file-vehicle-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-vehicle-cs-LC1" class="blob-code blob-code-inner js-file-line">    [Table(&quot;Vehicles&quot;)]</td>
</tr>
<tr>
<td id="file-vehicle-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-vehicle-cs-LC2" class="blob-code blob-code-inner js-file-line">    public class Vehicle</td>
</tr>
<tr>
<td id="file-vehicle-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-vehicle-cs-LC3" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-vehicle-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-vehicle-cs-LC4" class="blob-code blob-code-inner js-file-line">        [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-vehicle-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-vehicle-cs-LC5" class="blob-code blob-code-inner js-file-line">        public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-vehicle-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-vehicle-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-vehicle-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-vehicle-cs-LC7" class="blob-code blob-code-inner js-file-line">        public string Brand { get; set; }</td>
</tr>
<tr>
<td id="file-vehicle-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-vehicle-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-vehicle-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-vehicle-cs-LC9" class="blob-code blob-code-inner js-file-line">        public DateTime ProductionDate { get; set; }</td>
</tr>
<tr>
<td id="file-vehicle-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-vehicle-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-vehicle-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-vehicle-cs-LC11" class="blob-code blob-code-inner js-file-line">        public decimal EngineCapacity { get; set; }</td>
</tr>
<tr>
<td id="file-vehicle-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-vehicle-cs-LC12" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-vehicle-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-vehicle-cs-LC13" class="blob-code blob-code-inner js-file-line">        [ForeignKey(typeof(RegistrationCertificate))]</td>
</tr>
<tr>
<td id="file-vehicle-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-vehicle-cs-LC14" class="blob-code blob-code-inner js-file-line">        public int RegistrationCertificateId { get; set; }</td>
</tr>
<tr>
<td id="file-vehicle-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-vehicle-cs-LC15" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-vehicle-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-vehicle-cs-LC16" class="blob-code blob-code-inner js-file-line">        [OneToOne]</td>
</tr>
<tr>
<td id="file-vehicle-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-vehicle-cs-LC17" class="blob-code blob-code-inner js-file-line">        public RegistrationCertificate RegistrationCertificate { get; set; }</td>
</tr>
<tr>
<td id="file-vehicle-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-vehicle-cs-LC18" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/7ad52df0e33b6a871c1c46f3e0e2dad0/raw/910a48a372f861e3779abb783c966690ad9e020f/Vehicle.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/7ad52df0e33b6a871c1c46f3e0e2dad0#file-vehicle-cs" class="Link--inTextBlock"><br />
          Vehicle.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>What&#8217;s interesting here is the <span style="color: #ff9900;">ForeignKeyAttribute</span> defined on <span style="color: #ff9900;">RegistrationCertificateId</span> property. It is &#8211; as its name says &#8211; the foreign key to the primary key of related entity (of type <span style="color: #ff9900;">RegistrationCertificate</span>).</p>
<p>The related entity property itself is decorated with <span style="color: #ff9900;">OneToOneAttribute</span>.</p>
<p>There&#8217;s nothing more we need to do to have this relationship modeled. We can already use it:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47893732" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-onetoone_noinv-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="OneToOne_noInv.cs content, created by dsibinski on 09:49AM on May 21, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="OneToOne_noInv.cs">
<tr>
<td id="file-onetoone_noinv-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-onetoone_noinv-cs-LC1" class="blob-code blob-code-inner js-file-line">    var db = new SQLiteConnection(new SQLitePlatformAndroid(), Constants.DbFilePath);</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-onetoone_noinv-cs-LC2" class="blob-code blob-code-inner js-file-line">    db.CreateTable&lt;Vehicle&gt;();</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-onetoone_noinv-cs-LC3" class="blob-code blob-code-inner js-file-line">    db.CreateTable&lt;RegistrationCertificate&gt;();</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-onetoone_noinv-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-onetoone_noinv-cs-LC5" class="blob-code blob-code-inner js-file-line">    var vehicle = new Vehicle</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-onetoone_noinv-cs-LC6" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-onetoone_noinv-cs-LC7" class="blob-code blob-code-inner js-file-line">        Brand = &quot;Renault&quot;,</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-onetoone_noinv-cs-LC8" class="blob-code blob-code-inner js-file-line">        EngineCapacity = 1.9m,</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-onetoone_noinv-cs-LC9" class="blob-code blob-code-inner js-file-line">        ProductionDate = new DateTime(2001, 01, 01)</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-onetoone_noinv-cs-LC10" class="blob-code blob-code-inner js-file-line">    };</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-onetoone_noinv-cs-LC11" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-onetoone_noinv-cs-LC12" class="blob-code blob-code-inner js-file-line">    var certificate = new RegistrationCertificate</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-onetoone_noinv-cs-LC13" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-onetoone_noinv-cs-LC14" class="blob-code blob-code-inner js-file-line">        RegistrationNumber = &quot;AB 12345&quot;,</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-onetoone_noinv-cs-LC15" class="blob-code blob-code-inner js-file-line">        OwnerData = &quot;Dawid Sibiński&quot;,</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-onetoone_noinv-cs-LC16" class="blob-code blob-code-inner js-file-line">        VIN = &quot;1312BS1312ASDSSVVW&quot;</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-onetoone_noinv-cs-LC17" class="blob-code blob-code-inner js-file-line">    };</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-onetoone_noinv-cs-LC18" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-onetoone_noinv-cs-LC19" class="blob-code blob-code-inner js-file-line">    db.Insert(vehicle);</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-onetoone_noinv-cs-LC20" class="blob-code blob-code-inner js-file-line">    db.Insert(certificate);</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-onetoone_noinv-cs-LC21" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-onetoone_noinv-cs-LC22" class="blob-code blob-code-inner js-file-line">    vehicle.RegistrationCertificate = certificate;</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-onetoone_noinv-cs-LC23" class="blob-code blob-code-inner js-file-line">    db.UpdateWithChildren(vehicle);</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-onetoone_noinv-cs-LC24" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-onetoone_noinv-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-onetoone_noinv-cs-LC25" class="blob-code blob-code-inner js-file-line">    var vehicleStored = db.GetWithChildren&lt;Vehicle&gt;(vehicle.Id);</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/c04bd7030750a87ab3898621612eca03/raw/0430326856944469a47713ff2f61393fa349914e/OneToOne_noInv.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/c04bd7030750a87ab3898621612eca03#file-onetoone_noinv-cs" class="Link--inTextBlock"><br />
          OneToOne_noInv.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>Nothing special here, right? It looks very similar to what we&#8217;ve seen in the <a href="https://www.codejourney.net/2017/05/sqlite-net-extensions-many-to-many-relationships/" target="_blank" rel="noopener noreferrer">previous post about many-to-many relationships</a>. What&#8217;s interesting for us it that in the end, when <span style="color: #ff9900;">Vehicle</span> object is retrieved from the database using <span style="color: #ff9900;">GetWithChildren</span> method, its <span style="color: #ff9900;">RegistrationCertificate</span> property is filled as well:</p>
<p><figure id="attachment_2242" aria-describedby="caption-attachment-2242" style="width: 521px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2242" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/1t1_norev_debug/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?fit=809%2C334&amp;ssl=1" data-orig-size="809,334" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1t1_noRev_debug" data-image-description="" data-image-caption="&lt;p&gt;One-To-One &amp;#8211; filled related entity&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?fit=300%2C124&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?fit=809%2C334&amp;ssl=1" class="wp-image-2242" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?resize=521%2C215&#038;ssl=1" alt="" width="521" height="215" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?resize=300%2C124&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?resize=768%2C317&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?resize=720%2C297&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_noRev_debug.png?w=809&amp;ssl=1 809w" sizes="auto, (max-width: 521px) 100vw, 521px" /></a><figcaption id="caption-attachment-2242" class="wp-caption-text">One-To-One &#8211; filled related entity</figcaption></figure></p>
<h4>One-To-One with inversion (both-ways)</h4>
<p>This kind of relationship models itself as below:</p>
<p><figure id="attachment_2241" aria-describedby="caption-attachment-2241" style="width: 560px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?ssl=1" target="_blank" rel="noopener noreferrer"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2241" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/1t1_withrec/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?fit=549%2C135&amp;ssl=1" data-orig-size="549,135" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1495366361&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1t1_withRec" data-image-description="" data-image-caption="&lt;p&gt;One-To-One &amp;#8211; with reversion&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?fit=300%2C74&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?fit=549%2C135&amp;ssl=1" class="wp-image-2241" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?resize=560%2C138&#038;ssl=1" alt="" width="560" height="138" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?resize=300%2C74&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRec.jpg?w=549&amp;ssl=1 549w" sizes="auto, (max-width: 560px) 100vw, 560px" /></a><figcaption id="caption-attachment-2241" class="wp-caption-text">One-To-One &#8211; with inversion &#8211; class diagram</figcaption></figure></p>
<p>What actually changed on the diagram compared to the relationship with no inversion is that now <span style="color: #ff9900;">RegistrationCertificate</span> has a property of type <span style="color: #ff9900;">Vehicle</span> (in the code &#8211; a reference to <span style="color: #ff9900;">Vehicle</span> related object and a foreign key).</p>
<p>In our case, this is even more &#8220;real&#8221; &#8211; it would be nice if a <span style="color: #ff9900;">Vehicle</span> knows about its <span style="color: #ff9900;">RegistrationCertificate</span>, but also when we look at the certificate we&#8217;d like to see to which car it belongs.</p>
<p>We can now model it in the code. The only thing that changes in the model classes is addition of a reference and foreign key to <span style="color: #ff9900;">Vehicle</span> in <span style="color: #ff9900;">RegistrationCertificate</span> model, so I&#8217;m presenting only this class&#8217;s updated code:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47893923" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-registrationcertificate_withinv-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="RegistrationCertificate_withInv.cs content, created by dsibinski on 09:59AM on May 21, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="RegistrationCertificate_withInv.cs">
<tr>
<td id="file-registrationcertificate_withinv-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-registrationcertificate_withinv-cs-LC1" class="blob-code blob-code-inner js-file-line">    [Table(&quot;RegistrationCertificates&quot;)]</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-registrationcertificate_withinv-cs-LC2" class="blob-code blob-code-inner js-file-line">    public class RegistrationCertificate</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-registrationcertificate_withinv-cs-LC3" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-registrationcertificate_withinv-cs-LC4" class="blob-code blob-code-inner js-file-line">        [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-registrationcertificate_withinv-cs-LC5" class="blob-code blob-code-inner js-file-line">        public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-registrationcertificate_withinv-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-registrationcertificate_withinv-cs-LC7" class="blob-code blob-code-inner js-file-line">        public string RegistrationNumber { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-registrationcertificate_withinv-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-registrationcertificate_withinv-cs-LC9" class="blob-code blob-code-inner js-file-line">        public string VIN { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-registrationcertificate_withinv-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-registrationcertificate_withinv-cs-LC11" class="blob-code blob-code-inner js-file-line">        public string OwnerData { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-registrationcertificate_withinv-cs-LC12" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-registrationcertificate_withinv-cs-LC13" class="blob-code blob-code-inner js-file-line">        // added to have Inversion relationship</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-registrationcertificate_withinv-cs-LC14" class="blob-code blob-code-inner js-file-line">        [ForeignKey(typeof(Vehicle))]</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-registrationcertificate_withinv-cs-LC15" class="blob-code blob-code-inner js-file-line">        public int VehicleId { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-registrationcertificate_withinv-cs-LC16" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-registrationcertificate_withinv-cs-LC17" class="blob-code blob-code-inner js-file-line">        [OneToOne]</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-registrationcertificate_withinv-cs-LC18" class="blob-code blob-code-inner js-file-line">        public Vehicle Vehicle { get; set; }</td>
</tr>
<tr>
<td id="file-registrationcertificate_withinv-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-registrationcertificate_withinv-cs-LC19" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/6b5c7250deff7193c3e127dde2c2a947/raw/1b3f383df9c626044d01225b64bcd94c3004ec9c/RegistrationCertificate_withInv.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/6b5c7250deff7193c3e127dde2c2a947#file-registrationcertificate_withinv-cs" class="Link--inTextBlock"><br />
          RegistrationCertificate_withInv.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>What&#8217;s cool here is that we don&#8217;t need to modify our code for saving entities with relationships into SQLite database. We can simply add the following line at the end:</p>
<pre><pre class="brush: csharp; title: ; notranslate">var certificateStored = db.GetWithChildren&amp;lt;RegistrationCertificate&amp;gt;(certificate.Id);</pre>
<p>and notice that <span style="color: #ff9900;">certificateStored</span> already contains its associated <span style="color: #ff9900;">Vehicle</span> object:</p>
<p><figure id="attachment_2243" aria-describedby="caption-attachment-2243" style="width: 604px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2243" data-permalink="https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/1t1_withrev_debug/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?fit=939%2C362&amp;ssl=1" data-orig-size="939,362" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1t1_withRev_debug" data-image-description="" data-image-caption="&lt;p&gt;One-To-One &amp;#8211; Vehicle initialized&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?fit=300%2C116&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?fit=939%2C362&amp;ssl=1" class=" wp-image-2243" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?resize=604%2C234&#038;ssl=1" alt="" width="604" height="234" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?resize=300%2C116&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?resize=768%2C296&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?resize=720%2C278&amp;ssl=1 720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/1t1_withRev_debug.png?w=939&amp;ssl=1 939w" sizes="auto, (max-width: 604px) 100vw, 604px" /></a><figcaption id="caption-attachment-2243" class="wp-caption-text">One-To-One &#8211; Vehicle initialized</figcaption></figure></p>
<h2>Summary</h2>
<p>In today&#8217;s short post we&#8217;ve seen how to create one-to-one relationship between two entities in SQLite database, using SQLite-Net Extensions ORM. It&#8217;s very easy and doesn&#8217;t require using Entity Framework <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> or writing SQL queries directly in our code.</p>
<p>We&#8217;ve covered two types of one-to-one relationships: one-way and both-ways. The choice between those two depends on the usage and purpose of the relationship we model.</p>
<p>I hope you&#8217;ll find it useful one day <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/">SQLite-Net Extensions – one-to-one relationships</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/sqlite-net-extensions-one-to-one-relationships/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2238</post-id>	</item>
		<item>
		<title>SQLite-Net Extensions &#8211; many-to-many relationships</title>
		<link>https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/</link>
					<comments>https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Thu, 18 May 2017 21:23:31 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[sqlite-net-extensions]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=2218</guid>

					<description><![CDATA[<p>In today&#8217;s post we&#8217;re going to see what is SQLite-Net Extensions ORM and how to use it to create many-to-many relationship in SQLite database. The other types of relationships will be described in separate posts. What is SQLite-Net Extensions ? As you develop any mobile app, sooner than later you need to keep your app&#8217;s data&#8230;</p>
<p>The post <a href="https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/">SQLite-Net Extensions &#8211; many-to-many relationships</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In today&#8217;s post we&#8217;re going to see what is SQLite-Net Extensions ORM and how to use it to create many-to-many relationship in SQLite database. The other types of relationships will be described <a href="https://www.codejourney.net/tag/sqlite-net-extensions/" target="_blank" rel="noopener noreferrer">in separate posts</a>.<br />
<span id="more-2218"></span></p>
<h2>What is SQLite-Net Extensions ?</h2>
<p>As you develop any mobile app, sooner than later you need to keep your app&#8217;s data in some persistent storage. In my <em>MoneyBack </em>project I&#8217;ve chosen<em> </em><a href="https://www.codejourney.net/2017/03/using-sqlite-database-in-xamarin-android/" target="_blank" rel="noopener noreferrer">SQLite database using SQLite.NET library for performing operations on it</a>. This is actually very simple and easy-to-use database framework, but I recently realized I need to model some <strong><a href="https://en.wikipedia.org/wiki/Relation_(database)" target="_blank" rel="noopener noreferrer">relations</a> </strong>in my database.  <a href="https://www.nuget.org/packages/sqlite-net/" target="_blank" rel="noopener noreferrer">SQLite.NET</a> doesn&#8217;t offer any nice utilities to model such relations.</p>
<p>However, if you need to model any relations in your SQLite database, there is a wrapper on SQLite.NET which allows to do that &#8211; it is <strong>SQLite-Net Extensions</strong>. It basically extends the core functionalities of SQLite.NET by adding elements that allow to easily handle relationships, including one-to-one, one-to-many, many-to-one and many-to-many.</p>
<p>In this post we are going to see how to create many-to-many relationship using this library. I needed this kind of relationship to model the connection between Person and Event entities in my app.</p>
<h2>Many-to-many relationship</h2>
<p>Let&#8217;s see many-to-many relationship on an example of two entities: <strong>Person</strong> and <strong>Event</strong>. An event (entity of type <span style="color: #ff9900;">Event</span>) may contain zero or more participants (entities of type <span style="color: #ff9900;">Person</span>) whilst a person may be assigned to zero or more events. This is a typical many-to-many relationship which we are going to set up in our database now.</p>
<h2>Install SQLite-Net Extensions</h2>
<p>If you&#8217;ve previously been using <a href="https://www.nuget.org/packages/sqlite-net/" target="_blank" rel="noopener noreferrer">SQLite.NET</a> in your project &#8211; uninstall it first. I didn&#8217;t do it before starting to use SQLite-Net Extensions and I have many troubles with Visual Studio resolving my references incorrectly. SQLite-Net Extensions is a wrapper for SQLite.NET, so it already contains this library and additionally extends it by adding some extra functionalities for handling relationships.</p>
<p>SQLite-Net Extensions can be installed as a Nuget package into your solution. According to the version you&#8217;d like to use, execute appropriate command in Package Manager Console in Visual Studio:</p>
<ul>
<li>synchronous:
<pre><pre class="brush: csharp; title: ; notranslate">Install-Package SQLiteNetExtensions -Version 1.3.0</pre>
</li>
<li>asynchronous:
<pre><pre class="brush: csharp; title: ; notranslate">Install-Package SQLiteNetExtensions.Async -Version 1.3.0</pre>
</li>
</ul>
<h2>Define model classes</h2>
<p>Next we need to define our <span style="color: #ff9900;">Person</span> and <span style="color: #ff9900;">Event</span> model classes and establish the relationships between them. Below, you can find the code of both classes:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47815728" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-person_event-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Person_Event.cs content, created by dsibinski on 08:27PM on May 18, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Person_Event.cs">
<tr>
<td id="file-person_event-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-person_event-cs-LC1" class="blob-code blob-code-inner js-file-line">// Person class modelling People table</td>
</tr>
<tr>
<td id="file-person_event-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-person_event-cs-LC2" class="blob-code blob-code-inner js-file-line">[Table(&quot;People&quot;)]</td>
</tr>
<tr>
<td id="file-person_event-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-person_event-cs-LC3" class="blob-code blob-code-inner js-file-line">public class Person</td>
</tr>
<tr>
<td id="file-person_event-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-person_event-cs-LC4" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-person_event-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-person_event-cs-LC5" class="blob-code blob-code-inner js-file-line">    [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-person_event-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-person_event-cs-LC6" class="blob-code blob-code-inner js-file-line">    public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-person_event-cs-LC7" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-person_event-cs-LC8" class="blob-code blob-code-inner js-file-line">    public string Name { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-person_event-cs-LC9" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-person_event-cs-LC10" class="blob-code blob-code-inner js-file-line">    public string LastName { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-person_event-cs-LC11" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-person_event-cs-LC12" class="blob-code blob-code-inner js-file-line">    public string PhoneNumber { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-person_event-cs-LC13" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-person_event-cs-LC14" class="blob-code blob-code-inner js-file-line">    public string Email { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-person_event-cs-LC15" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-person_event-cs-LC16" class="blob-code blob-code-inner js-file-line">    [ManyToMany(typeof(PersonEvent))]</td>
</tr>
<tr>
<td id="file-person_event-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-person_event-cs-LC17" class="blob-code blob-code-inner js-file-line">    public List&lt;Event&gt; Events { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-person_event-cs-LC18" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="file-person_event-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-person_event-cs-LC19" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-person_event-cs-LC20" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-person_event-cs-LC21" class="blob-code blob-code-inner js-file-line">// Event class modelling Events table</td>
</tr>
<tr>
<td id="file-person_event-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-person_event-cs-LC22" class="blob-code blob-code-inner js-file-line">[Table(&quot;Events&quot;)]</td>
</tr>
<tr>
<td id="file-person_event-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-person_event-cs-LC23" class="blob-code blob-code-inner js-file-line">public class Event</td>
</tr>
<tr>
<td id="file-person_event-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-person_event-cs-LC24" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-person_event-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-person_event-cs-LC25" class="blob-code blob-code-inner js-file-line">    [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-person_event-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
<td id="file-person_event-cs-LC26" class="blob-code blob-code-inner js-file-line">    public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
<td id="file-person_event-cs-LC27" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
<td id="file-person_event-cs-LC28" class="blob-code blob-code-inner js-file-line">    public string Name { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
<td id="file-person_event-cs-LC29" class="blob-code blob-code-inner js-file-line">    public DateTime Date { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
<td id="file-person_event-cs-LC30" class="blob-code blob-code-inner js-file-line">    public string Place { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
<td id="file-person_event-cs-LC31" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person_event-cs-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
<td id="file-person_event-cs-LC32" class="blob-code blob-code-inner js-file-line">    [ManyToMany(typeof(PersonEvent))]</td>
</tr>
<tr>
<td id="file-person_event-cs-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
<td id="file-person_event-cs-LC33" class="blob-code blob-code-inner js-file-line">    public List&lt;Person&gt; Participants { get; set; }</td>
</tr>
<tr>
<td id="file-person_event-cs-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
<td id="file-person_event-cs-LC34" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1b0f1411d6478c7bebc55a451fbda068/raw/70311b99cece5a78262021d3e63a6034ded89ae2/Person_Event.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/1b0f1411d6478c7bebc55a451fbda068#file-person_event-cs" class="Link--inTextBlock"><br />
          Person_Event.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>As you can see, the models look almost the same as SQLite.NET db entities, with the following exceptions:</p>
<ul>
<li><span style="color: #ff9900;">ManyToManyAttribute<span style="color: #000000;"> &#8211; o</span></span>n both entities you can notice this attribute defined. On <span style="color: #ff9900;">Person</span> model class I decorate <span style="color: #ff9900;">Events</span> collection with it whereas on <span style="color: #ff9900;">Event</span> model class I decorate <span style="color: #ff9900;">Participants</span> collection with it. Simple as that.</li>
<li><span style="color: #ff9900;">PersonEvent <span style="color: #000000;">&#8211; y</span></span>ou may have noticed that as an argument to <span style="color: #ff9900;">ManyToManyAttribute</span> on both models I passed <span style="color: #ff9900;">PersonEvent</span> type. As you may know, in modelling many-to-many relationships we need an intermediate entity in order to store such kind of relationship in the database tables. The classic example is Student-Course relationship:<br />
<figure id="attachment_2221" aria-describedby="caption-attachment-2221" style="width: 337px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2221" data-permalink="https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/erd-many-to-many-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?fit=469%2C367&amp;ssl=1" data-orig-size="469,367" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="erd-many-to-many-1" data-image-description="" data-image-caption="&lt;p&gt;Source: smehrozalam&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?fit=300%2C235&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?fit=469%2C367&amp;ssl=1" class=" wp-image-2221" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?resize=337%2C264&#038;ssl=1" alt="" width="337" height="264" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?resize=300%2C235&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/erd-many-to-many-1.jpg?w=469&amp;ssl=1 469w" sizes="auto, (max-width: 337px) 100vw, 337px" /></a><figcaption id="caption-attachment-2221" class="wp-caption-text">Source: <a href="https://smehrozalam.wordpress.com/2010/06/29/entity-framework-queries-involving-many-to-many-relationship-tables/" target="_blank" rel="noopener noreferrer">smehrozalam</a></figcaption></figure></p>
<p>We also need to define such intermediate entity in our code.</p>
</li>
</ul>
<p>The implementation of <span style="color: #ff9900;">PersonEvent</span> intermediate model class looks as follows:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47816049" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-personevent-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="PersonEvent.cs content, created by dsibinski on 08:38PM on May 18, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="PersonEvent.cs">
<tr>
<td id="file-personevent-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-personevent-cs-LC1" class="blob-code blob-code-inner js-file-line">public class PersonEvent</td>
</tr>
<tr>
<td id="file-personevent-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-personevent-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-personevent-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-personevent-cs-LC3" class="blob-code blob-code-inner js-file-line">    [ForeignKey(typeof(Person))]</td>
</tr>
<tr>
<td id="file-personevent-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-personevent-cs-LC4" class="blob-code blob-code-inner js-file-line">    public int PersonId { get; set; }</td>
</tr>
<tr>
<td id="file-personevent-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-personevent-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-personevent-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-personevent-cs-LC6" class="blob-code blob-code-inner js-file-line">    [ForeignKey(typeof(Event))]</td>
</tr>
<tr>
<td id="file-personevent-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-personevent-cs-LC7" class="blob-code blob-code-inner js-file-line">    public int EventId { get; set; }</td>
</tr>
<tr>
<td id="file-personevent-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-personevent-cs-LC8" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/33dc1a774b183f4706174a3a656318b9/raw/e8244edf124388dfe058b148fe5bc67d8b71bc1e/PersonEvent.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/33dc1a774b183f4706174a3a656318b9#file-personevent-cs" class="Link--inTextBlock"><br />
          PersonEvent.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>Thanks to <span style="color: #ff9900;">PrimaryKey</span> attributes defined on <span style="color: #ff9900;">Person</span> and <span style="color: #ff9900;">Event</span> entities the ORM will be able to determine to which primary keys the foreign keys in this intermediate table relate.</p>
<p>In the <span style="color: #ff9900;">ManyToManyAttribute</span>, except the type of intermediate entity, you can set <span style="color: #ff9900;">CascadeOperations</span>, which specifies how the cascading should be handled when working with the entities (e.g. if cascade delete operation should be performed when one of the relationship&#8217;s sides is removed).</p>
<h2>Inserting and reading data</h2>
<p>As soon as our model classes are defined, we can write and read the data with many-to-many relationships. The following code presents a simple way to create a new person and assign it to an event:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist47816466" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-savingpersonevent-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="SavingPersonEvent.cs content, created by dsibinski on 08:47PM on May 18, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="SavingPersonEvent.cs">
<tr>
<td id="file-savingpersonevent-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-savingpersonevent-cs-LC1" class="blob-code blob-code-inner js-file-line">var db = new SQLiteConnection(new SQLitePlatformAndroid(), Constants.DbFilePath);</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-savingpersonevent-cs-LC2" class="blob-code blob-code-inner js-file-line">db.CreateTable&lt;Person&gt;();</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-savingpersonevent-cs-LC3" class="blob-code blob-code-inner js-file-line">db.CreateTable&lt;Event&gt;();</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-savingpersonevent-cs-LC4" class="blob-code blob-code-inner js-file-line">db.CreateTable&lt;PersonEvent&gt;();</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-savingpersonevent-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-savingpersonevent-cs-LC6" class="blob-code blob-code-inner js-file-line">var event1 = new Event</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-savingpersonevent-cs-LC7" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-savingpersonevent-cs-LC8" class="blob-code blob-code-inner js-file-line">    Name = &quot;Volleyball&quot;,</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-savingpersonevent-cs-LC9" class="blob-code blob-code-inner js-file-line">    Date = new DateTime(2017, 06, 18),</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-savingpersonevent-cs-LC10" class="blob-code blob-code-inner js-file-line">    Place = &quot;Sports hall&quot;</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-savingpersonevent-cs-LC11" class="blob-code blob-code-inner js-file-line">};</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-savingpersonevent-cs-LC12" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-savingpersonevent-cs-LC13" class="blob-code blob-code-inner js-file-line">var person1 = new Person</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-savingpersonevent-cs-LC14" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-savingpersonevent-cs-LC15" class="blob-code blob-code-inner js-file-line">    Name = &quot;A&quot;,</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-savingpersonevent-cs-LC16" class="blob-code blob-code-inner js-file-line">    LastName = &quot;B&quot;,</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-savingpersonevent-cs-LC17" class="blob-code blob-code-inner js-file-line">    PhoneNumber = &quot;123456789&quot;</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-savingpersonevent-cs-LC18" class="blob-code blob-code-inner js-file-line">};</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-savingpersonevent-cs-LC19" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-savingpersonevent-cs-LC20" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-savingpersonevent-cs-LC21" class="blob-code blob-code-inner js-file-line">db.Insert(person1);</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-savingpersonevent-cs-LC22" class="blob-code blob-code-inner js-file-line">db.Insert(event1);</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-savingpersonevent-cs-LC23" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-savingpersonevent-cs-LC24" class="blob-code blob-code-inner js-file-line">person1.Events = new List&lt;Event&gt; { event1 };</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-savingpersonevent-cs-LC25" class="blob-code blob-code-inner js-file-line">db.UpdateWithChildren(person1);</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
<td id="file-savingpersonevent-cs-LC26" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
<td id="file-savingpersonevent-cs-LC27" class="blob-code blob-code-inner js-file-line">var personStored = db.GetWithChildren&lt;Person&gt;(person1.Id);</td>
</tr>
<tr>
<td id="file-savingpersonevent-cs-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
<td id="file-savingpersonevent-cs-LC28" class="blob-code blob-code-inner js-file-line">var eventStored = db.GetWithChildren&lt;Event&gt;(event1.Id);</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/4b8566aba0d8280aa5117de3f1ce70fc/raw/5fc7f3d27f4313031c31cb40810e76a0e895b053/SavingPersonEvent.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/4b8566aba0d8280aa5117de3f1ce70fc#file-savingpersonevent-cs" class="Link--inTextBlock"><br />
          SavingPersonEvent.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>Lines 1-4 contain the database initialization (<span style="color: #ff9900;">Constants.DbFilePath</span> just returns an Android path of SQLite database file) and creation of all 3 tables in the database.</p>
<p>Lines 6-18 are simply the creation of <span style="color: #ff9900;">Person</span> and <span style="color: #ff9900;">Event</span> objects, filled with most basic details.</p>
<p>In lines 21 and 22 we firstly save our <span style="color: #ff9900;">person1</span> and <span style="color: #ff9900;">event1</span> entities separately, because in order to establish the relationships we need the primary keys of those entities, that are assigned by the database while saving. This can be also simplified by using recursive operations &#8211; more details in the <a href="https://bitbucket.org/twincoders/sqlite-net-extensions/" target="_blank" rel="noopener noreferrer">official documentation of the ORM</a>.</p>
<p>After that, we assign just created person to the event (line 24) and then the most rocket-science part comes:</p>
<pre><pre class="brush: csharp; title: ; notranslate">db.UpdateWithChildren(person1);</pre>
<p>This method does the write magic &#8211; it updates the person with all its children &#8211; so in our case, the <span style="color: #ff9900;">Events</span> collection. It will make the relationship established.</p>
<p>In order to prove it, in lines 27 and 28 we can check if the relationship collections are populated with children in both entities by calling <span style="color: #ff9900;">GetWithChildren</span> extension methods:</p>
<p><figure id="attachment_2231" aria-describedby="caption-attachment-2231" style="width: 571px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2231" data-permalink="https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/personcontainsevents-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?fit=814%2C321&amp;ssl=1" data-orig-size="814,321" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="personContainsEvents" data-image-description="" data-image-caption="&lt;p&gt;Person containing Events&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?fit=300%2C118&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?fit=814%2C321&amp;ssl=1" class="wp-image-2231 " src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?resize=571%2C225&#038;ssl=1" alt="" width="571" height="225" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?w=814&amp;ssl=1 814w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?resize=300%2C118&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?resize=768%2C303&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/personContainsEvents-1.png?resize=720%2C284&amp;ssl=1 720w" sizes="auto, (max-width: 571px) 100vw, 571px" /></a><figcaption id="caption-attachment-2231" class="wp-caption-text">Person containing Events</figcaption></figure> <figure id="attachment_2228" aria-describedby="caption-attachment-2228" style="width: 573px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="2228" data-permalink="https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/eventcontainsparticipants-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?fit=932%2C390&amp;ssl=1" data-orig-size="932,390" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="eventContainsParticipants" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?fit=300%2C126&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?fit=932%2C390&amp;ssl=1" class="wp-image-2228 " src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?resize=573%2C240&#038;ssl=1" alt="" width="573" height="240" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?w=932&amp;ssl=1 932w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?resize=300%2C126&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?resize=768%2C321&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/05/eventContainsParticipants-1.png?resize=720%2C301&amp;ssl=1 720w" sizes="auto, (max-width: 573px) 100vw, 573px" /></a><figcaption id="caption-attachment-2228" class="wp-caption-text">Event containing Participants</figcaption></figure></p>
<p>That&#8217;s how SQLite-Net Extensions ORM works. It doesn&#8217;t provide any lazy-loading of related entities &#8211; it just adds/retrieves to/from the database exactly what you tell it to. The limitation here is that if you access <span style="color: #ff9900;">Person.Events</span> collection you can see the events this person is in relation with, but if you access <span style="color: #ff9900;">Person.Events[0]</span> you will not see all people registered for this event.</p>
<h2>Summary</h2>
<p>SQLite-Net Extensions is an ORM, which is a wrapper for classic SQLite.NET library. It adds the extension methods/attributes to handle relationships in SQLite database. It doesn&#8217;t provide any lazy-loading mechanism, instead exposing methods for getting/saving entities along with their children (related entities). It&#8217;s lightweight and rather easy to implement, so for small solutions like mobile apps I totally prefer it to writing and maintaining SQL queries directly in C# in order to handle relationships.</p>
<p>In the next posts from the <a href="https://www.codejourney.net/tag/sqlite-net-extensions/" target="_blank" rel="noopener noreferrer">series about SQLite-Net Extensions ORM</a>, I will present to you the other types of relationships this ORM offers. Stay tuned <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&nbsp;</p>
<p>The post <a href="https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/">SQLite-Net Extensions &#8211; many-to-many relationships</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/sqlite-net-extensions-many-to-many-relationships/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2218</post-id>	</item>
		<item>
		<title>Android Apps Localization</title>
		<link>https://www.codejourney.net/android-apps-localization/</link>
					<comments>https://www.codejourney.net/android-apps-localization/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 19 Apr 2017 20:48:55 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=1803</guid>

					<description><![CDATA[<p>Hello everyone 🙂 As you might have noticed, I&#8217;ve recently decided to take a longer break in DSP competition. Few things to do, Easter in the meantime&#8230; but of course I didn&#8217;t give up and today I&#8217;m back 😉 In this post I&#8217;d like to show you how do we localize Android apps. Let&#8217;s see! What&#8230;</p>
<p>The post <a href="https://www.codejourney.net/android-apps-localization/">Android Apps Localization</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Hello everyone 🙂</p>
<p>As you might have noticed, I&#8217;ve recently decided to take a longer break in DSP competition. Few things to do, Easter in the meantime&#8230; but of course I didn&#8217;t give up and today I&#8217;m back 😉</p>
<p>In this post I&#8217;d like to show you how do we localize Android apps. Let&#8217;s see!<br />
<span id="more-1803"></span></p>
<h2>What is localization ?</h2>
<p>Generally, <strong>localization </strong>is a <em>process of adapting the product or application to specific markets by adjusting its language and cultural resources accordingly</em>.</p>
<p>People often think that localization is only a process of translating documentation and user interface into multiple languages, but in fact it may concern many other not less important topics, e.g. formats of numeric values or dates, currencies, numbers comparison/sorting methods, symbols, national flags or even country-specific law requirements.</p>
<p>Android supports app&#8217;s resources localization in pretty easy way. We can quite conveniently provide different versions of strings, images and layouts used in our application for different languages/regions. Let&#8217;s take a look at the basics of Android app&#8217;s localization.</p>
<h2>Android localization basics</h2>
<p>In every Android application, localization is based on the language user has set on his/her device. The language can be changed in <strong>Settings -&gt; Language &amp; input</strong>. Changing the language in this place affects both user interface&#8217;s language and region-specific settings (e.g. dates formats).</p>
<p>To retrieve the current <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html" target="_blank" rel="noopener">locale</a> (constant/object representing selected language) in code the following statement can be used:</p>
<pre><pre class="brush: csharp; title: ; notranslate">var currentLang = Resources.Configuration.Locale;</pre>
<p>In case user has Polish language set on his/her phone, <span style="color: #ff9900;">currentLang</span> variable would contain &#8220;pl_PL&#8221; locale symbol. For the full list of locales symbols, see <a href="http://www.oracle.com/technetwork/java/javase/locales-137662.html" target="_blank" rel="noopener">for example this list.</a></p>
<p>Basically, everything that is placed under <em>Resources</em> folder in Android solution can be localized. All of you probably have <em>values</em> folder in <em>Resources</em>, which contains <em>Strings.xml</em> file. We&#8217;ll see more details about this file in a while, but to present the ease of localization to you, it&#8217;s enough to create another folder under <em>Resources</em> called e.g. <em>values-pl</em>, which makes retrieving strings from <em>Strings.xml</em> file located in this folder on devices with language set to Polish. Simple as that. The same can be done with every type of resource. It means we can create totally different layouts of our Activities or use different images (e.g. countries&#8217; flags) depending on user&#8217;s device&#8217;s language.</p>
<h2>Strings localization</h2>
<h4>Strings.xml file</h4>
<p>To-be-localized strings (BTW, I think that we should do it straightaway with all strings we use in our app) should be put in <em>values</em>/<em>Strings.xml</em> file, which has the following structure:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46853585" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-strings-xml" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-xml  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Strings.xml content, created by dsibinski on 06:55PM on April 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Strings.xml">
<tr>
<td id="file-strings-xml-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-strings-xml-LC1" class="blob-code blob-code-inner js-file-line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-strings-xml-LC2" class="blob-code blob-code-inner js-file-line">&lt;resources&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-strings-xml-LC3" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;ApplicationName&quot;&gt;MoneyBack&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-strings-xml-LC4" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titleMenu&quot;&gt;Menu:&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-strings-xml-LC5" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;btnPeople&quot;&gt;People management&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-strings-xml-LC6" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titleName&quot;&gt;Name&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-strings-xml-LC7" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titleLastName&quot;&gt;Last name&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-strings-xml-LC8" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titlePhoneNumber&quot;&gt;Phone number&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-strings-xml-LC9" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;btnSavePerson&quot;&gt;Save person&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-strings-xml-LC10" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;btnPeopleList&quot;&gt;List of people&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-strings-xml-LC11" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;peopleListTitle&quot;&gt;List of people&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-strings-xml-LC12" class="blob-code blob-code-inner js-file-line">&lt;/resources&gt;</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/a0ae912d93e038ddf4b958666413edca/raw/420e073b031ec34f5a0c6b2fe1f47a448054d065/Strings.xml" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/a0ae912d93e038ddf4b958666413edca#file-strings-xml" class="Link--inTextBlock"><br />
          Strings.xml<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>The file is built in accordance with standard XML rules. The <em>name</em> represents <strong>Android resource ID</strong> (cannot contain any spaces or dashes) to which we will refer from code and other places in order to retrieve the <strong>value</strong> of this resource, which is placed between &#8220;&gt;&#8221; and &#8220;&lt;&#8221; characters.</p>
<p>For instance, first resource from above-pasted <em>Strings.xml</em> has <em>name</em> = &#8220;ApplicationName&#8221; and <em>value</em> = &#8220;MoneyBack&#8221;.</p>
<p>As mentioned in the previous paragraph, I also created <em>Strings.xml</em> file in <em>values-pl</em> folder, containing the same resources&#8217; Polish translations. The contents of <em>values-pl/Strings.xml</em> file:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46854312" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-strings-xml" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-xml  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Strings.xml content, created by dsibinski on 07:18PM on April 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Strings.xml">
<tr>
<td id="file-strings-xml-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-strings-xml-LC1" class="blob-code blob-code-inner js-file-line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-strings-xml-LC2" class="blob-code blob-code-inner js-file-line">&lt;resources&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-strings-xml-LC3" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;ApplicationName&quot;&gt;MoneyBack&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-strings-xml-LC4" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titleMenu&quot;&gt;Menu:&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-strings-xml-LC5" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;btnPeople&quot;&gt;Zarządzaj osobami&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-strings-xml-LC6" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titleName&quot;&gt;Imię&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-strings-xml-LC7" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titleLastName&quot;&gt;Nazwisko&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-strings-xml-LC8" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;titlePhoneNumber&quot;&gt;Numer telefonu&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-strings-xml-LC9" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;btnSavePerson&quot;&gt;Zapisz osobę&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-strings-xml-LC10" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;btnPeopleList&quot;&gt;Lista osób&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-strings-xml-LC11" class="blob-code blob-code-inner js-file-line">    &lt;string name=&quot;peopleListTitle&quot;&gt;Lista osób&lt;/string&gt;</td>
</tr>
<tr>
<td id="file-strings-xml-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-strings-xml-LC12" class="blob-code blob-code-inner js-file-line">&lt;/resources&gt;</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1376460c699c37b6c72a5c8d911e2c66/raw/0fad55e5233c5f3704011acbb74cb60c6231e3a2/Strings.xml" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/1376460c699c37b6c72a5c8d911e2c66#file-strings-xml" class="Link--inTextBlock"><br />
          Strings.xml<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<h4>Usage in layout files</h4>
<p>In our Activities&#8217; layout files (AXML) we can retrieve resources&#8217; values by using <em>@string/id</em> syntax. For example, <span style="color: #ff9900;">TextView</span>&#8216;s text can be set in the following way:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46854495" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-main-axml" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-xml  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Main.axml content, created by dsibinski on 07:25PM on April 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Main.axml">
<tr>
<td id="file-main-axml-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-main-axml-LC1" class="blob-code blob-code-inner js-file-line">    &lt;TextView</td>
</tr>
<tr>
<td id="file-main-axml-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-main-axml-LC2" class="blob-code blob-code-inner js-file-line">        android:text=&quot;@string/titleMenu&quot;</td>
</tr>
<tr>
<td id="file-main-axml-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-main-axml-LC3" class="blob-code blob-code-inner js-file-line">        android:id=&quot;@+id/titleMenu&quot; /&gt;</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/862fadb2f8d1ef158961aa9fa7f1f009/raw/5d1b641f8b95fd886ec261b33f9381424e3a3038/Main.axml" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/862fadb2f8d1ef158961aa9fa7f1f009#file-main-axml" class="Link--inTextBlock"><br />
          Main.axml<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>It can be used exactly the same way in the UI designer in Visual Studio.</p>
<h4>Usage directly in code</h4>
<p>In the code we can retrieve values of particular resources using <span style="color: #ff9900;">Resources.GetText</span> method giving it selected resource&#8217;s id as <span style="color: #ff9900;">Resource.String</span> class&#8217;s property:</p>
<pre><pre class="brush: csharp; title: ; notranslate">string titleMenuText = Resources.GetText(Resource.String.titleMenu);</pre>
<p>With all strings translated, I can see UI of <em>MoneyBack</em> translated when my device&#8217;s language is set to Polish:</p>
<p>
<a href='https://www.codejourney.net/android-apps-localization/moneyback_pl/'><img loading="lazy" decoding="async" width="169" height="300" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?fit=169%2C300&amp;ssl=1" class="attachment-medium size-medium" alt="" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?resize=720%2C1280&amp;ssl=1 720w" sizes="auto, (max-width: 169px) 100vw, 169px" data-attachment-id="1927" data-permalink="https://www.codejourney.net/android-apps-localization/moneyback_pl/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_PL" data-image-description="" data-image-caption="&lt;p&gt;MoneyBack &amp;#8211; PL&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PL.png?fit=576%2C1024&amp;ssl=1" /></a>
<a href='https://www.codejourney.net/android-apps-localization/moneyback_en/'><img loading="lazy" decoding="async" width="169" height="300" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?fit=169%2C300&amp;ssl=1" class="attachment-medium size-medium" alt="" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?resize=720%2C1280&amp;ssl=1 720w" sizes="auto, (max-width: 169px) 100vw, 169px" data-attachment-id="1926" data-permalink="https://www.codejourney.net/android-apps-localization/moneyback_en/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_EN" data-image-description="" data-image-caption="&lt;p&gt;MoneyBack &amp;#8211; EN&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_EN.png?fit=576%2C1024&amp;ssl=1" /></a>
</p>
<h4>Quantity strings</h4>
<p>Very interesting concept are so called <strong>quantity strings</strong>. It allows to define differently formatted strings depending on a number of some elements determined at runtime. For instance, on the list of people we could have the following strings displayed depending on the number of people:</p>
<p>&#8220;There is 1 person in your database.&#8221;</p>
<p>&#8220;There are 2 people in your database.&#8221;</p>
<p>To declare such kind of quantity string, we&#8217;d add to <em>Strings.xml</em> the following section:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46854777" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-strings_plurals-xml" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-xml  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Strings_plurals.xml content, created by dsibinski on 07:35PM on April 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Strings_plurals.xml">
<tr>
<td id="file-strings_plurals-xml-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-strings_plurals-xml-LC1" class="blob-code blob-code-inner js-file-line">&lt;<span class="pl-ent">plurals</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">&quot;</span>numberOfPeople<span class="pl-pds">&quot;</span></span>&gt;</td>
</tr>
<tr>
<td id="file-strings_plurals-xml-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-strings_plurals-xml-LC2" class="blob-code blob-code-inner js-file-line">         &lt;<span class="pl-ent">item</span> <span class="pl-e">quantity</span>=<span class="pl-s"><span class="pl-pds">&quot;</span>one<span class="pl-pds">&quot;</span></span>&gt;There is %d person in your database.&lt;/<span class="pl-ent">item</span>&gt;</td>
</tr>
<tr>
<td id="file-strings_plurals-xml-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-strings_plurals-xml-LC3" class="blob-code blob-code-inner js-file-line">         &lt;<span class="pl-ent">item</span> <span class="pl-e">quantity</span>=<span class="pl-s"><span class="pl-pds">&quot;</span>other<span class="pl-pds">&quot;</span></span>&gt;There are %d people in your database..&lt;/<span class="pl-ent">item</span>&gt;</td>
</tr>
<tr>
<td id="file-strings_plurals-xml-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-strings_plurals-xml-LC4" class="blob-code blob-code-inner js-file-line"> &lt;/<span class="pl-ent">plurals</span>&gt;</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/242f23517ee05b52f6ec365dd06e9ef6/raw/88b97726600cff4fc890821351ef1da81f346a72/Strings_plurals.xml" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/242f23517ee05b52f6ec365dd06e9ef6#file-strings_plurals-xml" class="Link--inTextBlock"><br />
          Strings_plurals.xml<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>To illustrate: in order to retrieve and format appropriate string depending on value stored in <span style="color: #ff9900;">numPeople</span> variable, the following code might be used:</p>
<pre><pre class="brush: csharp; title: ; notranslate">var text = Resources.GetQuantityString(Resource.Plurals.numberOfPeople, numPeople, numPeople);</pre>
<p>Second parameter passed is used to determine <strong>which</strong> string (plural) to use, and third parameter is the <strong>actual value</strong> passed to the final string (in the place of <em>%d</em> in that case).</p>
<p>The <em>quantity</em> of each plural can contain one of the following values:</p>
<ul>
<li>zero</li>
<li>one</li>
<li>two</li>
<li>few</li>
<li>many</li>
<li>other</li>
</ul>
<p>More details can be found <a href="https://developer.android.com/guide/topics/resources/string-resource.html#Plurals" target="_blank" rel="noopener">here</a>.</p>
<h4>Application&#8217;s/Activity&#8217;s name</h4>
<p>We can also localize the name of our app, by using string resource in the <span style="color: #ff9900;">ActivityAttribute</span> defined on <span style="color: #ff9900;">MainActivity</span>:</p>
<pre><pre class="brush: csharp; title: ; notranslate">&#x5B;Activity(Label = &quot;@string/ApplicationName&quot;, MainLauncher = true, Icon = &quot;@drawable/icon&quot;)]</pre>
<p>The same can be done for any of our app&#8217;s activities. However, be careful here if you are referencing your main Android project from another one (e.g. from tests project) &#8211; I&#8217;ve experienced really annoying issue with that (more details below).</p>
<h4>Other resources</h4>
<p>As we already said, not only strings can be localized. You can localize any kind of resources placed within <em>Resources</em> folder, for example images or data files.</p>
<h2>The file “obj\Debug\android\bin\packaged_resources” does not exist</h2>
<p>Two weeks ago, when I finally decided to take a break in publishing DSP posts, I wanted to work on <em>MoneyBack</em> a bit, however I encountered very frustrating issue, which I even described in <a href="http://stackoverflow.com/questions/43294345/visual-studio-2017-xamarin-the-file-obj-debug-android-bin-packaged-resource" target="_blank" rel="noopener">this StackOverflow post</a>. I&#8217;ve been fighting with that problem for few days and I still actually don&#8217;t know the real cause of the issue.</p>
<p>Basically, when I used resource string on my <span style="color: #ff9900;">PeopleListActivity</span> in order to translate its title:</p>
<pre><pre class="brush: csharp; title: ; notranslate">&#x5B;Activity(Label = &quot;@string/peopleListTitle&quot;)]</pre>
<p>I couldn&#8217;t build my <strong>MoneyBack.Android.Tests </strong>(yes, different project!) project. I was getting the following build error message:</p>
<p><figure id="attachment_1955" aria-describedby="caption-attachment-1955" style="width: 963px" class="wp-caption alignnone"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1955" data-permalink="https://www.codejourney.net/android-apps-localization/resourcenotfound/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?fit=963%2C163&amp;ssl=1" data-orig-size="963,163" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1492631799&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ResourceNotFound" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?fit=300%2C51&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?fit=963%2C163&amp;ssl=1" class=" size-full wp-image-1955 alignnone" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?resize=963%2C163&#038;ssl=1" alt="ResourceNotFound.JPG" width="963" height="163" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?w=963&amp;ssl=1 963w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?resize=300%2C51&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?resize=768%2C130&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound.jpg?resize=720%2C122&amp;ssl=1 720w" sizes="auto, (max-width: 963px) 100vw, 963px" /><figcaption id="caption-attachment-1955" class="wp-caption-text">Error during building Android tests project</figcaption></figure></p>
<p>I explored all existing forums threads on this topic and couldn&#8217;t resolve this issue. Finally, by setting build output verbosity to <code>Diagnostic</code> in <em>Tools -&gt; Options -&gt; Projects and Solutions -&gt; Build and Run </em>I was able to see the detailed error my build process is giving. It was telling me that <em>@string/peopleListTitle </em>doesn&#8217;t exist (or something similar). So when I changed the <span style="color: #ff9900;">Label</span>&#8216;s value in <span style="color: #ff9900;">ActivityAttribute</span> to use a string directly (not taken as a resource), it worked fine and the build passed.</p>
<p>Today I tried once more to use resource string, obviously getting the same error message. Then I realized that my <em>MoneyBack.Android.Tests</em> project is referencing  <em>MoneyBack</em> project in which I define those somehow missing strings:</p>
<p><figure id="attachment_1965" aria-describedby="caption-attachment-1965" style="width: 266px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1965" data-permalink="https://www.codejourney.net/android-apps-localization/resourcenotfound_test_reference/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound_Test_Reference.jpg?fit=384%2C426&amp;ssl=1" data-orig-size="384,426" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1492631847&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ResourceNotFound_Test_Reference" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound_Test_Reference.jpg?fit=270%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound_Test_Reference.jpg?fit=384%2C426&amp;ssl=1" class=" wp-image-1965 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound_Test_Reference.jpg?resize=266%2C295&#038;ssl=1" alt="ResourceNotFound_Test_Reference.JPG" width="266" height="295" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound_Test_Reference.jpg?w=384&amp;ssl=1 384w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ResourceNotFound_Test_Reference.jpg?resize=270%2C300&amp;ssl=1 270w" sizes="auto, (max-width: 266px) 100vw, 266px" /><figcaption id="caption-attachment-1965" class="wp-caption-text">Tests project referencing the main one</figcaption></figure></p>
<p>so I removed that reference (commenting out my unit tests which use <em>MoneyBack</em>&#8216;s logic) and the build worked fine. Apparently when trying to build tests project, which references the main one, in which my strings are defined, <strong>it somehow needs those strings resources to be present in tests project&#8217;s output directory.</strong> I have no idea why, because I&#8217;m not directly using those strings resources in my tests project.</p>
<p>Then I added the reference back and in <em>MoneyBack.Android.Tests</em> project I just created <em>values</em> folder and copy-pasted <em>Strings.xml</em> file to it from the <em>MoneyBack</em> project:</p>
<p><figure id="attachment_1978" aria-describedby="caption-attachment-1978" style="width: 1166px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1978" data-permalink="https://www.codejourney.net/android-apps-localization/resources_strings_copied/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?fit=1166%2C330&amp;ssl=1" data-orig-size="1166,330" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1492632228&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Resources_Strings_Copied" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?fit=300%2C85&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?fit=1024%2C290&amp;ssl=1" class="aligncenter size-full wp-image-1978" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?resize=1140%2C323&#038;ssl=1" alt="Resources_Strings_Copied.JPG" width="1140" height="323" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?w=1166&amp;ssl=1 1166w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?resize=300%2C85&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?resize=768%2C217&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?resize=1024%2C290&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Resources_Strings_Copied.jpg?resize=720%2C204&amp;ssl=1 720w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /><figcaption id="caption-attachment-1978" class="wp-caption-text">Strings.xml copied into test project</figcaption></figure></p>
<p>and it builds OK!</p>
<p><span style="text-decoration: underline;"><strong>Does any of you have some idea why it may happen?</strong></span> <span style="text-decoration: underline;"><strong>If you have a clue, you can answer here or even <a href="http://stackoverflow.com/questions/43294345/visual-studio-2017-xamarin-the-file-obj-debug-android-bin-packaged-resource" target="_blank" rel="noopener">on SO.</a></p>
<p></strong></span></p>
<p>For me it seems like a bug in the build process. I wanted to share it with you, because I wasted so much time because of this issue and maybe some of you will also find it useful.</p>
<p>BTW, I really recommend using Diagnostic verbosity of the build output for debugging such issues.</p>
<h2>Summary</h2>
<p>We&#8217;ve seen how Android application can be easily localized. I really recommend to put all strings visible for the end user from the beginning in <em>Strings.xml</em> file. Thanks to that, in case our application needs to be <strong>localized</strong>, we can even hire/ask some foreign languages&#8217; interpreters to create country-specific <em>values</em> folder and translate strings resources conveniently. This is even very common in mobile apps communities, that people who are non-technical can contribute to the project by translating the application into their own language.</p>
<p>I hope I won&#8217;t meet any other issues like the one I described today on my further DSP way 🙂 It would allow me to write more stuff here and hopefully implement some usable app finally! Keep your fingers crossed 🙂</p>
<p>PS: If I already mentioned taking breaks in DSP competition, I will also take one more during the first week of May (1-5.05.2017). In case anyone cares 😉</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.codejourney.net/android-apps-localization/">Android Apps Localization</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/android-apps-localization/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1803</post-id>	</item>
		<item>
		<title>Android Layout Types</title>
		<link>https://www.codejourney.net/android-layout-types/</link>
					<comments>https://www.codejourney.net/android-layout-types/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 02 Apr 2017 06:55:49 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=1695</guid>

					<description><![CDATA[<p>If you&#8217;re just an Android user, you may not even know that each screen in your application has controls composed within different Layouts. Let&#8217;s see what are the main Layout Types in designing Android app. What is a Layout ? Layout defines a visual structure of an Activity (or app widget). It may be considered as&#8230;</p>
<p>The post <a href="https://www.codejourney.net/android-layout-types/">Android Layout Types</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;re just an Android user, you may not even know that each screen in your application has controls composed within different <em>Layouts</em>. Let&#8217;s see what are the main Layout Types in designing Android app.<br />
<span id="more-1695"></span></p>
<h2>What is a Layout ?</h2>
<p><strong>Layout defines a visual structure</strong> of an Activity (or <a href="https://developer.android.com/guide/topics/appwidgets/index.html" target="_blank" rel="noopener">app widget</a>). It may be considered as a set of rules according to which controls (buttons, text fields, input fields etc.) are placed on the <em>View</em>.</p>
<h2>Layouts structure</h2>
<p>Basically, user interface in Android apps is built using <em>Layouts</em>. Each <em>Layout</em> is a subclass of <span style="color: #ff9900;">ViewGroup</span> class, which derives from <span style="color: #ff9900;">View</span> class, which is the basic UI building block. <span style="color: #ff9900;">View</span> is the base class for buttons, text fields etc., more precisely: for <a href="https://developer.xamarin.com/api/namespace/Android.Widget/" target="_blank" rel="noopener">widgets</a> (don&#8217;t confuse it with app widgets you place on your Android screen <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ).</p>
<p>The following diagram presents this hierarchy based on <em><span style="color: #ff9900;">RelativeLayout</span></em>:</p>
<p><figure id="attachment_1717" aria-describedby="caption-attachment-1717" style="width: 615px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1717" data-permalink="https://www.codejourney.net/android-layout-types/android_view_hierarchy_diagram/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Android_view_hierarchy_diagram.png?fit=615%2C272&amp;ssl=1" data-orig-size="615,272" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Android_view_hierarchy_diagram" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Android_view_hierarchy_diagram.png?fit=300%2C133&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Android_view_hierarchy_diagram.png?fit=615%2C272&amp;ssl=1" class="aligncenter size-full wp-image-1717" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Android_view_hierarchy_diagram.png?resize=615%2C272&#038;ssl=1" alt="Android_view_hierarchy_diagram.png" width="615" height="272" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Android_view_hierarchy_diagram.png?w=615&amp;ssl=1 615w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Android_view_hierarchy_diagram.png?resize=300%2C133&amp;ssl=1 300w" sizes="auto, (max-width: 615px) 100vw, 615px" /><figcaption id="caption-attachment-1717" class="wp-caption-text">RelativeLayout hierarchy, source: <a href="http://www.techotopia.com/index.php/Understanding_Android_Views,_View_Groups_and_Layouts" target="_blank" rel="noopener">techotopia.com</a></figcaption></figure></p>
<p>Let&#8217;s now see what are the most important Layout Types. Below each screenshot used to present a particular Layout Type you can find its <span style="text-decoration: underline;">source</span>, which leads to a tutorial or more detailed explanation on how to work with it.</p>
<h2>Linear Layout</h2>
<p><em>LinearLayout</em> is the most basic type of <em>Layout</em>. When Android app is created in Visual Studio 2017, its <span style="color: #ff9900;">MainActivity</span> has by default <em>LinearLayout</em> set:</p>
<p><figure id="attachment_1725" aria-describedby="caption-attachment-1725" style="width: 569px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1725" data-permalink="https://www.codejourney.net/android-layout-types/linear_moneyback/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?fit=847%2C327&amp;ssl=1" data-orig-size="847,327" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Dawid Sibi\u0144ski&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1491120503&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="Linear_MoneyBack" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?fit=300%2C116&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?fit=847%2C327&amp;ssl=1" class="wp-image-1725" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?resize=569%2C220&#038;ssl=1" alt="Linear_MoneyBack" width="569" height="220" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?w=847&amp;ssl=1 847w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?resize=300%2C116&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?resize=768%2C297&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Linear_MoneyBack.jpg?resize=720%2C278&amp;ssl=1 720w" sizes="auto, (max-width: 569px) 100vw, 569px" /><figcaption id="caption-attachment-1725" class="wp-caption-text">LinearLayout set on MoneyBack&#8217;s MainActivity</figcaption></figure></p>
<p>This type of <em>Layout</em> enforces you to put your controls in a linear direction, either horizontally or vertically:</p>
<p><figure id="attachment_1730" aria-describedby="caption-attachment-1730" style="width: 351px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1730" data-permalink="https://www.codejourney.net/android-layout-types/linearlayout/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?fit=788%2C517&amp;ssl=1" data-orig-size="788,517" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="LinearLayout" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?fit=300%2C197&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?fit=788%2C517&amp;ssl=1" class=" size-full wp-image-1730 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?resize=351%2C230&#038;ssl=1" alt="LinearLayout.png" width="351" height="230" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?w=788&amp;ssl=1 788w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?resize=300%2C197&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?resize=768%2C504&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/LinearLayout.png?resize=720%2C472&amp;ssl=1 720w" sizes="auto, (max-width: 351px) 100vw, 351px" /><figcaption id="caption-attachment-1730" class="wp-caption-text">LinearLayout, <a href="http://android4beginners.com/2013/07/lesson-2-1-how-to-build-android-app-with-simple-but-powerful-linearlayout-plus-layout-orientation-as-well-as-size-and-weight-of-elements/" target="_blank" rel="noopener">source</a></figcaption></figure></p>
<h2>Relative Layout</h2>
<p><em>RelativeLayout</em> enforces to display elements in relations to each other. You can specify that, for instance, one UI element can be said to be placed on the left of another element, or on the bottom of another etc. Each UI element can also be positioned according to the layout&#8217;s borders (e.g. aligned to the right):</p>
<p><figure id="attachment_1739" aria-describedby="caption-attachment-1739" style="width: 521px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1739" data-permalink="https://www.codejourney.net/android-layout-types/relativelayout_android/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?fit=801%2C501&amp;ssl=1" data-orig-size="801,501" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RelativeLayout_Android" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?fit=300%2C188&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?fit=801%2C501&amp;ssl=1" class="aligncenter wp-image-1739" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?resize=521%2C326&#038;ssl=1" alt="RelativeLayout_Android.png" width="521" height="326" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?w=801&amp;ssl=1 801w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?resize=300%2C188&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?resize=768%2C480&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/RelativeLayout_Android.png?resize=720%2C450&amp;ssl=1 720w" sizes="auto, (max-width: 521px) 100vw, 521px" /><figcaption id="caption-attachment-1739" class="wp-caption-text">RelativeLayout, <a href="https://www.skynils.com/relative-layout-in-android/" target="_blank" rel="noopener">source</a></figcaption></figure></p>
<p><em>RelativeLayout</em> is very powerful. Consider that for building mobile apps&#8217; interfaces these can be run on multiple devices with different screens&#8217; resolutions. <em>RelativeLayout</em> allows (if properly built, of course) to adjust your set of controls easily to almost every type of screen. It&#8217;s quite specific and I personally found it difficult to understand and use initially, but it seems to be worth it.</p>
<h2>Table Layout</h2>
<p>As its name suggests, <em>TableLayout</em> allows to group elements into rows and columns:</p>
<p><figure id="attachment_1746" aria-describedby="caption-attachment-1746" style="width: 248px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1746" data-permalink="https://www.codejourney.net/android-layout-types/tablelayout_android/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/TableLayout_Android.png?fit=287%2C400&amp;ssl=1" data-orig-size="287,400" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TableLayout_Android" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/TableLayout_Android.png?fit=215%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/TableLayout_Android.png?fit=287%2C400&amp;ssl=1" class="aligncenter wp-image-1746" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/TableLayout_Android.png?resize=248%2C346&#038;ssl=1" alt="TableLayout_Android.jpg" width="248" height="346" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/TableLayout_Android.png?w=287&amp;ssl=1 287w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/TableLayout_Android.png?resize=215%2C300&amp;ssl=1 215w" sizes="auto, (max-width: 248px) 100vw, 248px" /><figcaption id="caption-attachment-1746" class="wp-caption-text">TableLayout, <a href="https://www.tutorialspoint.com/android/android_table_layout.htm" target="_blank" rel="noopener">source</a></figcaption></figure></p>
<p>May be useful when displaying some statistics or reports.</p>
<h2>Grid View</h2>
<p><em>GridView</em> displays items in two-dimensional grid. The list can be easily scrolled. This type of <em>Layout</em> is often used on screens displaying photos or similar sets of &#8220;blocks&#8221; to click:</p>
<p><figure id="attachment_1753" aria-describedby="caption-attachment-1753" style="width: 436px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1753" data-permalink="https://www.codejourney.net/android-layout-types/gridview_android/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/GridView_Android.png?fit=580%2C491&amp;ssl=1" data-orig-size="580,491" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="GridView_Android" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/GridView_Android.png?fit=300%2C254&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/GridView_Android.png?fit=580%2C491&amp;ssl=1" class="aligncenter wp-image-1753" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/GridView_Android.png?resize=436%2C369&#038;ssl=1" alt="GridView_Android.png" width="436" height="369" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/GridView_Android.png?w=580&amp;ssl=1 580w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/GridView_Android.png?resize=300%2C254&amp;ssl=1 300w" sizes="auto, (max-width: 436px) 100vw, 436px" /><figcaption id="caption-attachment-1753" class="wp-caption-text">GridView, <a href="http://www.androidhive.info/2012/02/android-gridview-layout-tutorial/" target="_blank" rel="noopener">source</a></figcaption></figure></p>
<h2>Tab Layout</h2>
<p><a href="https://developer.xamarin.com/guides/android/user_interface/tab_layout/" target="_blank" rel="noopener">Tabbed layouts</a> allow to introduce tabs in our Android application. Then, a single Activity may contain several tabs and user can easily switch between them. On each tab you can use different type of Layout.</p>
<p>Consider that tabs design has changed between Android 2.X and 4.X:</p>
<p><figure id="attachment_1764" aria-describedby="caption-attachment-1764" style="width: 474px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1764" data-permalink="https://www.codejourney.net/android-layout-types/tabs_android/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Tabs_Android.png?fit=550%2C194&amp;ssl=1" data-orig-size="550,194" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Tabs_Android" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Tabs_Android.png?fit=300%2C106&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Tabs_Android.png?fit=550%2C194&amp;ssl=1" class=" wp-image-1764 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Tabs_Android.png?resize=474%2C167&#038;ssl=1" alt="Tabs_Android.png" width="474" height="167" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Tabs_Android.png?w=550&amp;ssl=1 550w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/Tabs_Android.png?resize=300%2C106&amp;ssl=1 300w" sizes="auto, (max-width: 474px) 100vw, 474px" /><figcaption id="caption-attachment-1764" class="wp-caption-text">Tabs, <a href="https://developer.xamarin.com/guides/android/user_interface/tab_layout/" target="_blank" rel="noopener">source</a></figcaption></figure></p>
<h2>List View</h2>
<p><em>ListView</em> allows to display a list of items. It may be used in multiple places, from short lists of menu options to long list of emails or news feed. It allows to easily and quickly present a list of items:</p>
<p><figure id="attachment_1778" aria-describedby="caption-attachment-1778" style="width: 267px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1778" data-permalink="https://www.codejourney.net/android-layout-types/listview_android/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ListView_Android.png?fit=320%2C480&amp;ssl=1" data-orig-size="320,480" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ListView_Android" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ListView_Android.png?fit=200%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ListView_Android.png?fit=320%2C480&amp;ssl=1" class=" size-full wp-image-1778 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ListView_Android.png?resize=267%2C401&#038;ssl=1" alt="ListView_Android.png" width="267" height="401" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ListView_Android.png?w=320&amp;ssl=1 320w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/ListView_Android.png?resize=200%2C300&amp;ssl=1 200w" sizes="auto, (max-width: 267px) 100vw, 267px" /><figcaption id="caption-attachment-1778" class="wp-caption-text">ListView, <a href="http://windrealm.org/tutorials/android/android-listview.php" target="_blank" rel="noopener">source</a></figcaption></figure></p>
<p>I used it in <em>MoneyBack</em> for displaying a very simple list of people from the database. You can check how it&#8217;s done in <a href="https://gist.github.com/dsibinski/b6dcbf1dc0956b584188282c2cb832a2" target="_blank" rel="noopener">this public Gist</a> (there is even no AXML layout file for it, it&#8217;s just an Activity class).</p>
<p>However, Android and Xamarin teams recommend to use <em>RecyclerView</em> for new apps development, which is said to be more advanced and flexible version of<em> ListView</em>. I just noticed it seems to be a bit more complex to set up. You can check more details <a href="https://developer.xamarin.com/guides/android/user_interface/recyclerview/" target="_blank" rel="noopener">here.</a></p>
<h2>Summary</h2>
<p>We&#8217;ve explored some basic Layout Types that can be used for grouping UI elements in Android application. Remember that all types of layouts we&#8217;ve gone through may be nested into each other (as we&#8217;ve seen for tabs &#8211; you can use tabbed layout and then in each tab &#8220;nest&#8221; any other type of layout).</p>
<p>It may seem to be a bit strict, that we shouldn&#8217;t just put the controls whatever we&#8217;d like to (as we are used to do in <em>WinForms</em>, for example <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ), but mobile development requires such restrictions.</p>
<p>Especially building for Android &#8211; as for September 2015, there were <strong>1.5 billion</strong> registered devices running Android system. This implies thousands of different screens resolutions, which must be handled by the UI of our apps.</p>
<p><span style="text-decoration: underline;"><strong>What types of Layouts do you use the most in your Android apps? Do you have any best practices using them ? Share your knowledge! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></span></p>
<p>The post <a href="https://www.codejourney.net/android-layout-types/">Android Layout Types</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/android-layout-types/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1695</post-id>	</item>
		<item>
		<title>Xamarin &#8211; Android Intents</title>
		<link>https://www.codejourney.net/xamarin-android-intents/</link>
					<comments>https://www.codejourney.net/xamarin-android-intents/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 01 Apr 2017 10:19:59 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=1499</guid>

					<description><![CDATA[<p>We&#8217;ve already seen what are Activities, the most basic pieces of every Android app and today&#8217;s topic is associated with it. We&#8217;re going to see how to communicate between Activities (or Application Blocks) using Intents. Android Application Blocks Android apps are composed of Application Blocks, which are special kind of Android classes consisting several elements bundled together,&#8230;</p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-intents/">Xamarin &#8211; Android Intents</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>We&#8217;ve already seen what are <a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener">Activities</a>, the most basic pieces of every Android app and today&#8217;s topic is associated with it. We&#8217;re going to see how to communicate between Activities (or <em>Application Blocks</em>) using <em>Intents</em>.<br />
<span id="more-1499"></span></p>
<h2>Android Application Blocks</h2>
<p>Android apps are composed of <em>Application Blocks</em>, which are special kind of Android classes consisting several elements bundled together, including:</p>
<ul>
<li><a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener">Activities</a></li>
<li><a href="https://developer.xamarin.com/guides/android/application_fundamentals/services/" target="_blank" rel="noopener">Services</a></li>
<li>Resources (images, themes, classes)</li>
</ul>
<p>Everything that comes in such <em>package</em> is coordinated by <em>AndroidManifest.XML</em> file. Especially, in this XML file (or by using various attributes on Activity class) it&#8217;s possible to <em>register</em> our <em>Application Block</em> to be &#8220;callable&#8221; by the others.</p>
<p>We&#8217;ll see more details in a while, but generally your app block is &#8220;callable&#8221; when it can be used by the other apps &#8211; probably you&#8217;ve already seen Application Chooser screen on your Android phone, e.g. when you wanted to open downloaded movie and the system asked you which video player you want to use. The same can be done with your own app &#8211; if you&#8217;re developing a dialer app, you can register it to be callable for <em><a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_DIAL" target="_blank" rel="noopener">ACTION_DIAL</a> </em>Activity Action. Then, as soon as any other app uses <em>Intent</em> to make a phone call (which we&#8217;ll see in this post), Application Chooser appears and your app will be one of the possible ones to use for making this phone call.</p>
<h2>What is an Intent ?</h2>
<p>Android system is designed to be <em>loosely-coupled</em>. Moreover, there is a <em>principle of least privilege</em> introduced in system&#8217;s architecture. It means that each app has access only to <em>Blocks</em> which it requires to work. Different <em>Blocks</em> don&#8217;t know much about each other (even if defined within the same application). Here&#8217;s where an<em> </em><em>Intent</em> comes into play. <em><strong>Application Blocks</strong></em><strong> use </strong><strong><em>Intents</em></strong><strong> to asynchronously communicate with each other.</p>
<p></strong></p>
<p>In general, you can think of an <em>Intent </em>literally &#8211; <strong>it&#8217;s the <em>intent</em> (or a <em>will</em>) to do something</strong>. By sending <em>Intents</em> between different components, we can coordinate complex actions such as launching email app to send a message, using Location for obtaining user&#8217;s coordinates or navigating between application&#8217;s screens.</p>
<p>For me, we can think of <em>Intents</em> and their usage from two perspectives:</p>
<ol>
<li><strong><em>Intent</em> as an</strong> <span style="text-decoration: underline;"><strong>intent</strong></span><strong> </strong>&#8211; a will to do something. In this case, you use <em>Intent</em> to execute <em>some</em> action. When creating a new <em>Intent</em> you need to tell it <em>what</em> you want to do and give it necessary <em>parameters</em> for such operation (e.g. for <em>send email</em> action, you need to provide <em>email address </em>parameter)</li>
<li><strong><em>Intent</em> as a</strong> <span style="text-decoration: underline;"><strong>message </strong></span>&#8211; bidirectional information having <em>sender</em>, <em>recipient </em>and potentially some <em>content</em>. This can be for instance navigating to a new screen (Activity), where sender is the original Activity, recipient is the destination Activity to be opened and the content may consist some parameters to pass between two screens.</li>
</ol>
<p>We&#8217;ll now see those two approaches in details.</p>
<h2>Intent as an intent</h2>
<p>In order to trigger another (external) action, e.g. camera recording or email sending, we can create an <em>Intent</em> and start a new Activity. Let&#8217;s see it by the example I implemented in <em>MoneyBack</em> &#8211; I added an additional <em>ListActivity</em> (<span style="color: #ff9900;">PeopleListActivity</span> class) which is the list of people added to app&#8217;s database. When a person on the list is clicked, I create an <em>Intent</em> in order to call his/her phone number as the following code presents:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46270777" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-peoplelistactivity_clicking-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="PeopleListActivity_clicking.cs content, created by dsibinski on 09:03AM on April 01, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="PeopleListActivity_clicking.cs">
<tr>
<td id="file-peoplelistactivity_clicking-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-peoplelistactivity_clicking-cs-LC1" class="blob-code blob-code-inner js-file-line">  private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-peoplelistactivity_clicking-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-peoplelistactivity_clicking-cs-LC3" class="blob-code blob-code-inner js-file-line">      var person = _peopleList[e.Position];</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-peoplelistactivity_clicking-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-peoplelistactivity_clicking-cs-LC5" class="blob-code blob-code-inner js-file-line">      var uri = Android.Net.Uri.Parse(&quot;tel:&quot; + person.PhoneNumber);</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-peoplelistactivity_clicking-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-peoplelistactivity_clicking-cs-LC7" class="blob-code blob-code-inner js-file-line">      var intent = new Intent(Intent.ActionDial, uri);</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-peoplelistactivity_clicking-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-peoplelistactivity_clicking-cs-LC9" class="blob-code blob-code-inner js-file-line">      StartActivity(intent);</td>
</tr>
<tr>
<td id="file-peoplelistactivity_clicking-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-peoplelistactivity_clicking-cs-LC10" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/c5e4309e60888a66284df0dede98d877/raw/b0078b3ff7fe9656c97da6127f3e4e8310e552e7/PeopleListActivity_clicking.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/c5e4309e60888a66284df0dede98d877#file-peoplelistactivity_clicking-cs" class="Link--inTextBlock"><br />
          PeopleListActivity_clicking.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>What those 4 lines of code do, is when tapping an entry from the list:</p>
<p><figure id="attachment_1589" aria-describedby="caption-attachment-1589" style="width: 240px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1589" data-permalink="https://www.codejourney.net/xamarin-android-intents/monayback_listofpeople/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MonayBack_ListOfPeople" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-1589 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?resize=240%2C400&#038;ssl=1" alt="MonayBack_ListOfPeople" width="240" height="400" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MonayBack_ListOfPeople.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 240px) 100vw, 240px" /><figcaption id="caption-attachment-1589" class="wp-caption-text">MoneyBack &#8211; people list Activity</figcaption></figure></p>
<p>it opens the phone dialer app with selected person&#8217;s phone number to call:</p>
<p><figure id="attachment_1594" aria-describedby="caption-attachment-1594" style="width: 242px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1594" data-permalink="https://www.codejourney.net/xamarin-android-intents/moneyback_phonedialercall/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_phoneDialerCall" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-1594 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?resize=242%2C403&#038;ssl=1" alt="MoneyBack_phoneDialerCall.png" width="242" height="403" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_phoneDialerCall.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 242px) 100vw, 242px" /><figcaption id="caption-attachment-1594" class="wp-caption-text">Phone Dialer opened</figcaption></figure></p>
<p><span style="font-size: 10pt;">NOTE: If I had more than one dialer app installed (if the other dialer app has itself registered as receiver for <em>ACTION_DIAL, </em>of course) Android would ask me to choose which app I want to use.</p>
<p></span></p>
<p>How did that happen? First actually interesting line of code is the following one:</p>
<pre><pre class="brush: csharp; title: ; notranslate">var intent = new Intent(Intent.ActionDial, uri);</pre>
<p>It creates a new <em>Intent</em>, giving to it &#8211; as we said in the previous paragraph &#8211; two things:</p>
<ul>
<li><em>what</em> we want to do &#8211; it this case, we set <em>action </em>to <span style="color: #ff9900;">Intent.ActionDial</span>, which corresponds to <a href="https://developer.android.com/reference/android/content/Intent.html#ACTION_DIAL" target="_blank" rel="noopener">ACTION_DIAL</a> Activity Action</li>
<li>operation&#8217;s <em>parameters</em> &#8211; in our case there is just one parameter, which is the phone number in <a href="https://developer.xamarin.com/api/type/Android.Net.Uri/" target="_blank" rel="noopener">URI</a> format</li>
</ul>
<p>For each type of Activity Action you want to trigger, you can find what parameters it needs in <a href="https://developer.android.com/reference/android/content/Intent.html" target="_blank" rel="noopener">official Android Documentation</a>.</p>
<p>In the end, we just need to finally start a new Activity with the <em>Intent</em> we just created:</p>
<pre><pre class="brush: csharp; title: ; notranslate">StartActivity(intent);</pre>
<p>and we&#8217;re all done.</p>
<h2>Intent as a message</h2>
<p>Now, let&#8217;s think about our app as a set of Activities, which are <em>loosly-coopled</em>. We have <span style="color: #ff9900;">MainActivity</span> class, which represents the main screen of our app. We&#8217;ve also built another Activity, which we want to open from the main one. In that case, we already see everything which fits into intent-as-a-message template &#8211; two Activities want to &#8220;talk&#8221; with each other.</p>
<p>In <em>MoneyBack</em> I changed the <span style="color: #ff9900;">MainActivity</span> to look as follows:</p>
<p><figure id="attachment_1624" aria-describedby="caption-attachment-1624" style="width: 223px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1624" data-permalink="https://www.codejourney.net/xamarin-android-intents/moneyback_mainactivity/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_MainActivity" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-1624 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?resize=223%2C371&#038;ssl=1" alt="MoneyBack_MainActivity.png" width="223" height="371" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_MainActivity.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 223px) 100vw, 223px" /><figcaption id="caption-attachment-1624" class="wp-caption-text">MoneyBack &#8211; <em>MainActivity</em></figcaption></figure></p>
<p>When clicking on &#8220;People Management&#8221; button, I&#8217;d like another Activity (represented by <span style="color: #ff9900;">PeopleActivity</span> class) to open.</p>
<p>In order to achieve that, <em>MoneyBack</em> executes the following code when clicking on the button:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46271232" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_peoplemanagementclick-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_peopleManagementClick.cs content, created by dsibinski on 09:28AM on April 01, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_peopleManagementClick.cs">
<tr>
<td id="file-mainactivity_peoplemanagementclick-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_peoplemanagementclick-cs-LC1" class="blob-code blob-code-inner js-file-line">  private void _btnPeople_Click(object sender, EventArgs e)</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_peoplemanagementclick-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_peoplemanagementclick-cs-LC3" class="blob-code blob-code-inner js-file-line">      var intent = new Intent(this, typeof(PeopleActivity));</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_peoplemanagementclick-cs-LC4" class="blob-code blob-code-inner js-file-line">      StartActivity(intent);</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_peoplemanagementclick-cs-LC5" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/87ace30937c460184ccb36d59919727c/raw/ce3100662ce3e8a8746a713fed52ca9b7940fc46/MainActivity_peopleManagementClick.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/87ace30937c460184ccb36d59919727c#file-mainactivity_peoplemanagementclick-cs" class="Link--inTextBlock"><br />
          MainActivity_peopleManagementClick.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>What you can see here, is that we create a new <em>Intent</em> that takes two parameters:</p>
<ul>
<li><em>Context </em>&#8211; being the class storing information about current application&#8217;s/Activity&#8217;s state, from the place where the <em>Intent</em> is created; in our case, we set it to <span style="color: #ff9900;">this</span>, which is the calling Activity class reference. Context is our message&#8217;s <strong>sender</strong></li>
<li><em>Type</em> &#8211; this is our message&#8217;s <strong>recipient</strong>; in our case it&#8217;s the <span style="color: #ff9900;">Type</span> of destination Activity we want to start (<span style="color: #ff9900;">PeopleActivity</span>)</li>
</ul>
<p><span style="font-size: 10pt;">NOTE: Notice that we have no <em>content</em> provided in that case.</p>
<p></span></p>
<p>Then we just start the Activity as in the previous example and another screen appears:</p>
<p><figure id="attachment_1645" aria-describedby="caption-attachment-1645" style="width: 217px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1645" data-permalink="https://www.codejourney.net/xamarin-android-intents/moneyback_peopleactivity/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_PeopleActivity" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-1645 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?resize=217%2C362&#038;ssl=1" alt="MoneyBack_PeopleActivity.png" width="217" height="362" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_PeopleActivity.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 217px) 100vw, 217px" /><figcaption id="caption-attachment-1645" class="wp-caption-text">MoneyBack &#8211; PeopleActivity</figcaption></figure></p>
<p>If the back button is now pressed, it goes back to previous (calling) Activity. That&#8217;s how the Activities stack is built, by the way <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h4>Passing additional content using Intent as a message</h4>
<p>I mentioned we can also pass some additional data (message&#8217;s <strong>content</strong>) within an <em>Intent</em>. In the above example we didn&#8217;t do it, because there is no sense to pass anything from <span style="color: #ff9900;">MainActivity</span> to <span style="color: #ff9900;">PeopleActivity</span> for now. However, if we&#8217;d like to do that, we can add a simple modification to button&#8217;s pressing code in <span style="color: #ff9900;">MainActivity</span>:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46271394" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_peoplemanagementclick_msg-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_peopleManagementClick_msg.cs content, created by dsibinski on 09:39AM on April 01, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_peopleManagementClick_msg.cs">
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC1" class="blob-code blob-code-inner js-file-line">  private void _btnPeople_Click(object sender, EventArgs e)</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC3" class="blob-code blob-code-inner js-file-line">      var intent = new Intent(this, typeof(PeopleActivity));</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC5" class="blob-code blob-code-inner js-file-line">      var msgContent = &quot;Hello! This is a secret sent from MainActivity! Don&#39;t tell anyone!&quot;;</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC6" class="blob-code blob-code-inner js-file-line">      intent.PutExtra(&quot;secret_message&quot;, msgContent);</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC7" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC8" class="blob-code blob-code-inner js-file-line">      StartActivity(intent);</td>
</tr>
<tr>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-mainactivity_peoplemanagementclick_msg-cs-LC9" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/c41976d7f7873ab870f1a41fc0b9540c/raw/e3cbbe0505a984c152a7646452e374cd15ccb451/MainActivity_peopleManagementClick_msg.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/c41976d7f7873ab870f1a41fc0b9540c#file-mainactivity_peoplemanagementclick_msg-cs" class="Link--inTextBlock"><br />
          MainActivity_peopleManagementClick_msg.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>As you see, I used <span style="color: #ff9900;">PutExtra</span> method of the <span style="color: #ff9900;">Intent </span>class to insert <span style="color: #ff9900;"><em>msgContent</em></span> into Intent&#8217;s simple key-value Bundle Dictionary called <em>Extras, </em>using &#8220;secret_message&#8221; string as a key. Then, in the destination Activity&#8217;s <span style="color: #ff9900;">OnCreate</span> method we can retrieve such value back using <span style="color: #ff9900;">Intent.Extras.GetString</span> (for <span style="color: #ff9900;">String</span> data type) method:</p>
<p><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1670" data-permalink="https://www.codejourney.net/xamarin-android-intents/moneyback_intentextrasretrieve/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?fit=975%2C504&amp;ssl=1" data-orig-size="975,504" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_IntentExtrasRetrieve" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?fit=300%2C155&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?fit=975%2C504&amp;ssl=1" class=" wp-image-1670 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?resize=584%2C302&#038;ssl=1" alt="MoneyBack_IntentExtrasRetrieve.PNG" width="584" height="302" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?w=975&amp;ssl=1 975w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?resize=300%2C155&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?resize=768%2C397&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/04/MoneyBack_IntentExtrasRetrieve.png?resize=720%2C372&amp;ssl=1 720w" sizes="auto, (max-width: 584px) 100vw, 584px" /></p>
<p>This kind of data-passing between Activities using <span style="color: #ff9900;">Intent.Extras</span> should be used only for simple, mostly key-value data transferring. There are other methods for passing/storing more complex data in an app or between different applications.</p>
<h2>Summary</h2>
<p>Today we&#8217;ve seen what is an <em>Intent</em>, how to use it to trigger external actions such as calling a phone number, sending email etc., but also how to use it to handle navigation between Activities. We&#8217;ve also passed key-value data between two Activities using <span style="color: #ff9900;">Intent.Extras</span>.</p>
<p><em>Intent</em>, as well as <a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener">Activity</a>, is one of the fundamental concepts of Android. It&#8217;s essential to know how <em>Intents</em> work, how they relate to <em>Activities</em>, <em>Services</em> (which we&#8217;ll also cover one day) and <em>Application Blocks.  </em>I hope you&#8217;ll find it useful <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-intents/">Xamarin &#8211; Android Intents</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/xamarin-android-intents/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1499</post-id>	</item>
		<item>
		<title>Unit Testing Xamarin application</title>
		<link>https://www.codejourney.net/unit-testing-xamarin-application/</link>
					<comments>https://www.codejourney.net/unit-testing-xamarin-application/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 25 Mar 2017 23:07:19 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=1166</guid>

					<description><![CDATA[<p>Today we&#8217;ll see how to add unit tests to Xamarin Android application, testing both platform-independent logic and Android-specific features. Issue with unit tests in Visual Studio 2017 When I started to create my data access methods in MoneyBack, I really wanted to start writing even some basic unit tests of that logic. My first trial was to&#8230;</p>
<p>The post <a href="https://www.codejourney.net/unit-testing-xamarin-application/">Unit Testing Xamarin application</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Today we&#8217;ll see how to add unit tests to Xamarin Android application, testing both platform-independent logic and Android-specific features.<br />
<span id="more-1166"></span></p>
<h2>Issue with unit tests in Visual Studio 2017</h2>
<p>When I started to create my data access methods in <em>MoneyBack</em>, I really wanted to start writing even some basic unit tests of that logic.</p>
<p>My first trial was to add a new project to my solution which contains unit tests. So I checked what kind of projects templates I have available and I I found <strong>Unit Test App (Android) </strong>project template and added it to my solution. Generated project contained <span style="color: #ff6600;"><em>TestsSample</em> </span>class with some unit-looking tests methods, but I had no idea how to execute them. With ReSharper installed, I didn&#8217;t have any &#8220;Run Tests&#8221; option on this project. I read somewhere on the web that this project type is used to execute tests on the device, but I couldn&#8217;t figure out how to do it. I gave up.</p>
<p>Then I found another project template &#8211; <strong>Class Library (Android) with nUnit</strong>. Sounds better, <em>nUnit</em> in the name suggests unit tests, so I added this project to my solution. This time when right-clicking the project I had &#8220;Run Tests&#8221; option, but when clicking on it I got the following exception coming from ReSharper:</p>
<p><figure id="attachment_1200" aria-describedby="caption-attachment-1200" style="width: 1030px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1200" data-permalink="https://www.codejourney.net/unit-testing-xamarin-application/resharper_exc/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?fit=1030%2C829&amp;ssl=1" data-orig-size="1030,829" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ReSharper_Exc" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?fit=300%2C241&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?fit=1024%2C824&amp;ssl=1" class="wp-image-1200 size-full" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?resize=1030%2C829&#038;ssl=1" alt="ReSharper_Exc" width="1030" height="829" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?w=1030&amp;ssl=1 1030w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?resize=300%2C241&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?resize=768%2C618&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?resize=1024%2C824&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/ReSharper_Exc.png?resize=720%2C579&amp;ssl=1 720w" sizes="auto, (max-width: 1030px) 100vw, 1030px" /><figcaption id="caption-attachment-1200" class="wp-caption-text">ReSharper error when executing unit tests</figcaption></figure></p>
<p>&#8220;Hmm&#8230; Visual Studio 2017&#8221;, I thought. &#8220;Some bugs for sure&#8221;. And I&#8230;</p>
<p>&#8230; didn&#8217;t give up this time and with some help of folks from StackOverflow I figured out how unit tests should be done in Xamarin app. Let&#8217;s see that in the next chapters.</p>
<h2>Levels of testing Xamarin application</h2>
<p>There are basically three &#8220;levels&#8221; of testing Xamarin apps:</p>
<ol>
<li><strong>Classic unit tests of pure .NET/Mono</strong>
<ul>
<li>standard, good old unit tests of logic independent from targeting platform (Xamarin.Android/iOS/Windows Phone)</li>
<li>unit-testing frameworks can be used (nUnit / xUnit)</li>
</ul>
</li>
<li><strong>Platform-specific tests</strong>
<ul>
<li>unit tests of functionalities specific to targeting platform (e.g. Bluetooth, Location, GPS, SMS etc.)</li>
<li>specific for each platform</li>
<li>don&#8217;t contain GUI tests</li>
<li>executed on the emulator/device</li>
</ul>
</li>
<li><strong>UI tests</strong>
<ul>
<li>tests of UI elements of the app and how those react for input (touch) events</li>
<li>executed by cloud/testing lab services (local or remote)</li>
</ul>
</li>
</ol>
<p>We&#8217;ll dive into the first two, UI tests is more complex topic, which requires setting up tests lab or using cloud testing services. For small projects, in the beginning it&#8217;s not necessary.</p>
<h2>Classic platform-independent unit tests</h2>
<p>In order to simply use ReSharper for executing unit tests of logic, which is independent from Android/iOS/Windows Phone, there is a need to add a new project using template <strong>Unit Test Project (.NET Framework) </strong>to our Xamarin solution.</p>
<p>To such project, you can add your favourite unit-testing framework (such as <em>nUnit</em> or <em>xUnit</em>) by simply installing it from Nuget.  After, ReSharper allows to run your unit tests as in old good times:</p>
<p><figure id="attachment_1246" aria-describedby="caption-attachment-1246" style="width: 714px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1246" data-permalink="https://www.codejourney.net/unit-testing-xamarin-application/tests_rsharper/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/tests_rsharper.png?fit=714%2C149&amp;ssl=1" data-orig-size="714,149" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="tests_rsharper" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/tests_rsharper.png?fit=300%2C63&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/tests_rsharper.png?fit=714%2C149&amp;ssl=1" class="wp-image-1246 size-full" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/tests_rsharper.png?resize=714%2C149&#038;ssl=1" alt="tests_rsharper.PNG" width="714" height="149" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/tests_rsharper.png?w=714&amp;ssl=1 714w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/tests_rsharper.png?resize=300%2C63&amp;ssl=1 300w" sizes="auto, (max-width: 714px) 100vw, 714px" /><figcaption id="caption-attachment-1246" class="wp-caption-text">nUnit tests executed by ReSharper</figcaption></figure></p>
<p>The exception I was getting with ReSharper previously was because I added the project using template <em>Class Library (Android) </em>which has its target set to Android device/emulator. ReSharper doesn&#8217;t know about any Android-specific (or Xamarin-specific) testing, so it was displaying unhandled error.</p>
<h2>Platform-specific unit tests</h2>
<p>In order to test platform-specific (in out case Android-specific) functionalities of your application, the tests need targeting runtime environment to run. It means they need to be executed on the physical device or emulator. Providers of the most popular unit-testing frameworks created wrappers for on-device testing. I&#8217;m using <a href="https://github.com/nunit/nunit.xamarin" target="_blank" rel="noopener">NUnit Xamarin Runners</a>.</p>
<p>First of all, a new project should be added to our solution. To make things easier, download <a href="https://marketplace.visualstudio.com/items?itemName=NUnitDevelopers.NUnitTemplatesforVisualStudio" target="_blank" rel="noopener">NUnit Templates for Visual Studio</a> (although it officially supports VS up to 2015, it also works in VS 2017) and install it. After, add new project using appropriate template &#8211; I chose <strong>NUnit 3 Test Project (Android)</strong>. What&#8217;s interesting, the newly created project contains <em><span style="color: #ff6600;">MainActivity</span> </em>class with the following content:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46061652" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_tests-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_Tests.cs content, created by dsibinski on 10:13PM on March 25, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_Tests.cs">
<tr>
<td id="file-mainactivity_tests-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_tests-cs-LC1" class="blob-code blob-code-inner js-file-line">  public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_tests-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_tests-cs-LC3" class="blob-code blob-code-inner js-file-line">      protected override void OnCreate(Bundle savedInstanceState)</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_tests-cs-LC4" class="blob-code blob-code-inner js-file-line">      {</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_tests-cs-LC5" class="blob-code blob-code-inner js-file-line">          base.OnCreate(savedInstanceState);</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-mainactivity_tests-cs-LC6" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-mainactivity_tests-cs-LC7" class="blob-code blob-code-inner js-file-line">          global::Xamarin.Forms.Forms.Init(this, savedInstanceState);</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-mainactivity_tests-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-mainactivity_tests-cs-LC9" class="blob-code blob-code-inner js-file-line">          // This will load all tests within the current project</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-mainactivity_tests-cs-LC10" class="blob-code blob-code-inner js-file-line">          var nunit = new NUnit.Runner.App();</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-mainactivity_tests-cs-LC11" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-mainactivity_tests-cs-LC12" class="blob-code blob-code-inner js-file-line">          // If you want to add tests in another assembly</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-mainactivity_tests-cs-LC13" class="blob-code blob-code-inner js-file-line">          //nunit.AddTestAssembly(typeof(MyTests).Assembly);</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-mainactivity_tests-cs-LC14" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-mainactivity_tests-cs-LC15" class="blob-code blob-code-inner js-file-line">          // Do you want to automatically run tests when the app starts?</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-mainactivity_tests-cs-LC16" class="blob-code blob-code-inner js-file-line">          nunit.AutoRun = true;</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-mainactivity_tests-cs-LC17" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-mainactivity_tests-cs-LC18" class="blob-code blob-code-inner js-file-line">          LoadApplication(nunit);</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-mainactivity_tests-cs-LC19" class="blob-code blob-code-inner js-file-line">      }</td>
</tr>
<tr>
<td id="file-mainactivity_tests-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-mainactivity_tests-cs-LC20" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/ea386a734c1021a4ba5430e0306ab732/raw/fc5a31fd21ae36379882b0993be91d216944c4ec/MainActivity_Tests.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/ea386a734c1021a4ba5430e0306ab732#file-mainactivity_tests-cs" class="Link--inTextBlock"><br />
          MainActivity_Tests.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>As you can see, this is an <a href="https://www.codejourney.net/2017/03/xamarin-android-activities/" target="_blank" rel="noopener">Activity</a>, so it will be launched as a separate app with its own GUI. It&#8217;s built using Xamarin.Forms. The comments in auto-generated class are obvious, so I won&#8217;t explain the details here. That&#8217;s just what nUnit wrapper for Android on-device tests does &#8211; it allows to be run as a separate, small application with a GUI allowing to run unit tests directly on the device (similarly to ReSharper tests runner we use directly in Visual Studio).</p>
<p>One testable piece of <em>MoneyBack</em> application is the <em>Repository</em> used for database operations (by the way I refactored and made it generic, you can see how it looks currently on <a href="https://github.com/dsibinski/MoneyBack" target="_blank" rel="noopener">GitHub</a>), so I added <span style="color: #ff6600;"><em>RepositoryTests</em></span> class to <em>MoneyBack.Android.Tests</em> project with two test methods:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46061804" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-repositorytests_methods-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="RepositoryTests_methods.cs content, created by dsibinski on 10:22PM on March 25, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="RepositoryTests_methods.cs">
<tr>
<td id="file-repositorytests_methods-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-repositorytests_methods-cs-LC1" class="blob-code blob-code-inner js-file-line">[Test]</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-repositorytests_methods-cs-LC2" class="blob-code blob-code-inner js-file-line">public void one_new_person_inserted_adds_one_new_row()</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-repositorytests_methods-cs-LC3" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-repositorytests_methods-cs-LC4" class="blob-code blob-code-inner js-file-line">    // given</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-repositorytests_methods-cs-LC5" class="blob-code blob-code-inner js-file-line">    var person = new Person()</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-repositorytests_methods-cs-LC6" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-repositorytests_methods-cs-LC7" class="blob-code blob-code-inner js-file-line">        Name = &quot;A&quot;,</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-repositorytests_methods-cs-LC8" class="blob-code blob-code-inner js-file-line">        LastName = &quot;B&quot;</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-repositorytests_methods-cs-LC9" class="blob-code blob-code-inner js-file-line">    };</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-repositorytests_methods-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-repositorytests_methods-cs-LC11" class="blob-code blob-code-inner js-file-line">    var repo = new Repository&lt;Person&gt;(InMemorySqliteConnection);</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-repositorytests_methods-cs-LC12" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-repositorytests_methods-cs-LC13" class="blob-code blob-code-inner js-file-line">    // when</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-repositorytests_methods-cs-LC14" class="blob-code blob-code-inner js-file-line">    var numRows = repo.Insert(person).Result;</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-repositorytests_methods-cs-LC15" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-repositorytests_methods-cs-LC16" class="blob-code blob-code-inner js-file-line">    // then</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-repositorytests_methods-cs-LC17" class="blob-code blob-code-inner js-file-line">    Assert.AreEqual(1, numRows);</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-repositorytests_methods-cs-LC18" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-repositorytests_methods-cs-LC19" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-repositorytests_methods-cs-LC20" class="blob-code blob-code-inner js-file-line">[Test]</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-repositorytests_methods-cs-LC21" class="blob-code blob-code-inner js-file-line">public void new_person_added_has_id_primarykey_generated()</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-repositorytests_methods-cs-LC22" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-repositorytests_methods-cs-LC23" class="blob-code blob-code-inner js-file-line">    // given</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-repositorytests_methods-cs-LC24" class="blob-code blob-code-inner js-file-line">    var person1 = new Person</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-repositorytests_methods-cs-LC25" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
<td id="file-repositorytests_methods-cs-LC26" class="blob-code blob-code-inner js-file-line">        Name = &quot;A&quot;,</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
<td id="file-repositorytests_methods-cs-LC27" class="blob-code blob-code-inner js-file-line">        LastName = &quot;B&quot;</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
<td id="file-repositorytests_methods-cs-LC28" class="blob-code blob-code-inner js-file-line">    };</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
<td id="file-repositorytests_methods-cs-LC29" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
<td id="file-repositorytests_methods-cs-LC30" class="blob-code blob-code-inner js-file-line">    var person2 = new Person</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
<td id="file-repositorytests_methods-cs-LC31" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
<td id="file-repositorytests_methods-cs-LC32" class="blob-code blob-code-inner js-file-line">        Name = &quot;A&quot;,</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
<td id="file-repositorytests_methods-cs-LC33" class="blob-code blob-code-inner js-file-line">        LastName = &quot;B&quot;</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
<td id="file-repositorytests_methods-cs-LC34" class="blob-code blob-code-inner js-file-line">    };</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
<td id="file-repositorytests_methods-cs-LC35" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
<td id="file-repositorytests_methods-cs-LC36" class="blob-code blob-code-inner js-file-line">    var repo = new Repository&lt;Person&gt;(InMemorySqliteConnection);</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
<td id="file-repositorytests_methods-cs-LC37" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
<td id="file-repositorytests_methods-cs-LC38" class="blob-code blob-code-inner js-file-line">    // when</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
<td id="file-repositorytests_methods-cs-LC39" class="blob-code blob-code-inner js-file-line">    var n1 = repo.Insert(person1).Result; // getting Result in order to force Task&#39;s completion before continuing</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
<td id="file-repositorytests_methods-cs-LC40" class="blob-code blob-code-inner js-file-line">    var n2 = repo.Insert(person2).Result;</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L41" class="blob-num js-line-number js-blob-rnum" data-line-number="41"></td>
<td id="file-repositorytests_methods-cs-LC41" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L42" class="blob-num js-line-number js-blob-rnum" data-line-number="42"></td>
<td id="file-repositorytests_methods-cs-LC42" class="blob-code blob-code-inner js-file-line">    // then</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L43" class="blob-num js-line-number js-blob-rnum" data-line-number="43"></td>
<td id="file-repositorytests_methods-cs-LC43" class="blob-code blob-code-inner js-file-line">    Assert.Greater(person1.Id, 0);</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L44" class="blob-num js-line-number js-blob-rnum" data-line-number="44"></td>
<td id="file-repositorytests_methods-cs-LC44" class="blob-code blob-code-inner js-file-line">    Assert.AreEqual(person2.Id, person1.Id + 1);</td>
</tr>
<tr>
<td id="file-repositorytests_methods-cs-L45" class="blob-num js-line-number js-blob-rnum" data-line-number="45"></td>
<td id="file-repositorytests_methods-cs-LC45" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/2cefa097384d3c5e33595f37392cc330/raw/444e616d3480cdad0bda4c96e7112c7e65b2f698/RepositoryTests_methods.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/2cefa097384d3c5e33595f37392cc330#file-repositorytests_methods-cs" class="Link--inTextBlock"><br />
          RepositoryTests_methods.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>The interesting part is that as I&#8217;m using <a href="https://www.codejourney.net/2017/03/using-sqlite-database-in-xamarin-android/" target="_blank" rel="noopener">SQLite database in my app</a>, I wanted to test it without creating database file on the device. For that purpose, when creating <em><span style="color: #ff6600;">SQLiteAsyncConnection</span> </em>in order<em> </em>to initialize my <em><span style="color: #ff6600;">Repository</span>, </em>I passed to its constructor a <em>&#8220;:memory:&#8221;</em> string, which makes SQLite database created <a href="https://sqlite.org/inmemorydb.html" target="_blank" rel="noopener">in-memory</a> (there is no physical file created):</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist46061888" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-repositorytests_sqlite-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="RepositoryTests_sqlite.cs content, created by dsibinski on 10:27PM on March 25, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="RepositoryTests_sqlite.cs">
<tr>
<td id="file-repositorytests_sqlite-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-repositorytests_sqlite-cs-LC1" class="blob-code blob-code-inner js-file-line">  public SQLiteAsyncConnection InMemorySqliteConnection;</td>
</tr>
<tr>
<td id="file-repositorytests_sqlite-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-repositorytests_sqlite-cs-LC2" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-repositorytests_sqlite-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-repositorytests_sqlite-cs-LC3" class="blob-code blob-code-inner js-file-line">  [OneTimeSetUp]</td>
</tr>
<tr>
<td id="file-repositorytests_sqlite-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-repositorytests_sqlite-cs-LC4" class="blob-code blob-code-inner js-file-line">  public void Init()</td>
</tr>
<tr>
<td id="file-repositorytests_sqlite-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-repositorytests_sqlite-cs-LC5" class="blob-code blob-code-inner js-file-line">  {</td>
</tr>
<tr>
<td id="file-repositorytests_sqlite-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-repositorytests_sqlite-cs-LC6" class="blob-code blob-code-inner js-file-line">      InMemorySqliteConnection = new SQLiteAsyncConnection(&quot;:memory:&quot;);</td>
</tr>
<tr>
<td id="file-repositorytests_sqlite-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-repositorytests_sqlite-cs-LC7" class="blob-code blob-code-inner js-file-line">  }</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/e205d0eacd107226c0986a2b9d2d8422/raw/53f9fb2a2be3c5f28320fbc09049b087694ed624/RepositoryTests_sqlite.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/e205d0eacd107226c0986a2b9d2d8422#file-repositorytests_sqlite-cs" class="Link--inTextBlock"><br />
          RepositoryTests_sqlite.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>&nbsp;</p>
<p>Such database lives in device&#8217;s memory only for the time of our unit tests.</p>
<p>After having tests written, there&#8217;s a time to execute them. As the project contains <em><span style="color: #ff6600;">MainActivity</span> </em>class, we simply deploy and run it on a device/emulator, which presents the following view:</p>
<p><figure id="attachment_1306" aria-describedby="caption-attachment-1306" style="width: 210px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1306" data-permalink="https://www.codejourney.net/unit-testing-xamarin-application/screenshot_2017-03-25-23-31-44/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot_2017-03-25-23-31-44" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?fit=576%2C1024&amp;ssl=1" class=" wp-image-1306 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?resize=210%2C374&#038;ssl=1" alt="Screenshot_2017-03-25-23-31-44.png" width="210" height="374" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-23-31-44.png?resize=720%2C1280&amp;ssl=1 720w" sizes="auto, (max-width: 210px) 100vw, 210px" /><figcaption id="caption-attachment-1306" class="wp-caption-text">Device &#8211; tests results</figcaption></figure></p>
<p>If any of our tests is not passed, we can see the failure&#8217;s details:</p>
<p><figure id="attachment_1311" aria-describedby="caption-attachment-1311" style="width: 219px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1311" data-permalink="https://www.codejourney.net/unit-testing-xamarin-application/screenshot_2017-03-25-21-23-07/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?fit=1080%2C1920&amp;ssl=1" data-orig-size="1080,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot_2017-03-25-21-23-07" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?fit=169%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?fit=576%2C1024&amp;ssl=1" class=" wp-image-1311 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?resize=219%2C389&#038;ssl=1" alt="Screenshot_2017-03-25-21-23-07.png" width="219" height="389" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?w=1080&amp;ssl=1 1080w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?resize=169%2C300&amp;ssl=1 169w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?resize=768%2C1365&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?resize=576%2C1024&amp;ssl=1 576w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_2017-03-25-21-23-07.png?resize=720%2C1280&amp;ssl=1 720w" sizes="auto, (max-width: 219px) 100vw, 219px" /><figcaption id="caption-attachment-1311" class="wp-caption-text">Device &#8211; test failed</figcaption></figure></p>
<p>We can of course debug our units tests in Visual Studio. The GUI on the device also allows to re-run the tests and see results of all of them.</p>
<h2>Summary</h2>
<p>We&#8217;ve seen how to add two new projects to Xamarin solution: one containing platform-independent unit tests (old good ones), the other one testing Android-specific stuff which is run directly on the device or emulator.</p>
<p>For bigger and more &#8220;real&#8221; apps, UI testing would also be necessary. This however requires using some cloud testing lab or setting up your own testing environment. More details can be found <a href="https://developer.xamarin.com/guides/testcloud/introduction-to-test-cloud/" target="_blank" rel="noopener">here</a>.</p>
<p><span style="text-decoration: underline;"><strong>If you have any experience in testing Xamarin applications, share your insights/advices <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></span></p>
<h2> </h2>
<p>&nbsp;</p>
<p>The post <a href="https://www.codejourney.net/unit-testing-xamarin-application/">Unit Testing Xamarin application</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/unit-testing-xamarin-application/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1166</post-id>	</item>
		<item>
		<title>Using SQLite database in Xamarin.Android</title>
		<link>https://www.codejourney.net/using-sqlite-database-in-xamarin-android/</link>
					<comments>https://www.codejourney.net/using-sqlite-database-in-xamarin-android/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 19 Mar 2017 22:32:29 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=970</guid>

					<description><![CDATA[<p>I started to define development tasks to be done within MoneyBack project in the coming days (maybe I&#8217;ll even publish my Trello board soon 🙂 ) and it turned out that each functionality the app is going to offer needs persistent storage (e.g. to store people, payments, events etc.). The obvious choice is the local database in which&#8230;</p>
<p>The post <a href="https://www.codejourney.net/using-sqlite-database-in-xamarin-android/">Using SQLite database in Xamarin.Android</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I started to define development tasks to be done within <em>MoneyBack</em> project in the coming days (maybe I&#8217;ll even publish my Trello board soon <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ) and it turned out that each functionality the app is going to offer needs persistent storage (e.g. to store people, payments, events etc.). The obvious choice is the local database in which I could store my entities and application&#8217;s data.</p>
<p>In this post, I&#8217;d like to show you how quickly and easily SQLite database can be added and started to be used in Xamarin.Android project using <a href="https://www.nuget.org/packages/sqlite-net/" target="_blank" rel="noopener">SQLite.NET</a> and Visual Studio 2017.<br />
<span id="more-970"></span></p>
<h2>What is SQLite?</h2>
<p><a href="http://sqlite.org/" target="_blank" rel="noopener">SQLite</a> is an open-source database engine, which allows to store data in SQL structures. The whole database is stored in a single file, which makes it easily manageable on mobile devices. It&#8217;s lightweight, small and easily portable. It&#8217;s also prepared to work on multiple platforms.</p>
<p>There are some limitations in contrast to &#8220;classic&#8221; SQL database engines, including:</p>
<ul>
<li>OUTER join syntax is not fully supported</li>
<li>for altering tables, only &#8220;RENAME&#8221; and &#8220;ADDCOLUMN&#8221; operations are available</li>
<li>writing to views is impossible (views are read-only).</li>
</ul>
<p>SQLite database can be easily operated using SQLite.NET ORM library available to download and install via Nuget. Let&#8217;s see how to do it.</p>
<h2>Installing SQLite.NET package</h2>
<p>In order to install SQLite.NET package, simply open Android.Xamarin solution in Visual Studio, open Package Manager Console and type the following command:</p>
<pre><pre class="brush: csharp; title: ; notranslate">install-package Sqlite-Net</pre>
<p>After few seconds, two files are added to our project:</p>
<p><figure id="attachment_1007" aria-describedby="caption-attachment-1007" style="width: 185px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1007" data-permalink="https://www.codejourney.net/using-sqlite-database-in-xamarin-android/sqlitenetfiles/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/SQLiteNetFiles.png?fit=315%2C420&amp;ssl=1" data-orig-size="315,420" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="SQLiteNetFiles" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/SQLiteNetFiles.png?fit=225%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/SQLiteNetFiles.png?fit=315%2C420&amp;ssl=1" class=" wp-image-1007 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/SQLiteNetFiles.png?resize=185%2C247&#038;ssl=1" alt="SQLiteNetFiles" width="185" height="247" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/SQLiteNetFiles.png?w=315&amp;ssl=1 315w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/SQLiteNetFiles.png?resize=225%2C300&amp;ssl=1 225w" sizes="auto, (max-width: 185px) 100vw, 185px" /><figcaption id="caption-attachment-1007" class="wp-caption-text">Files added by SQLite.NET</figcaption></figure></p>
<p>It means we&#8217;re all set <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h2>Entity definition</h2>
<p>We have SQLite ORM ready to use. Now we need to define our first entity. In case of <em>MoneyBack</em>, I decided to start with defining <em>Person </em>(plural: <em>People</em>) entity. First thing we need to do is to define entity class. I created &#8220;Entities&#8221; folder for that and added the following class file:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45864679" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-person-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Person.cs content, created by dsibinski on 09:06PM on March 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Person.cs">
<tr>
<td id="file-person-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-person-cs-LC1" class="blob-code blob-code-inner js-file-line">namespace MoneyBack.Entities</td>
</tr>
<tr>
<td id="file-person-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-person-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-person-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-person-cs-LC3" class="blob-code blob-code-inner js-file-line">    [Table(&quot;People&quot;)]</td>
</tr>
<tr>
<td id="file-person-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-person-cs-LC4" class="blob-code blob-code-inner js-file-line">    public class Person</td>
</tr>
<tr>
<td id="file-person-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-person-cs-LC5" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-person-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-person-cs-LC6" class="blob-code blob-code-inner js-file-line">        [PrimaryKey, AutoIncrement]</td>
</tr>
<tr>
<td id="file-person-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-person-cs-LC7" class="blob-code blob-code-inner js-file-line">        public int Id { get; set; }</td>
</tr>
<tr>
<td id="file-person-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-person-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-person-cs-LC9" class="blob-code blob-code-inner js-file-line">        public string Name { get; set; }</td>
</tr>
<tr>
<td id="file-person-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-person-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-person-cs-LC11" class="blob-code blob-code-inner js-file-line">        public string LastName { get; set; }</td>
</tr>
<tr>
<td id="file-person-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-person-cs-LC12" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-person-cs-LC13" class="blob-code blob-code-inner js-file-line">        public string PhoneNumber { get; set; }</td>
</tr>
<tr>
<td id="file-person-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-person-cs-LC14" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-person-cs-LC15" class="blob-code blob-code-inner js-file-line">        public string Email { get; set; }</td>
</tr>
<tr>
<td id="file-person-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-person-cs-LC16" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-person-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-person-cs-LC17" class="blob-code blob-code-inner js-file-line">        public override string ToString()</td>
</tr>
<tr>
<td id="file-person-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-person-cs-LC18" class="blob-code blob-code-inner js-file-line">        {</td>
</tr>
<tr>
<td id="file-person-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-person-cs-LC19" class="blob-code blob-code-inner js-file-line">            return $&quot;[Person: Id={Id}, Name={Name}, LastName={LastName}, PhoneNumber={PhoneNumber}, Email={Email}]&quot;;</td>
</tr>
<tr>
<td id="file-person-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-person-cs-LC20" class="blob-code blob-code-inner js-file-line">        }</td>
</tr>
<tr>
<td id="file-person-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-person-cs-LC21" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
<tr>
<td id="file-person-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-person-cs-LC22" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/a1d1ca6c5380e0acc5c439f3060da9cc/raw/afc1d9b4c0442489fdb760ba88e681d3663b9e07/Person.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/a1d1ca6c5380e0acc5c439f3060da9cc#file-person-cs" class="Link--inTextBlock"><br />
          Person.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>Just a class, in which we define basic properties of a Person &#8211;<em> Name, LastName, PhoneNumber</em> and <em>Email</em>. As we are designing a database entities, we also need to have keys for each of them &#8211; in this case we add <em>Id</em> property, and decorate it with two attributes:</p>
<ul>
<li><em>PrimaryKeyAttribute</em> &#8211; marks the column as PRIMARY KEY</li>
<li><em>AutoIncrementAttribute</em> &#8211; marks the column with AUTO_INCREMENT (unique number is generated when a new record is added into a table).</li>
</ul>
<p>We also have <em>TableAttribute</em> defined on <em>Person</em> class. This attribute&#8217;s constructor takes a single argument <em>name</em>, which is the name of the table which will be created underneath. In our case, single entity is called <em>Person</em>, but the table should be named in plural (table == set of entities) so we want it to be called <em>People</em>.</p>
<p>I also implemented <em>ToString() </em>method in order to be able to easily see details of our entity if needed.</p>
<h2>Location of database file</h2>
<p>Before database can be used, a database file must be created on the device. ORM does it for us before any query is made on the database, but we need to specify where we want to keep the db file. On Android, it can be stored either on internal or external storage.</p>
<p>I created <em>Constants.cs</em> class in which I put a read-only constant string returning path to database file. As a folder to store db file, I used <em>Environment.GetFolderPath(Environment.SpecialFolder.Personal) </em>which returns local path defined in Android system&#8217;s environmental variable $HOME:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45865151" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-constants_dbpath-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Constants_dbPath.cs content, created by dsibinski on 09:30PM on March 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Constants_dbPath.cs">
<tr>
<td id="file-constants_dbpath-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-constants_dbpath-cs-LC1" class="blob-code blob-code-inner js-file-line">public class Constants</td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-constants_dbpath-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-constants_dbpath-cs-LC3" class="blob-code blob-code-inner js-file-line">    public static readonly string DbFilePath = </td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-constants_dbpath-cs-LC4" class="blob-code blob-code-inner js-file-line">        Path.Combine(</td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-constants_dbpath-cs-LC5" class="blob-code blob-code-inner js-file-line">                Environment.GetFolderPath(Environment.SpecialFolder.Personal), </td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-constants_dbpath-cs-LC6" class="blob-code blob-code-inner js-file-line">                &quot;moneyback.db&quot;</td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-constants_dbpath-cs-LC7" class="blob-code blob-code-inner js-file-line">        );</td>
</tr>
<tr>
<td id="file-constants_dbpath-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-constants_dbpath-cs-LC8" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/d5fb45ea47ee86b0540bf9f68666d103/raw/f01a0588740a5477cc78d7ce8e9e89b80d95d299/Constants_dbPath.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/d5fb45ea47ee86b0540bf9f68666d103#file-constants_dbpath-cs" class="Link--inTextBlock"><br />
          Constants_dbPath.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<h2>Database access methods</h2>
<p>As soon as we have entity class defined and location of database file, we can start performing operations on the db &#8211; define tables, add new entities (rows), retrieve rows from the database, delete them etc. In general, it comes down to creating <em>SQLiteConnection </em>object and performing operations on it.</p>
<p>There are several approaches of exposing Data Access Layer services/methods &#8211; we can create a database service, entities repository or use complex services location and dependency injection in order to operate our persistent data. I don&#8217;t know what is a standard way in Android applications, but I decided to create a very simple repository for our <em>Person</em> entity and expose database-access methods in it:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45865287" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-peoplerepository-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="PeopleRepository.cs content, created by dsibinski on 09:39PM on March 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="PeopleRepository.cs">
<tr>
<td id="file-peoplerepository-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-peoplerepository-cs-LC1" class="blob-code blob-code-inner js-file-line">public class PeopleRepository</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-peoplerepository-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-peoplerepository-cs-LC3" class="blob-code blob-code-inner js-file-line">    private SQLiteConnection db = null;</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-peoplerepository-cs-LC4" class="blob-code blob-code-inner js-file-line">    protected static PeopleRepository me;</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-peoplerepository-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-peoplerepository-cs-LC6" class="blob-code blob-code-inner js-file-line">    static PeopleRepository()</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-peoplerepository-cs-LC7" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-peoplerepository-cs-LC8" class="blob-code blob-code-inner js-file-line">        me = new PeopleRepository();</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-peoplerepository-cs-LC9" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-peoplerepository-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-peoplerepository-cs-LC11" class="blob-code blob-code-inner js-file-line">    protected PeopleRepository()</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-peoplerepository-cs-LC12" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-peoplerepository-cs-LC13" class="blob-code blob-code-inner js-file-line">        db = new SQLiteConnection(Constants.DbFilePath);</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-peoplerepository-cs-LC14" class="blob-code blob-code-inner js-file-line">        db.CreateTable&lt;Person&gt;();</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-peoplerepository-cs-LC15" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-peoplerepository-cs-LC16" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-peoplerepository-cs-LC17" class="blob-code blob-code-inner js-file-line">    public static int SavePerson(Person person)</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-peoplerepository-cs-LC18" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-peoplerepository-cs-LC19" class="blob-code blob-code-inner js-file-line">        me.db.Insert(person);</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-peoplerepository-cs-LC20" class="blob-code blob-code-inner js-file-line">        return person.Id;</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-peoplerepository-cs-LC21" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-peoplerepository-cs-LC22" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-peoplerepository-cs-LC23" class="blob-code blob-code-inner js-file-line">    public static Person GetPerson(int id)</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
<td id="file-peoplerepository-cs-LC24" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
<td id="file-peoplerepository-cs-LC25" class="blob-code blob-code-inner js-file-line">        return me.db.Get&lt;Person&gt;(p =&gt; p.Id == id);</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
<td id="file-peoplerepository-cs-LC26" class="blob-code blob-code-inner js-file-line">    }</td>
</tr>
<tr>
<td id="file-peoplerepository-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
<td id="file-peoplerepository-cs-LC27" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/c8256dbaaf5970a512062aa3a9fe5ad3/raw/5371465e526cbf189e77c720e9f97e2b37748042/PeopleRepository.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/c8256dbaaf5970a512062aa3a9fe5ad3#file-peoplerepository-cs" class="Link--inTextBlock"><br />
          PeopleRepository.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>I haven&#8217;t even created any abstract layer for the repository (e.g. interface), as I simply don&#8217;t know what approach I will use for the next entities. I&#8217;m not sure if the repository is the right choice. On the other hand, I don&#8217;t think such rather simple app requires something more. <span style="text-decoration: underline;"><strong>What do you think ?</p>
<p></strong></span></p>
<p>As you can see, <em>PeopleRepository</em> executes its static constructor when any of static methods is called for the first time, in which it instantiates <em>db</em> variable of type <em>SQLiteConnection</em>, giving it the path to db file we defined. If database file doesn&#8217;t exist, it will be automatically created. Then, <em>db.CreateTable&lt;Person&gt;()</em> creates <em>People</em> table if it doesn&#8217;t exist, according to what we defined in <em>Person</em> entity model.</p>
<p>Two static methods &#8211; <em>SavePerson</em> and <em>GetPerson </em>allow to save and retrieve <em>Person</em> entity to/from the database accordingly. The first one is additionally returning the integer <em>Id</em> of newly added row.</p>
<h2>Usage in the code</h2>
<p>I added two text fields to <em>MoneyBack</em> app to enter name and last name of person to be added and one button which actually allows to perform saving operation:</p>
<p><figure id="attachment_1088" aria-describedby="caption-attachment-1088" style="width: 233px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1088" data-permalink="https://www.codejourney.net/using-sqlite-database-in-xamarin-android/moneyback_savingperson/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_SavingPerson" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-1088 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?resize=233%2C388&#038;ssl=1" alt="MoneyBack_SavingPerson.png" width="233" height="388" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 233px) 100vw, 233px" /><figcaption id="caption-attachment-1088" class="wp-caption-text">Adding new Person</figcaption></figure></p>
<p>On clicking the button, the following method is executed:</p>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45865616" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-addpersonbuttonclick-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="addPersonButtonClick.cs content, created by dsibinski on 09:58PM on March 19, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="addPersonButtonClick.cs">
<tr>
<td id="file-addpersonbuttonclick-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-addpersonbuttonclick-cs-LC1" class="blob-code blob-code-inner js-file-line">private void _btnAddPerson_Click(object sender, EventArgs e)</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-addpersonbuttonclick-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-addpersonbuttonclick-cs-LC3" class="blob-code blob-code-inner js-file-line">    var name = _inputName.Text;</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-addpersonbuttonclick-cs-LC4" class="blob-code blob-code-inner js-file-line">    var lastName = _inputLastName.Text;</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-addpersonbuttonclick-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-addpersonbuttonclick-cs-LC6" class="blob-code blob-code-inner js-file-line">    var id = PeopleRepository.SavePerson(new Person</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-addpersonbuttonclick-cs-LC7" class="blob-code blob-code-inner js-file-line">    {</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-addpersonbuttonclick-cs-LC8" class="blob-code blob-code-inner js-file-line">        Name = name,</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-addpersonbuttonclick-cs-LC9" class="blob-code blob-code-inner js-file-line">        LastName = lastName</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-addpersonbuttonclick-cs-LC10" class="blob-code blob-code-inner js-file-line">    });</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-addpersonbuttonclick-cs-LC11" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-addpersonbuttonclick-cs-LC12" class="blob-code blob-code-inner js-file-line">    var person = PeopleRepository.GetPerson(id);</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-addpersonbuttonclick-cs-LC13" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-addpersonbuttonclick-cs-LC14" class="blob-code blob-code-inner js-file-line">    if (person == null)</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-addpersonbuttonclick-cs-LC15" class="blob-code blob-code-inner js-file-line">        Toast.MakeText(this, $&quot;Person: Name={name}, LastName={lastName} wasn&#39;t properly saved!&quot;, ToastLength.Long).Show();</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-addpersonbuttonclick-cs-LC16" class="blob-code blob-code-inner js-file-line">    else</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-addpersonbuttonclick-cs-LC17" class="blob-code blob-code-inner js-file-line">        Toast.MakeText(this, $&quot;Person saved, details: {person}&quot;, ToastLength.Long).Show();</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-addpersonbuttonclick-cs-LC18" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-addpersonbuttonclick-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-addpersonbuttonclick-cs-LC19" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/4b9472f0a5f787a265fee0982dfcec96/raw/5b9be5b6240b78b71654a2a3651315b9e508b3c6/addPersonButtonClick.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/4b9472f0a5f787a265fee0982dfcec96#file-addpersonbuttonclick-cs" class="Link--inTextBlock"><br />
          addPersonButtonClick.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>&nbsp;</p>
<p>Here&#8217;s the result of clicking the button in the app:</p>
<p><figure id="attachment_1093" aria-describedby="caption-attachment-1093" style="width: 249px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="1093" data-permalink="https://www.codejourney.net/using-sqlite-database-in-xamarin-android/moneyback_savingperson_success/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_SavingPerson_Success" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-1093 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?resize=249%2C415&#038;ssl=1" alt="MoneyBack_SavingPerson_Success.png" width="249" height="415" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_SavingPerson_Success.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 249px) 100vw, 249px" /><figcaption id="caption-attachment-1093" class="wp-caption-text">Person saved successfully</figcaption></figure></p>
<p>As you can see, in the toast message received, <em>Id</em> of the <em>Person</em> added has value 3. That&#8217;s because when I launched the app previously I&#8217;ve already added two new people. It shows that the data is really persistently stored and doesn&#8217;t disappear when the app is restarted.</p>
<h2>Summary</h2>
<p>Today we&#8217;ve seen that using SQLite file database in Xamarin.Android is very easy. Thanks to SQLite.NET lightweight ORM library we were able to quickly start working with the db.</p>
<p>To make the code ready for &#8220;production&#8221; use, I should also make it thread-safe (more details e.g. <a href="https://developer.xamarin.com/guides/android/application_fundamentals/data/part_2_configuration/" target="_blank" rel="noopener">here</a>) and add unit tests (which I&#8217;m BTW not able to do for now, I&#8217;m getting <em>TargetInvocationException</em> when trying to run any NUnit tests adding <em>Unit Test App (Android)</em> project in VS 2017&#8230;).</p>
<p>I&#8217;m also not sure if repository is a proper concept for managing local db entities in Android project. <span style="text-decoration: underline;"><strong>If you have more experience, I&#8217;d be grateful to hear how it should be done in a really &#8220;Android way&#8221; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></span></p>
<p>The post <a href="https://www.codejourney.net/using-sqlite-database-in-xamarin-android/">Using SQLite database in Xamarin.Android</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/using-sqlite-database-in-xamarin-android/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">970</post-id>	</item>
		<item>
		<title>Xamarin – Android Activities</title>
		<link>https://www.codejourney.net/xamarin-android-activities/</link>
					<comments>https://www.codejourney.net/xamarin-android-activities/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 11 Mar 2017 18:53:10 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=405</guid>

					<description><![CDATA[<p>Today we’re going to take a look at Android’s most basic and in the same time most important concept, which is an Activity. To create even the simplest “HelloWorld” app one should know what are the Activities and how to work with them. What is an Activity ? The simplest, an Activity is a single&#8230;</p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-activities/">Xamarin – Android Activities</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p style="text-align: left;">Today we’re going to take a look at Android’s most basic and in the same time most important concept, which is an <strong>Activity</strong>. To create even the simplest “HelloWorld” app one should know what are the Activities and how to work with them.<br />
<span id="more-405"></span></p>
<h2>What is an Activity ?</h2>
<p style="text-align: left;" align="left">The simplest, an <strong>Activity is a single screen in Android application</strong>. The concept of Activities is unusual in programming and it&#8217;s specific to Android platform.</p>
<p style="text-align: left;" align="left">Every Activity in Xamarin consists of two components:</p>
<ul>
<li style="text-align: left;"><strong>UI </strong>(XML) &#8211; layout with user controls defined</li>
<li style="text-align: left;"><strong>Code </strong>(C#) &#8211; implementing the behavior</li>
</ul>
<p>Let&#8217;s consider email client application &#8211; it&#8217;d probably have several Activities: &#8220;New email&#8221;, &#8220;List of emails&#8221;, &#8220;Email details&#8221;, &#8220;Settings&#8221; &#8211; notice all of them having both UI and behavior. We&#8217;d probably need &#8220;Email sending service&#8221;, which doesn&#8217;t necessarily need UI, so it wouldn&#8217;t be created as an Activity, but rather as a separate class realizing concrete task.</p>
<p>As we can already see, every Android app contains several Activities:</p>
<p><figure id="attachment_484" aria-describedby="caption-attachment-484" style="width: 1823px" class="wp-caption alignnone"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="484" data-permalink="https://www.codejourney.net/xamarin-android-activities/activities/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?fit=1823%2C914&amp;ssl=1" data-orig-size="1823,914" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="activities" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?fit=1024%2C513&amp;ssl=1" class="alignnone size-full wp-image-484" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?resize=1140%2C572&#038;ssl=1" alt="activities" width="1140" height="572" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?w=1823&amp;ssl=1 1823w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?resize=300%2C150&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?resize=768%2C385&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?resize=1024%2C513&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities.png?resize=720%2C361&amp;ssl=1 720w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /><figcaption id="caption-attachment-484" class="wp-caption-text">Android app composed of Activities, source: <a href="https://elearning.xamarin.com/android/AND101/2-activities/default" target="_blank" rel="noopener">elearning.xamarin.com</a></figcaption></figure></p>
<p>In most programming platforms, the application has a static method which is called on the application&#8217;s startup. This is not the case in Android &#8211; do you remember our <em>MainActivity </em>class <a href="https://www.codejourney.net/2017/03/hello-xamarin-world-first-steps/" target="_blank" rel="noopener">from the previous post</a> ? It&#8217;s decorated with <em>ActivityAttribute</em> which registers the Activity within the Android system, but what&#8217;s more important by having <em>MainLauncher</em> attribute&#8217;s property set to <strong>true</strong> it tells the system it&#8217;s the startup Activity for the application within which it&#8217;s registered. It means nothing more than when our app is launched, Android creates <em>MainActivity</em> as the first one from all Activities in our application. Apart from that, OS operates the <em>MainActivity</em> as all other Activities.</p>
<h2>Activities Back Stack</h2>
<p>Android app starts its own Activities from other Activities. It may also start Activities that are defined by different apps, e.g. your Android app can offer a possibility to send an email. You don&#8217;t have to implement your own email sending client for that &#8211; it&#8217;s possible to use already existing email sending Activities (using <a href="https://developer.xamarin.com/recipes/android/fundamentals/intent/" target="_blank" rel="noopener">Android Intents</a>, which we&#8217;ll also cover one day) registered within another apps installed in the system which expose such &#8220;external calling&#8221; possibility. Then, this external app launches looking as if it was the part of your application. This is very <strong>powerful!</strong></p>
<p>When your email is finally sent, you are redirected back to your app from which you triggered email&#8217;s sending. <em><strong>How is that possible?</p>
<p></strong></em></p>
<p>In order to ensure such way of functioning, Android keeps all the Activities needed to perform a certain job (even if they come from different apps) in the same <em>task</em>. The &#8220;scope&#8221; of a <em>task</em> (when new <em>task</em> is created, what Activities it contains etc.) depends, among others, on Android version (e.g. starting from Android 7.0 many apps can be started in multiple windows in the same time on a single screen &#8211; in that case, the system keeps a separate <em>task</em> for each window).</p>
<p>Within a particular <em>task</em>, several Activities are started. Each started Activity is pushed to the <strong>Activities</strong> <strong>Back Stack</strong>. The Activity being on the top of the stack <strong>has focus </strong>(is visible to the user). The previous Activities remain on the stack, but are stopped or even destroyed by Android system in certain cases (few more words about it in the next chapter).</p>
<p>Activities Back Stack is a LIFO objects structure: when user presses <a href="https://www.codejourney.net/wp-content/uploads/2017/03/android_back_button.png" target="_blank" rel="noopener"><strong>Back</strong> button</a> the current Activity is popped from the top of the stack and the state of the previous Activity is restored. The following figure visualizes this behavior:</p>
<p><figure id="attachment_550" aria-describedby="caption-attachment-550" style="width: 617px" class="wp-caption alignnone"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="550" data-permalink="https://www.codejourney.net/xamarin-android-activities/diagram_backstack/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/diagram_backstack.png?fit=617%2C195&amp;ssl=1" data-orig-size="617,195" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="diagram_backstack" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/diagram_backstack.png?fit=300%2C95&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/diagram_backstack.png?fit=617%2C195&amp;ssl=1" class="alignnone size-full wp-image-550" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/diagram_backstack.png?resize=617%2C195&#038;ssl=1" alt="diagram_backstack" width="617" height="195" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/diagram_backstack.png?w=617&amp;ssl=1 617w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/diagram_backstack.png?resize=300%2C95&amp;ssl=1 300w" sizes="auto, (max-width: 617px) 100vw, 617px" /><figcaption id="caption-attachment-550" class="wp-caption-text">Activities Back Stack (LIFO) visualization, source: <a href="https://developer.android.com/guide/components/activities/tasks-and-back-stack.html" target="_blank" rel="noopener">developer.android.com</a></figcaption></figure></p>
<h2>Android Activities Lifecycle</h2>
<p>We already know the Activities are kept on Back Stack. We also need to know that Android OS may try to <strong>restart</strong> the application (after it crashed, for instance) at the last opened Activity. The OS may also <strong>pause</strong> the Activities when they&#8217;re not active or <strong>kill </strong>them when the device is low on memory. All those possible operations and states&#8217; changes form <strong>Android Activities Lifecycle</strong>, which is a set of defined states in which every Activity may be:</p>
<p><figure id="attachment_578" aria-describedby="caption-attachment-578" style="width: 1720px" class="wp-caption alignnone"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="578" data-permalink="https://www.codejourney.net/xamarin-android-activities/activities_states/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?fit=1720%2C347&amp;ssl=1" data-orig-size="1720,347" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="activities_states" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?fit=300%2C61&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?fit=1024%2C207&amp;ssl=1" class="alignnone size-full wp-image-578" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?resize=1140%2C230&#038;ssl=1" alt="activities_states" width="1140" height="230" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?w=1720&amp;ssl=1 1720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?resize=300%2C61&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?resize=768%2C155&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?resize=1024%2C207&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/activities_states.png?resize=720%2C145&amp;ssl=1 720w" sizes="auto, (max-width: 1140px) 100vw, 1140px" /><figcaption id="caption-attachment-578" class="wp-caption-text">Activity states, source: <a href="https://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/" target="_blank" rel="noopener">developer.xamarin.com</a></figcaption></figure></p>
<p>Let&#8217;s see what those states mean:</p>
<ul>
<li><strong>Running</strong> &#8211; Activity is in the foreground (top of the activities stack); <span style="text-decoration: underline;">highest-priority Activity</span> for OS</li>
<li><strong>Paused </strong>&#8211; Activity is in this state when still visible, but covered by another non-full sized Activity or when the device enters sleep mode; <span style="text-decoration: underline;">second-highest-priority Activity</span> for OS</li>
<li><strong>Backgrounded/Stopped</strong>&#8211; Activity enters Backgrounded state when it&#8217;s overtaken by another, completely new Activity which is pushed on the top of the back stack; <span style="text-decoration: underline;">lowest-priority Activity</span> for OS, which will be killed firstly in order to free resources</li>
<li><strong>Restarted </strong>&#8211; this state is not visible on the diagram, however it&#8217;s possible that Android (e.g. user using task manager or similar app) kills the app being in any of above-mentioned states; if the user wants to go back to this Activity later, it must be restarted (previous state must be retrieved).</li>
</ul>
<h2>Handling states changes &#8211; lifecycle methods</h2>
<p>Android (and Xamarin) provides SDK methods that are called by the OS each time an Activity&#8217;s state changes. Those methods may be overridden and implemented for each Activity in order to react on states changes and ensure application&#8217;s stability. The following diagram visualizes the dependencies and flow of methods being called:</p>
<p><figure id="attachment_605" aria-describedby="caption-attachment-605" style="width: 399px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="605" data-permalink="https://www.codejourney.net/xamarin-android-activities/android_lifecycle_methods/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?fit=1720%2C1998&amp;ssl=1" data-orig-size="1720,1998" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="android_lifecycle_methods" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?fit=258%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?fit=882%2C1024&amp;ssl=1" class=" wp-image-605 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?resize=399%2C464&#038;ssl=1" alt="android_lifecycle_methods" width="399" height="464" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?w=1720&amp;ssl=1 1720w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?resize=258%2C300&amp;ssl=1 258w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?resize=768%2C892&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?resize=882%2C1024&amp;ssl=1 882w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_lifecycle_methods.png?resize=720%2C836&amp;ssl=1 720w" sizes="auto, (max-width: 399px) 100vw, 399px" /><figcaption id="caption-attachment-605" class="wp-caption-text">Android lifecycle methods, source: <a href="https://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/" target="_blank" rel="noopener">developer.xamarin.com</a></figcaption></figure></p>
<p>Let&#8217;s see in what cases the particular methods should be implemented:</p>
<ul>
<li><strong>OnCreate()</strong> &#8211; called when an Activity is created; used for initializing views and variables</li>
<li><strong>OnStart()</strong> &#8211; called immediately after <em>OnCreate()</em> finishes; UI refreshing can be handled here</li>
<li><strong>OnResume()</strong> &#8211; called after <em>OnStart()</em> finishes and also when Activity is restarted after being paused</li>
<li><strong>OnPause()</strong> &#8211; called when OS is about to pause or move the Activity to the background; here all resources-consuming objects should be cleaned-up, unsaved changes should be stored in some kind of persistent storage to be able to restore it when the Activity is revealed</li>
<li><strong>OnStop()</strong> &#8211; called when the Activity stops being visible to the user or is destroyed (e.g. when OS needs to release some resources)</li>
<li><strong>OnDestroy()</strong> &#8211; final method called on Activity just before it&#8217;s destroyed; it may not be called in some cases, so it&#8217;s better to clean-up resources in <em>OnPause()</em> and <em>OnStop()</em> methods.</li>
</ul>
<h2>Let&#8217;s see some code</h2>
<p>In order to really test those lifecycle methods, I added a stunning functionality to <em>MoneyBack</em> app:</p>
<p><figure id="attachment_629" aria-describedby="caption-attachment-629" style="width: 238px" class="wp-caption aligncenter"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="629" data-permalink="https://www.codejourney.net/xamarin-android-activities/screenshot_lifecycle/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?fit=768%2C1280&amp;ssl=1" data-orig-size="768,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot_Lifecycle" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?fit=180%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?fit=614%2C1024&amp;ssl=1" class=" wp-image-629 aligncenter" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?resize=238%2C397&#038;ssl=1" alt="Screenshot_Lifecycle" width="238" height="397" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?w=768&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?resize=180%2C300&amp;ssl=1 180w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?resize=614%2C1024&amp;ssl=1 614w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/Screenshot_Lifecycle.png?resize=720%2C1200&amp;ssl=1 720w" sizes="auto, (max-width: 238px) 100vw, 238px" /><figcaption id="caption-attachment-629" class="wp-caption-text">Simple division Activity</figcaption></figure></p>
<p>As you could already realize, you can enter amount of money spent, number of people involved and it will make a simple division operation to split the costs equally. That&#8217;s already kinda costs splitting, right ?! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>I implemented the lifecycle-control methods to check how it really behaves.</p>
<h3>OnCreate</h3>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45611437" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_oncreate-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_OnCreate.cs content, created by dsibinski on 05:54PM on March 11, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_OnCreate.cs">
<tr>
<td id="file-mainactivity_oncreate-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_oncreate-cs-LC1" class="blob-code blob-code-inner js-file-line">protected override void OnCreate(Bundle bundle)</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_oncreate-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_oncreate-cs-LC3" class="blob-code blob-code-inner js-file-line">    base.OnCreate(bundle);</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_oncreate-cs-LC4" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_oncreate-cs-LC5" class="blob-code blob-code-inner js-file-line">    // Set our view from the &quot;main&quot; layout resource</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-mainactivity_oncreate-cs-LC6" class="blob-code blob-code-inner js-file-line">    SetContentView(Resource.Layout.Main);</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-mainactivity_oncreate-cs-LC7" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-mainactivity_oncreate-cs-LC8" class="blob-code blob-code-inner js-file-line">    _amount = 0.00m;</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-mainactivity_oncreate-cs-LC9" class="blob-code blob-code-inner js-file-line">    _result = 0.00m;</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-mainactivity_oncreate-cs-LC10" class="blob-code blob-code-inner js-file-line">    _numberOfPeople = 0;</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-mainactivity_oncreate-cs-LC11" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-mainactivity_oncreate-cs-LC12" class="blob-code blob-code-inner js-file-line">    InitializeUserControls();</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-mainactivity_oncreate-cs-LC13" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
<td id="file-mainactivity_oncreate-cs-LC14" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
<td id="file-mainactivity_oncreate-cs-LC15" class="blob-code blob-code-inner js-file-line">// &#8230;</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
<td id="file-mainactivity_oncreate-cs-LC16" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
<td id="file-mainactivity_oncreate-cs-LC17" class="blob-code blob-code-inner js-file-line">private void InitializeUserControls()</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
<td id="file-mainactivity_oncreate-cs-LC18" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
<td id="file-mainactivity_oncreate-cs-LC19" class="blob-code blob-code-inner js-file-line">    _inputAmount = this.FindViewById&lt;EditText&gt;(Resource.Id.inputAmount);</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
<td id="file-mainactivity_oncreate-cs-LC20" class="blob-code blob-code-inner js-file-line">    _inputNumberOfPeople = this.FindViewById&lt;EditText&gt;(Resource.Id.inputNumberOfPeople);</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
<td id="file-mainactivity_oncreate-cs-LC21" class="blob-code blob-code-inner js-file-line">    _txtResultDecimal = this.FindViewById&lt;EditText&gt;(Resource.Id.txtResultDecimal);</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
<td id="file-mainactivity_oncreate-cs-LC22" class="blob-code blob-code-inner js-file-line">    _btnCalculate = this.FindViewById&lt;Button&gt;(Resource.Id.btnCalculate);</td>
</tr>
<tr>
<td id="file-mainactivity_oncreate-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
<td id="file-mainactivity_oncreate-cs-LC23" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/5ace702ca7109b4f6ae08c35cce9ee84/raw/1fcf175d5220a6938bce340691a4a14e4f1ff391/MainActivity_OnCreate.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/5ace702ca7109b4f6ae08c35cce9ee84#file-mainactivity_oncreate-cs" class="Link--inTextBlock"><br />
          MainActivity_OnCreate.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>Here I only initialize my view from layout, Activity&#8217;s private variables and instantiate user controls. Nothing more for this simple example.</p>
<h3>OnStart</h3>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45611494" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_onstart-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_OnStart.cs content, created by dsibinski on 05:56PM on March 11, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_OnStart.cs">
<tr>
<td id="file-mainactivity_onstart-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_onstart-cs-LC1" class="blob-code blob-code-inner js-file-line">protected override void OnStart()</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_onstart-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_onstart-cs-LC3" class="blob-code blob-code-inner js-file-line">    base.OnStart();</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_onstart-cs-LC4" class="blob-code blob-code-inner js-file-line">    RefreshUserInputsFromVariables();</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_onstart-cs-LC5" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-mainactivity_onstart-cs-LC6" class="blob-code blob-code-inner js-file-line">// &#8230;</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-mainactivity_onstart-cs-LC7" class="blob-code blob-code-inner js-file-line">private void RefreshUserInputsFromVariables()</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-mainactivity_onstart-cs-LC8" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-mainactivity_onstart-cs-LC9" class="blob-code blob-code-inner js-file-line">    _inputAmount.SetText(_amount.ToString(CultureInfo.InvariantCulture), TextView.BufferType.Editable);</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-mainactivity_onstart-cs-LC10" class="blob-code blob-code-inner js-file-line">    _txtResultDecimal.SetText(_result.ToString(CultureInfo.InvariantCulture), TextView.BufferType.Editable);</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-mainactivity_onstart-cs-LC11" class="blob-code blob-code-inner js-file-line">    _inputNumberOfPeople.SetText(_numberOfPeople.ToString(CultureInfo.InvariantCulture),</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-mainactivity_onstart-cs-LC12" class="blob-code blob-code-inner js-file-line">        TextView.BufferType.Editable);</td>
</tr>
<tr>
<td id="file-mainactivity_onstart-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
<td id="file-mainactivity_onstart-cs-LC13" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/f5b27956b31e09db96167eeca264ee8a/raw/27d5ba3b21973ac87435bb671966bfce121567a2/MainActivity_OnStart.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/f5b27956b31e09db96167eeca264ee8a#file-mainactivity_onstart-cs" class="Link--inTextBlock"><br />
          MainActivity_OnStart.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>In <em>OnStart()</em> method I just refresh UI elements &#8211; in that case initialize their <em>Text</em> properties with values stored in private variables.</p>
<h3>OnResume</h3>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45611550" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_onresume-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_OnResume.cs content, created by dsibinski on 05:59PM on March 11, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_OnResume.cs">
<tr>
<td id="file-mainactivity_onresume-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_onresume-cs-LC1" class="blob-code blob-code-inner js-file-line">protected override void OnResume()</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_onresume-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_onresume-cs-LC3" class="blob-code blob-code-inner js-file-line">    base.OnResume();</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_onresume-cs-LC4" class="blob-code blob-code-inner js-file-line">    InitializeUserControlsEvents();</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_onresume-cs-LC5" class="blob-code blob-code-inner js-file-line">    // TODO: retrieving variables (amount, number of people) from persistent storage (file, database)</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-mainactivity_onresume-cs-LC6" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-mainactivity_onresume-cs-LC7" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-mainactivity_onresume-cs-LC8" class="blob-code blob-code-inner js-file-line">// &#8230;</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-mainactivity_onresume-cs-LC9" class="blob-code blob-code-inner js-file-line">private void InitializeUserControlsEvents()</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-mainactivity_onresume-cs-LC10" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-mainactivity_onresume-cs-LC11" class="blob-code blob-code-inner js-file-line">    _btnCalculate.Click += _btnCalculate_Click;</td>
</tr>
<tr>
<td id="file-mainactivity_onresume-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
<td id="file-mainactivity_onresume-cs-LC12" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/543cdbccbb0e28c144d15548db8b9e6f/raw/479a1e85703fa5680d62daee5acbd2187da89e76/MainActivity_OnResume.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/543cdbccbb0e28c144d15548db8b9e6f#file-mainactivity_onresume-cs" class="Link--inTextBlock"><br />
          MainActivity_OnResume.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>As we know, <em>OnResume</em> method is called every time our Activity is brought to the top of Activities stack (either after <em>OnCreate -&gt; OnStart</em> or when revealing it after being backgrounded). That&#8217;s a very good place to initialize dependencies to external services (e.g. open communication with DB or remote service). In my case, I just subscribed to <em>Click</em> events of the button. If I had any persistent storage present (for instance local DB) I would in this place retrieve recently saved values from it to my Activity&#8217;s variables to restore its state (<em>OnResume</em> might be called when Activity class&#8217;s state is already cleaned up).</p>
<h3>OnPause</h3>
<p><style>.gist table { margin-bottom: 0; }</style>
<div style="tab-size: 8" id="gist45611682" class="gist">
<div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
<div class="gist-data">
<div class="js-gist-file-update-container js-task-list-container">
<div id="file-mainactivity_onpause-cs" class="file my-2">
<div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="MainActivity_OnPause.cs content, created by dsibinski on 06:05PM on March 11, 2017."
    ></p>
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">
<p>  <template class="js-file-alert-template"></p>
<div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
    <span><br />
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br />
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a><br />
    </span></p>
<div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters<br />
</a>
</div>
</div>
<p></template><br />
<template class="js-line-alert-template"><br />
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e"><br />
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg><br />
</span></template></p>
<table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="MainActivity_OnPause.cs">
<tr>
<td id="file-mainactivity_onpause-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
<td id="file-mainactivity_onpause-cs-LC1" class="blob-code blob-code-inner js-file-line">protected override void OnPause()</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
<td id="file-mainactivity_onpause-cs-LC2" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
<td id="file-mainactivity_onpause-cs-LC3" class="blob-code blob-code-inner js-file-line">    base.OnPause();</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
<td id="file-mainactivity_onpause-cs-LC4" class="blob-code blob-code-inner js-file-line">    DetatchUserControlsEvents();</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
<td id="file-mainactivity_onpause-cs-LC5" class="blob-code blob-code-inner js-file-line">    // TODO: saving variables (amount, number of people) to persistent storage (file, database)</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
<td id="file-mainactivity_onpause-cs-LC6" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
<td id="file-mainactivity_onpause-cs-LC7" class="blob-code blob-code-inner js-file-line">// &#8230;</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
<td id="file-mainactivity_onpause-cs-LC8" class="blob-code blob-code-inner js-file-line">private void DetatchUserControlsEvents()</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
<td id="file-mainactivity_onpause-cs-LC9" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
<td id="file-mainactivity_onpause-cs-LC10" class="blob-code blob-code-inner js-file-line">    _btnCalculate.Click -= _btnCalculate_Click;</td>
</tr>
<tr>
<td id="file-mainactivity_onpause-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
<td id="file-mainactivity_onpause-cs-LC11" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</table>
</div></div>
</p></div>
</div></div>
<div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/3c2715968ecf87822ee6f79a46a553ac/raw/7002c8439f39510b30d5a7c4d7a2a60a085d4a98/MainActivity_OnPause.cs" style="float:right" class="Link--inTextBlock">view raw</a><br />
        <a href="https://gist.github.com/dsibinski/3c2715968ecf87822ee6f79a46a553ac#file-mainactivity_onpause-cs" class="Link--inTextBlock"><br />
          MainActivity_OnPause.cs<br />
        </a><br />
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
</p></div>
</div>
<p>In <em>OnPause</em> method I need to be consistent with what I do in <em>OnResume</em> &#8211; when my app is taken to the background, I don&#8217;t need to wait for my button&#8217;s click events anymore, so let&#8217;s detach from it (maybe button&#8217;s <em>Click</em> event is not the best example here, but it&#8217;s just to visualize the purpose of the method). When my app is <em>resumed</em>, we will subscribe to this event again. Again, if I had any persistent storage, I&#8217;d save all variables&#8217; (which are necessary for restoring Activity&#8217;s state) values here to this storage, so they are able to be retrieved back as soon as <em>OnResume</em> is called.</p>
<h3>OnStop &amp; OnDestroy</h3>
<p>I didn&#8217;t implement those two methods in my app, it&#8217;s too simple to need anything in those places.</p>
<p>I deployed the app, attached with debugger and checked the order of methods&#8217; calls &#8211; all of them were called as described in previous paragraph.</p>
<h2>Summary</h2>
<p>It&#8217;s vital to understand how Android Activities and their states work. Even though it seems to be Android-specific, I&#8217;d rather say such approach is reasonable and even required by hardware on which mobile apps run (BTW, <a href="https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/high_level_flow_2x.png" target="_blank" rel="noopener">similar states seem to exist in iOS apps</a>).</p>
<p>When building Android app we need to think about Activities, especially make sure that each Activity in our application properly implements necessary lifecycle methods.</p>
<p><em><span style="text-decoration: underline;"><strong>Do you have or know any best practices while working with Activities and managing their lifecycle?</strong></span></em> I&#8217;d appreciate if you share it in the comments <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.codejourney.net/xamarin-android-activities/">Xamarin – Android Activities</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/xamarin-android-activities/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">405</post-id>	</item>
		<item>
		<title>Hello Xamarin World &#8211; first steps</title>
		<link>https://www.codejourney.net/hello-xamarin-world-first-steps/</link>
					<comments>https://www.codejourney.net/hello-xamarin-world-first-steps/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 04 Mar 2017 23:12:14 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dajsiepoznac2017]]></category>
		<category><![CDATA[xamarin]]></category>
		<guid isPermaLink="false">http://www.dsibinski.pl/?p=244</guid>

					<description><![CDATA[<p>This time I want to say “Hello” to Xamarin world. First thing that needs to be done before starting Xamarin development, is obviously the installation of all necessary components. In this post I want to share my feelings about the installation (not without issues of course), configuration of my Xamarin Android solution and deployment process to&#8230;</p>
<p>The post <a href="https://www.codejourney.net/hello-xamarin-world-first-steps/">Hello Xamarin World &#8211; first steps</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p style="text-align: left;">This time I want to say “Hello” to Xamarin world.</p>
<p style="text-align: left;">First thing that needs to be done before starting Xamarin development, is obviously the installation of all necessary components.</p>
<p style="text-align: left;">In this post I want to share my feelings about the installation (not without issues of course), configuration of my Xamarin Android solution and deployment process to the device.<br />
<span id="more-244"></span></p>
<h2>Xamarin installation into Visual Studio 2015</h2>
<p style="text-align: left;">I’ve created my account at <a href="http://www.xamarin.com/" target="_blank" rel="noopener">xamarin.com</a>, logged in and chose <em>Download Xamarin for free</em> to download the installation package. There are generally two IDEs that can be used for Xamarin development: Visual Studio or Xamarin Studio. I’ve already had VS 2015 installed and decided I don’t want to explore a new IDE, so I downloaded installer for Visual Studio. What’s more, following Xamarin’s website, “Xamarin Studio is no longer included” in the Windows installer and they “encourage Windows developers to move to Visual Studio”. Well, that&#8217;s understandable, Microsoft acquired Xamarin, didn&#8217;t they? 😉</p>
<p style="text-align: left;"><em>BTW, when <a href="https://www.xamarin.com/download" target="_blank" rel="noopener">downloading Xamarin</a> I was obliged to fill the “Company” field – does anyone know why is that?</em></p>
<h2 style="text-align: left;"> Android SDK and emulator images size</h2>
<p style="text-align: left;">Interesting parts of the installation (if there could by any at all?) are Android Emulator installation which is then integrated into Visual Studio as well as Android SDK installation – fortunately it’s possible to change the location of Android SDK installation, because right after the setup it takes an enormous amount of disk space (with mandatory tools mentioned in the installation guide and two Android APIs):</p>
<p><figure id="attachment_323" aria-describedby="caption-attachment-323" style="width: 300px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?ssl=1" target="_blank" rel="noopener"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="323" data-permalink="https://www.codejourney.net/hello-xamarin-world-first-steps/android_sdk_size/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?fit=348%2C243&amp;ssl=1" data-orig-size="348,243" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="android_sdk_size" data-image-description="&lt;p&gt;Android SDK size&lt;/p&gt;
" data-image-caption="&lt;p&gt;Android SDK size&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?fit=300%2C209&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?fit=348%2C243&amp;ssl=1" class="wp-image-323 size-medium" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?resize=300%2C209&#038;ssl=1" alt="Android SDK size - 41.6 GBs" width="300" height="209" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?resize=300%2C209&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/android_sdk_size.png?w=348&amp;ssl=1 348w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-323" class="wp-caption-text"><span style="font-size: 8pt;">Android SDK size</span></figcaption></figure></p>
<p style="text-align: left;">I’ve examined a bit more and it turns out that <strong>system images</strong> take the most of this space. Those are used only by emulators to be able to create a virtual device and debug on a simulator instead of deploying the app to a physical device every rime.</p>
<p style="text-align: left;">When I used to write some Android apps in Java and Android Studio long time ago, I found it very hard and complex to debug/test anything using emulator – it was simply very, very slow to load and work. This time I&#8217;ll see if emulator built in Visual Studio will do the job – if yes, why not using it ? I will of course also deploy directly to the device for tests, but it also takes time. I remember that when I wanted to test some small adjustments done “on the fly” (e.g. UI modifications/alignments) I dreamt about doing it quicker then deploying app to the phone every time. We’ll see, if emulator won’t do the job – I will clean up those folders.</p>
<h2 style="text-align: left;"> First issue in DSP</h2>
<p style="text-align: left;">I had to create a separate paragraph for that 🙂 Of course, it must have finally happened – first issue on my DSP way! Installation error, of course &#8211; <em>&#8220;Installation of &#8216;Xamarin&#8217; failed with more then one exception (attempt 3). It was not possible to complete an automatic installation.&#8221;</p>
<p></em></p>
<p style="text-align: left;">I expected the installation to terminate and evening spent on looking for a solution, exploring StackOverflow threads, but to my surprise a quite familiar-looking screen appeared explaining what to do next, i.e. how to install all the components manually. I had to download and install Java JDK, Android SDK and Xamarin.</p>
<p style="text-align: left;">After the next 30 minutes everything seemed to be installed. Just two last configuration steps in Visual Studio <a href="https://developer.xamarin.com/guides/android/getting_started/installation/windows/manual_installation/" target="_blank" rel="noopener">as described here.</a> Finally, to be able to run Android emulator Android Virtual Device Manager needs to be configured, <a href="https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/debug-on-emulator/android-sdk-emulator/#Configuring_Virtual_Devices" target="_blank" rel="noopener">as this tutorial describes</a>.</p>
<h2 style="text-align: left;">Android Solution Creation</h2>
<p style="text-align: left;">I cloned my <a href="https://github.com/dsibinski/MoneyBack" target="_blank" rel="noopener">Git repository</a>, opened Visual Studio and created <em>MoneyBack</em> solution 😉 I chose the project of type <em>Blank App (Android). </em>Here’s what VS produced:</p>
<p><figure id="attachment_358" aria-describedby="caption-attachment-358" style="width: 207px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?ssl=1"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="358" data-permalink="https://www.codejourney.net/hello-xamarin-world-first-steps/vs_android_xamarin_solution/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?fit=202%2C310&amp;ssl=1" data-orig-size="202,310" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="VS_Android_Xamarin_Solution" data-image-description="&lt;p&gt;VS Android Xamarin Solution&lt;/p&gt;
" data-image-caption="&lt;p&gt;VS Android Xamarin Solution&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?fit=195%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?fit=202%2C310&amp;ssl=1" class=" wp-image-358" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?resize=207%2C318&#038;ssl=1" alt="VS Android Xamarin Solution" width="207" height="318" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?resize=195%2C300&amp;ssl=1 195w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/VS_Android_Xamarin_Solution.png?w=202&amp;ssl=1 202w" sizes="auto, (max-width: 207px) 100vw, 207px" /></a><figcaption id="caption-attachment-358" class="wp-caption-text"><span style="font-size: 8pt;">VS Android Xamarin Solution</span></figcaption></figure></p>
<p style="text-align: left;">Android Xamarin solution contains the following elements out-of-the-box:</p>
<ul>
<li><em>Properties<b> </b></em>– here <em>AssemblyInfo.cs</em> is probably well-known to all .NET developers (for the others: this file is .NET assembly’s metadata file, containing basic data about our application, like its name, version, company etc.), but there is also <em>AndroidManifest.xml, </em>which contains details and requirements for Android application, e.g. app’s name, supported SDKs versions numbers and required permissions for which the end user is asked when installing the app</li>
<li><em>References</em> – contains other assemblies required for the application to build; in case of Xamarin Android solution, it references both .NET assemblies like <em>System</em> or <em>System.Core</em> and <em>Mono.Android </em>assembly</li>
<li><em>Components</em> – stores Xamarin development packages that can be retrieved from <a href="https://components.xamarin.com/" target="_blank" rel="noopener">Components Store</a> (something like Xamarin-specific <em>Nuget</em>, I guess 😉 )</li>
<li><em>Assets</em> – allows to store additional files needed by the app (e.g. text files) available easily from the code</li>
<li><em>Resources</em><strong> – </strong>contains strings, images and layouts of the application</li>
</ul>
<h2>MainActivity</h2>
<p style="text-align: left;">Apart from above-mentioned folders, solution contains an <em>Activity </em>class (<em>MainActivity.cs</em>) which is decorated with <em>ActivityAttribute</em>:</p>
<pre><pre class="brush: csharp; title: ; notranslate">&#x5B;Activity(Label = &quot;MoneyBack&quot;, MainLauncher = true, Icon = &quot;@drawable/icon&quot;)]</pre>
<p style="text-align: left;">We&#8217;ll get into details of <em>activities</em> soon. For now, let&#8217;s just assume that:</p>
<pre><pre class="brush: csharp; title: ; notranslate">MainLauncher = true</pre>
<p style="text-align: left;">means that this class is the starting point of the application. It contains only one method:</p>
<pre><pre class="brush: csharp; title: ; notranslate">
protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);

   // Set our view from the &quot;main&quot; layout resource
   SetContentView (Resource.Layout.Main);

}</pre>
<p style="text-align: left;">Again, we’ll dive into <a href="https://developer.xamarin.com/guides/android/application_fundamentals/activity_lifecycle/" target="_blank" rel="noopener">Android activity’s lifecycle</a> very soon, but we can already imagine that “OnCreate” method is called when the activity is created.</p>
<h2>MoneyBack on the phone</h2>
<p style="text-align: left;">I plugged my Huawei P8 to the laptop, hit F5 and hoped to see my app running on the device. Instead, two components were installed first as separate apps &#8211; <em>Mono Shared Runtime</em> and <em>Xamarin.Android API-25</em>. Those two are used in debug build mode to allow debugging stuff. It would be fine if I didn&#8217;t have to re-plug my phone after installation of each of these two, as phone was doing nothing after.</p>
<p style="text-align: left;"> Finally,  <em>MoneyBack</em> appeared on Huawei&#8217;s screen with sad, black empty canvas. I added some well-known sentence to become a real Xamarin-newbie:</p>
<p><figure id="attachment_384" aria-describedby="caption-attachment-384" style="width: 182px" class="wp-caption aligncenter"><a href="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?ssl=1" target="_blank" rel="noopener"><img data-recalc-dims="1" loading="lazy" decoding="async" data-attachment-id="384" data-permalink="https://www.codejourney.net/hello-xamarin-world-first-steps/moneyback_helloworld_xamarin/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?fit=201%2C354&amp;ssl=1" data-orig-size="201,354" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="MoneyBack_HelloWorld_Xamarin" data-image-description="&lt;p&gt;MoneyBack &amp;#8211; Hello world deployed to the phone&lt;/p&gt;
" data-image-caption="&lt;p&gt;MoneyBack &amp;#8211; Hello world deployed to the phone&lt;/p&gt;
" data-medium-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?fit=170%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?fit=201%2C354&amp;ssl=1" class="wp-image-384" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?resize=182%2C321&#038;ssl=1" alt="MoneyBack - Hello world deployed to the phone" width="182" height="321" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?resize=170%2C300&amp;ssl=1 170w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2017/03/MoneyBack_HelloWorld_Xamarin.png?w=201&amp;ssl=1 201w" sizes="auto, (max-width: 182px) 100vw, 182px" /></a><figcaption id="caption-attachment-384" class="wp-caption-text"><span style="font-size: 8pt;">MoneyBack &#8211; Hello world deployed to the phone</span></figcaption></figure></p>
<h2>MoneyBack on the emulator</h2>
<p style="text-align: left;">I couldn’t initially manage to deploy my application to Android Emulator device. I tried creating few emulator devices – firstly I had issues with very strange resolution on the emulated device, then I created another one and when I tried to deploy on it I got an error saying “2&gt;Emulator is not ready to be used”. What I came up to is creating new Android Emulator Device, trying to start it (without deployment) and having “android” text on the device’s screen for the last 20 minutes. Then I found <a href="https://developer.xamarin.com/guides/android/getting_started/installation/accelerating_android_emulators/" target="_blank" rel="noopener">this emulation acceleration guide</a>, so I installed HAXM and it helped <strong>A LOT</strong>. Emulator is now starting within 30 seconds and I managed to deploy my app on it. Cool.</p>
<h2 style="text-align: left;">Summary</h2>
<p style="text-align: left;">Automatic installation of Xamarin on Windows with Visual Studio didn’t work, so I had to install all the packages manually, however it wasn’t problematic. Deployment to the phone was OK, but the installation of two additional components (<em>Mono Shared Runtime</em> and <em>Xamarin.Android API</em>) forced me to re-plug the device twice. I hope I won’t have this case very often, because if every deployment looks like that I’ll never finish this app…</p>
<p style="text-align: left;">I recommend everyone who wants to work with Android device emulator <a href="https://developer.xamarin.com/guides/android/getting_started/installation/accelerating_android_emulators/" target="_blank" rel="noopener">installing HAXM</a> &#8211; it really boosts the emulation.</p>
<div class="post">
<div class="body">
<div id="c4c4c9b5-cfa2-4848-a5d1-af794b4279f7" class="postBody" style="margin: 4px 0px 0px; border-width: 0px; padding: 0px;" contenteditable="true">
<p style="text-align: left;">Get ready for a deep dive into Xamarin soon 😎</p>
</div>
</div>
</div>
<p>&nbsp;</p>
<p>The post <a href="https://www.codejourney.net/hello-xamarin-world-first-steps/">Hello Xamarin World &#8211; first steps</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/hello-xamarin-world-first-steps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">244</post-id>	</item>
	</channel>
</rss>
