SlideShare a Scribd company logo
1 of 37
Download to read offline
Jérémie Laval
Happy Hacker
Xamarin
jeremie.laval@xamarin.com
Tips & Tricks to Spice Up
Your Android App
Spice-Up Tricks
ListView Tricks
Why ListView? Ubiquity.
Why ListView? Ubiquity.
Why ListView? Ubiquity.
Why ListView? Ubiquity.
From Basic ListView…
Boring
… to Complete App
Let’s Build This
Breaking Things Up
1. The Basics
Loading and data fetching
2. The Pretty
Improving the look and feel
3. The Gimmick
Spicing up the result
The Basics
DEMO
ListFragment Customization
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
ListFragment Customization
<?xml	
  version="1.0"	
  encoding="utf-­‐8"?>
<LinearLayout	
  xmlns:android="http://schemas.android.com/apk/res/android"
	
  	
  	
  	
  android:orientation="vertical"
	
  	
  	
  	
  android:layout_width="fill_parent"
	
  	
  	
  	
  android:layout_height="fill_parent">
	
  	
  	
  	
  <LinearLayout
	
  	
  	
  	
  	
  	
  	
  	
  android:orientation="horizontal"
	
  	
  	
  	
  	
  	
  	
  	
  android:id="@id/android:empty">
	
  	
  	
  	
  	
  	
  	
  	
  <ProgressBar	
  />
	
  	
  	
  	
  	
  	
  	
  	
  <TextView	
  android:text="Loading..."	
  />
	
  	
  	
  	
  </LinearLayout>
	
  	
  	
  	
  <ListView
	
  	
  	
  	
  	
  	
  	
  	
  android:id="@id/android:list"
	
  	
  	
  	
  	
  	
  	
  	
  android:layout_weight="1"	
  />
</LinearLayout
...
LulzDog
LulzCat
...
...
Warning! Async Loading
request
callback
01
02
03
04
05
06
07
08
09
10
11
12
13
14
Async Loading
public	
  override	
  View	
  GetView	
  (int	
  position,	
  View	
  convertView,	
  ViewGroup	
  parent)
{
	
   MyCustomView	
  view	
  =	
  EnsureView	
  (convertView);
	
   var	
  versionNumber	
  =	
  Interlocked.Increment	
  (ref	
  view.VersionNumber);
	
   var	
  item	
  =	
  events	
  [position];
	
   var	
  avatarView	
  =	
  view.FindViewById<ImageView>	
  (...);
	
   avatarView.SetImageDrawable	
  (EmptyAvatarDrawable);
	
   FetchAvatar	
  (view,	
  avatarView,	
  item,	
  versionNumber);
	
   return	
  view;
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
Async Loading (cont)
var	
  imageCache	
  =	
  new	
  ConcurrentDictionary<string,	
  Task<Bitmap>>	
  ();
void	
  FetchAvatar	
  (...	
  view,	
  ...	
  avatarView,	
  string	
  url,	
  long	
  versionNumber)
{
	
   var	
  bmp	
  =	
  imageCache.GetOrAdd	
  (url,	
  u	
  =>	
  Task.Run	
  (()	
  =>	
  DownloadData	
  (u)));
	
   if	
  (bmp.IsCompleted	
  &&	
  bmp.Result	
  !=	
  null)
	
   	
   avatarView.SetImage	
  (bmp.Result);
	
   else
	
   	
   bmp.ContinueWith	
  (t	
  =>	
  {
	
   	
   	
   if	
  (view.VersionNumber	
  ==	
  versionNumber	
  &&	
  t.Result	
  !=	
  null)
	
   	
   	
   	
   handler.Post	
  (()	
  =>	
  {
	
   	
   	
   	
   	
   if	
  (view.VersionNumber	
  ==	
  versionNumber)
	
   	
   	
   	
   	
   	
   avatarView.SetImageAnimated	
  (t.Result);
	
   	
   	
   	
   });
	
   	
   });
}
The Pretty
DEMO
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
Prettify Your List Items
<?xml	
  version="1.0"	
  encoding="utf-­‐8"?>
<shape	
  xmlns:android="http://schemas.android.com/apk/res/android"
	
  	
  	
  	
  	
  	
  	
  android:shape="rectangle">
	
  	
  	
  	
  <corners	
  android:radius="3dp"	
  />
	
  	
  	
  	
  <gradient
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:startColor="@android:color/transparent"
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:endColor="#10000000"
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:type="linear"
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:centerColor="@android:color/transparent"
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:centerY="0.8"
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:angle="270"	
  />
	
  	
  	
  	
  <stroke
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:width="1dp"
	
  	
  	
  	
  	
   	
  	
  	
  	
  android:color="#D0D0D0"	
  />
</shape>
Prettify Your List Items
<FrameLayout	
  android:background="@drawable/list_item_box"	
  />
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
Custom Drawable
public	
  class	
  RoundCornersDrawable	
  :	
  Drawable
{
	
   	
  public	
  RoundCornersDrawable	
  (Bitmap	
  bitmap,	
  float	
  cornerRadius	
  =	
  5)
	
   	
  {
	
   	
   	
  	
  this.cornerRadius	
  =	
  cornerRadius;
	
   	
   	
  	
  this.paint	
  =	
  new	
  Paint	
  ()	
  {	
  AntiAlias	
  =	
  true	
  };
	
   	
   	
  	
  var	
  tileMode	
  =	
  Shader.TileMode.Clamp;
	
   	
   	
  	
  paint.SetShader	
  (new	
  BitmapShader	
  (bitmap,	
  tileMode,	
  tileMode));
	
   	
  }
	
   	
  public	
  override	
  void	
  Draw	
  (Canvas	
  canvas)
	
   	
  {
	
   	
   	
  	
  canvas.DrawRoundRect	
  (rect,	
  cornerRadius,	
  cornerRadius,	
  paint);
	
   	
  }
}
Custom Drawable
imageView.SetImageDrawable	
  (new	
  RoundCornersDrawable	
  (glacierBmp,	
  cornerRadius:	
  10))
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Easy Inset Effects
<TextView
	
  	
  	
  	
  android:text="White-­‐based	
  inset"
	
  	
  	
  	
  android:shadowColor="@android:color/white"
	
  	
  	
  	
  android:shadowDx="1"
	
  	
  	
  	
  android:shadowDy="1"
	
  	
  	
  	
  android:shadowRadius="0.1"	
  />
<TextView
	
  	
  	
  	
  android:text="Black-­‐based	
  inset"
	
  	
  	
  	
  android:shadowColor="@android:color/black"
	
  	
  	
  	
  android:shadowDx="-­‐1"
	
  	
  	
  	
  android:shadowDy="-­‐1"
	
  	
  	
  	
  android:shadowRadius="0.1"	
  />
Easy Inset Effects
The Gimmick
The Animated Stuff
“The best animations are the ones your users
don’t notice because they feel natural”
- Jérémie Laval
“The best animations are the ones your users
don’t notice because they feel natural”
01
02
03
04
05
06
07
08
09
10
11
12
13
14
Fade ImageView
public	
  static	
  class	
  ImageViewExtensions
{
	
   	
  public	
  static	
  void	
  SetImageDrawableAnimated	
  (this	
  ImageView	
  view,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Drawable	
  drawable)
	
   	
  {
	
   	
   	
  	
  var	
  lng	
  =	
  view.Resources.GetInteger	
  (ConfigLongAnimTime);
	
   	
   	
  	
  var	
  med	
  =	
  view.Resources.GetInteger	
  (ConfigMediumAnimTime);
	
   	
   	
  	
  view.Animate	
  ().Alpha	
  (0).SetDuration	
  (med).WithEndAction	
  (()	
  =>	
  {
	
   	
   	
   	
  	
  	
  view.SetImageDrawable	
  (drawable);
	
   	
   	
   	
  	
  	
  view.Animate	
  ().Alpha	
  (1).SetDuration	
  (lng);
	
   	
   	
  	
  });
	
   	
  }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
ListView Item Animations
public	
  override	
  View	
  GetView	
  (int	
  position,	
  View	
  convertView,	
  ViewGroup	
  parent)
{
	
   var	
  view	
  =	
  EnsureView	
  (convertView);
	
   var	
  item	
  =	
  events	
  [position];
	
   if	
  (!item.Consumed)	
  {
	
   	
   item.Consumed	
  =	
  true;
	
   	
   var	
  animation	
  =	
  AnimationUtils.MakeInChildBottomAnimation	
  (context);
	
   	
   view.StartAnimation	
  (animation);
	
   }
	
   return	
  view;
}
01
02
03
04
05
06
07
08
09
10
11
12
13
Automatic Layout Transitions
<LinearLayout
	
  	
  	
  	
  android:orientation="vertical"
	
  	
  	
  	
  android:id="@+id/AnimatedLayout"
	
  	
  	
  	
  android:animateLayoutChanges="true"
	
  	
  	
  	
  android:minHeight="49dp"
	
  	
  	
  	
  android:layout_height="wrap_content">
	
  	
  	
  	
  <LinearLayout	
  android:id="@+id/PresentationLayout"	
  />
	
  	
  	
  	
  <LinearLayout	
  android:id="@+id/ActionLayout"
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  android:layout_height="1px"	
  />
</LinearLayout>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
Automatic Layout Transitions
if	
  (presentationLayout.Visibility	
  ==	
  ViewStates.Gone)	
  {
	
   presentationLayout.Visibility	
  =	
  ViewStates.Visible;
	
   var	
  lp	
  =	
  new	
  LayoutParams	
  (actionLayout.LayoutParameters)	
  {
	
   	
   Height	
  =	
  1
	
   };
	
   actionLayout.LayoutParameters	
  =	
  lp;
}	
  else	
  {
	
   var	
  lp	
  =	
  new	
  LayoutParams	
  (actionLayout.LayoutParameters)	
  {
	
   	
   Height	
  =	
  ViewGroup.LayoutParams.WrapContent,
	
   	
   Gravity	
  =	
  GravityFlags.Center
	
   };
	
   actionLayout.LayoutParameters	
  =	
  lp;
	
   presentationLayout.Visibility	
  =	
  ViewStates.Gone;
}
Last Call
developers.android.com/design
A worthy read for every app developer
Thanks!
/garuma/EvolveDemo

More Related Content

What's hot

Daniel Jalkut - dotSwift 2019
Daniel Jalkut - dotSwift 2019Daniel Jalkut - dotSwift 2019
Daniel Jalkut - dotSwift 2019DanielJalkut
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJSJacopo Nardiello
 
Introduction to WebGL and WebVR
Introduction to WebGL and WebVRIntroduction to WebGL and WebVR
Introduction to WebGL and WebVRDaosheng Mu
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material DesignYasin Yildirim
 
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCsStandford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs彼得潘 Pan
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functionsYan Cui
 
jQuery for Beginners
jQuery for Beginners jQuery for Beginners
jQuery for Beginners NAILBITER
 
Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...
Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...
Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...彼得潘 Pan
 
A frame beginner lesson
A frame beginner lessonA frame beginner lesson
A frame beginner lessonDaosheng Mu
 
How to build a html5 websites.v1
How to build a html5 websites.v1How to build a html5 websites.v1
How to build a html5 websites.v1Bitla Software
 

What's hot (11)

Daniel Jalkut - dotSwift 2019
Daniel Jalkut - dotSwift 2019Daniel Jalkut - dotSwift 2019
Daniel Jalkut - dotSwift 2019
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJS
 
Introduction to WebGL and WebVR
Introduction to WebGL and WebVRIntroduction to WebGL and WebVR
Introduction to WebGL and WebVR
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material Design
 
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCsStandford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
Standford 2015 week4: 1.Protocols and Delegation, Gestures 2. Multiple MVCs
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functions
 
jQuery for Beginners
jQuery for Beginners jQuery for Beginners
jQuery for Beginners
 
Angular animate
Angular animateAngular animate
Angular animate
 
Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...
Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...
Standford 2015 week7: 1. Unwind Segues, Alerts, Timers, View Animation 2. Dyn...
 
A frame beginner lesson
A frame beginner lessonA frame beginner lesson
A frame beginner lesson
 
How to build a html5 websites.v1
How to build a html5 websites.v1How to build a html5 websites.v1
How to build a html5 websites.v1
 

Similar to Tips & Tricks to spice up your Android app

Material design basics
Material design basicsMaterial design basics
Material design basicsJorge Barroso
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in androidInnovationM
 
Advance Android application development workshop day 2
Advance Android application development workshop day 2Advance Android application development workshop day 2
Advance Android application development workshop day 2cresco
 
ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]Somkiat Khitwongwattana
 
Constraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleConstraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleDroidConTLV
 
Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015
Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015
Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015Mathias Seguy
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)Mathias Seguy
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談awonwon
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basicsAnton Narusberg
 
Advanced Android gReporter
Advanced Android gReporterAdvanced Android gReporter
Advanced Android gReporternatdefreitas
 
06. Android Basic Widget and Container
06. Android Basic Widget and Container06. Android Basic Widget and Container
06. Android Basic Widget and ContainerOum Saokosal
 
android level 3
android level 3android level 3
android level 3DevMix
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Mario Jorge Pereira
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Robert DeLuca
 
android layouts
android layoutsandroid layouts
android layoutsDeepa Rani
 
Android Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docxAndroid Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docxamrit47
 

Similar to Tips & Tricks to spice up your Android app (20)

Chapter 5 - Layouts
Chapter 5 - LayoutsChapter 5 - Layouts
Chapter 5 - Layouts
 
Material design basics
Material design basicsMaterial design basics
Material design basics
 
How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
 
Svcc 2013-d3
Svcc 2013-d3Svcc 2013-d3
Svcc 2013-d3
 
Advance Android application development workshop day 2
Advance Android application development workshop day 2Advance Android application development workshop day 2
Advance Android application development workshop day 2
 
ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]
 
Constraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleConstraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, Google
 
Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015
Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015
Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
Layouts in android
Layouts in androidLayouts in android
Layouts in android
 
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
Animate Me, if you don't do it for me do it for chet (DroidCon Paris)
 
Data binding 入門淺談
Data binding 入門淺談Data binding 入門淺談
Data binding 入門淺談
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
Advanced Android gReporter
Advanced Android gReporterAdvanced Android gReporter
Advanced Android gReporter
 
06. Android Basic Widget and Container
06. Android Basic Widget and Container06. Android Basic Widget and Container
06. Android Basic Widget and Container
 
android level 3
android level 3android level 3
android level 3
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
android layouts
android layoutsandroid layouts
android layouts
 
Android Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docxAndroid Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docx
 

Recently uploaded

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsAndrey Dotsenko
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 

Recently uploaded (20)

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 

Tips & Tricks to spice up your Android app

  • 11. Breaking Things Up 1. The Basics Loading and data fetching 2. The Pretty Improving the look and feel 3. The Gimmick Spicing up the result
  • 13. DEMO
  • 15. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 ListFragment Customization <?xml  version="1.0"  encoding="utf-­‐8"?> <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"        android:orientation="vertical"        android:layout_width="fill_parent"        android:layout_height="fill_parent">        <LinearLayout                android:orientation="horizontal"                android:id="@id/android:empty">                <ProgressBar  />                <TextView  android:text="Loading..."  />        </LinearLayout>        <ListView                android:id="@id/android:list"                android:layout_weight="1"  /> </LinearLayout
  • 17. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 Async Loading public  override  View  GetView  (int  position,  View  convertView,  ViewGroup  parent) {   MyCustomView  view  =  EnsureView  (convertView);   var  versionNumber  =  Interlocked.Increment  (ref  view.VersionNumber);   var  item  =  events  [position];   var  avatarView  =  view.FindViewById<ImageView>  (...);   avatarView.SetImageDrawable  (EmptyAvatarDrawable);   FetchAvatar  (view,  avatarView,  item,  versionNumber);   return  view; }
  • 18. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 Async Loading (cont) var  imageCache  =  new  ConcurrentDictionary<string,  Task<Bitmap>>  (); void  FetchAvatar  (...  view,  ...  avatarView,  string  url,  long  versionNumber) {   var  bmp  =  imageCache.GetOrAdd  (url,  u  =>  Task.Run  (()  =>  DownloadData  (u)));   if  (bmp.IsCompleted  &&  bmp.Result  !=  null)     avatarView.SetImage  (bmp.Result);   else     bmp.ContinueWith  (t  =>  {       if  (view.VersionNumber  ==  versionNumber  &&  t.Result  !=  null)         handler.Post  (()  =>  {           if  (view.VersionNumber  ==  versionNumber)             avatarView.SetImageAnimated  (t.Result);         });     }); }
  • 20. DEMO
  • 21. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 Prettify Your List Items <?xml  version="1.0"  encoding="utf-­‐8"?> <shape  xmlns:android="http://schemas.android.com/apk/res/android"              android:shape="rectangle">        <corners  android:radius="3dp"  />        <gradient                  android:startColor="@android:color/transparent"                  android:endColor="#10000000"                  android:type="linear"                  android:centerColor="@android:color/transparent"                  android:centerY="0.8"                  android:angle="270"  />        <stroke                  android:width="1dp"                  android:color="#D0D0D0"  /> </shape>
  • 22. Prettify Your List Items <FrameLayout  android:background="@drawable/list_item_box"  />
  • 23. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 Custom Drawable public  class  RoundCornersDrawable  :  Drawable {    public  RoundCornersDrawable  (Bitmap  bitmap,  float  cornerRadius  =  5)    {        this.cornerRadius  =  cornerRadius;        this.paint  =  new  Paint  ()  {  AntiAlias  =  true  };        var  tileMode  =  Shader.TileMode.Clamp;        paint.SetShader  (new  BitmapShader  (bitmap,  tileMode,  tileMode));    }    public  override  void  Draw  (Canvas  canvas)    {        canvas.DrawRoundRect  (rect,  cornerRadius,  cornerRadius,  paint);    } }
  • 24. Custom Drawable imageView.SetImageDrawable  (new  RoundCornersDrawable  (glacierBmp,  cornerRadius:  10))
  • 25. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 Easy Inset Effects <TextView        android:text="White-­‐based  inset"        android:shadowColor="@android:color/white"        android:shadowDx="1"        android:shadowDy="1"        android:shadowRadius="0.1"  /> <TextView        android:text="Black-­‐based  inset"        android:shadowColor="@android:color/black"        android:shadowDx="-­‐1"        android:shadowDy="-­‐1"        android:shadowRadius="0.1"  />
  • 29. “The best animations are the ones your users don’t notice because they feel natural”
  • 30. - Jérémie Laval “The best animations are the ones your users don’t notice because they feel natural”
  • 31. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 Fade ImageView public  static  class  ImageViewExtensions {    public  static  void  SetImageDrawableAnimated  (this  ImageView  view,                                                                                                  Drawable  drawable)    {        var  lng  =  view.Resources.GetInteger  (ConfigLongAnimTime);        var  med  =  view.Resources.GetInteger  (ConfigMediumAnimTime);        view.Animate  ().Alpha  (0).SetDuration  (med).WithEndAction  (()  =>  {            view.SetImageDrawable  (drawable);            view.Animate  ().Alpha  (1).SetDuration  (lng);        });    } }
  • 32. 01 02 03 04 05 06 07 08 09 10 11 12 13 ListView Item Animations public  override  View  GetView  (int  position,  View  convertView,  ViewGroup  parent) {   var  view  =  EnsureView  (convertView);   var  item  =  events  [position];   if  (!item.Consumed)  {     item.Consumed  =  true;     var  animation  =  AnimationUtils.MakeInChildBottomAnimation  (context);     view.StartAnimation  (animation);   }   return  view; }
  • 33. 01 02 03 04 05 06 07 08 09 10 11 12 13 Automatic Layout Transitions <LinearLayout        android:orientation="vertical"        android:id="@+id/AnimatedLayout"        android:animateLayoutChanges="true"        android:minHeight="49dp"        android:layout_height="wrap_content">        <LinearLayout  android:id="@+id/PresentationLayout"  />        <LinearLayout  android:id="@+id/ActionLayout"                                    android:layout_height="1px"  /> </LinearLayout>
  • 34. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 Automatic Layout Transitions if  (presentationLayout.Visibility  ==  ViewStates.Gone)  {   presentationLayout.Visibility  =  ViewStates.Visible;   var  lp  =  new  LayoutParams  (actionLayout.LayoutParameters)  {     Height  =  1   };   actionLayout.LayoutParameters  =  lp; }  else  {   var  lp  =  new  LayoutParams  (actionLayout.LayoutParameters)  {     Height  =  ViewGroup.LayoutParams.WrapContent,     Gravity  =  GravityFlags.Center   };   actionLayout.LayoutParameters  =  lp;   presentationLayout.Visibility  =  ViewStates.Gone; }