Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Tips & Tricks to spice up your Android app

Tips & Tricks to spice up your Android app

We will explore how Android (especially in recent versions) lets you develop awesomer apps and how you can tap into that potential with Xamarin.Android. Topics covered will include graphics, user interaction, best practices and animations.

Jérémie Laval

April 17, 2013
Tweet

More Decks by Jérémie Laval

Other Decks in Technology

Transcript

  1. 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
  2. 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
  3. 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; }
  4. 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);         });     }); }
  5. 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>
  6. 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);    } }
  7. 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"  />
  8. - Jérémie Laval “The best animations are the ones your

    users don’t notice because they feel natural”
  9. 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);        });    } }
  10. 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; }
  11. 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>
  12. 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; }