filthy rich android

Upload: tudor-luca

Post on 13-Apr-2018

233 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/27/2019 Filthy Rich Android

    1/96

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    2/96

    Filthy Rich Clients

    Romain Guy

    Chet Haase

    google.com/+RomainGuy

    google.com/+ChetHaase

    @ro

    @c

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    3/96

    Filthy Rich Clients

    Romain Guy

    Chet Haase

    google.com/+RomainGuy

    google.com/+ChetHaase

    @ro

    @c

    Android

    Thursday, November 14, 13

    S

  • 7/27/2019 Filthy Rich Android

    4/96

    Filthy Rich Clients

    Romain Guy

    Chet Haase

    google.com/+RomainGuy

    google.com/+ChetHaase

    @ro

    @c

    Android

    Shin

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    5/96

    De!nition: Filthy Rich Clients

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    6/96

    De!nition: Filthy Rich Clients

    2007

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    7/96

    Ultra-graphically rich applications that ooze coolsuck the user in from the outset and hang on to

    with a death grip of excitement.

    De!nition: Filthy Rich Clients

    2007

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    8/96

    Ultra-graphically rich applications that ooze coolsuck the user in from the outset and hang on to

    with a death grip of excitement.

    De!nition: Filthy Rich Clients

    2007

    2013

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    9/96

    Ultra-graphically rich applications that ooze coolsuck the user in from the outset and hang on to

    with a death grip of excitement.

    De!nition: Filthy Rich Clients

    Applications that look cool, run smoothly, and inwell with the user.

    2007

    2013

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    10/96

    Graphics

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    11/96

    #DV13 #Filth

    Images withrounded corne

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    12/96

    #DV13 #Filth

    Images with rounded corners

    Dont bake the shape in your images

    Dont use intermediate layers Dont use clipping

    Use shaders!

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    13/96

    #DV13 #Filth

    What is a shader?

    A set of instructions that computes the source

    color of a pixel being drawn.

    Chet or Romain, just now

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    14/96

    #DV13 #Filth

    Example

    Paintp =newPaint();p.setColor(Color.RED);

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    15/96

    #DV13 #Filth

    Example

    Paintp =newPaint();p.setColor(Color.RED);

    Simplestshaderever

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    16/96

    #DV13 #Filth

    Android shaders

    Similar to OpenGL fragment shaders

    Not programmable Subclasses of android.graphics.Shader

    - BitmapShader

    - ComposeShader

    - LinearGradient

    - RadialGradient

    - SweepGradient

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    17/96

    #DV13 #Filth

    How drawing works (simplified)

    +

    drawRoundRect

    Paint

    Mask

    Shader

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    18/96

    #DV13 #Filth

    Back to images

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    19/96

    #DV13 #Filth

    Back to images

    BitmapShadershader =newBitmapShader(bitma Shader.TileMode.CLAMP, Shader.TileMode.C

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    20/96

    #DV13 #Filth

    Back to images

    BitmapShadershader =newBitmapShader(bitma Shader.TileMode.CLAMP, Shader.TileMode.C

    Paintpaint =newPaint();paint.setAntiAlias(true);paint.setShader(shader);

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    21/96

    #DV13 #Filth

    Back to images

    BitmapShadershader =newBitmapShader(bitma Shader.TileMode.CLAMP, Shader.TileMode.C

    Paintpaint =newPaint();paint.setAntiAlias(true);paint.setShader(shader);

    RectFrect =newRectF(0.0f, 0.0f, width, hecanvas.drawRoundRect(rect, radius, radius, p

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    22/96

    #DV13 #Filth

    Contrary to the previous slideNever allocate in draw() methods.

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    23/96

    #DV13 #Filth

    Vignette

    Novignette

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    24/96

    #DV13 #Filth

    ComposeShader

    LinearGradient

    BitmapShader ComposeS

    xfermode

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    25/96

    #DV13 #Filth

    Vignette

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    26/96

    #DV13 #Filth

    Vignette

    RadialGradientvignette =newRadialGradient( mRect.centerX(), mRect.centerY(), radius, newint[] { 0, 0, 0x7f000000}, newfloat[] { 0.0f, 0.7f, 1.0f}, Shader.TileMode.CLAMP);

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    27/96

    #DV13 #Filth

    Vignette

    RadialGradientvignette =newRadialGradient( mRect.centerX(), mRect.centerY(), radius, newint[] { 0, 0, 0x7f000000}, newfloat[] { 0.0f, 0.7f, 1.0f}, Shader.TileMode.CLAMP);

    Matrixoval =newMatrix();

    oval.setScale(1.0f, 0.7f);vignette.setLocalMatrix(oval);

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    28/96

    #DV13 #Filth

    Vignette

    RadialGradientvignette =newRadialGradient( mRect.centerX(), mRect.centerY(), radius, newint[] { 0, 0, 0x7f000000}, newfloat[] { 0.0f, 0.7f, 1.0f}, Shader.TileMode.CLAMP);

    Matrixoval =newMatrix();oval.setScale(1.0f, 0.7f);vignette.setLocalMatrix(oval);mPaint.setShader(newComposeShader( mBitmapShader, vignette, PorterDuff.Mode.SRC_O

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    29/96

    #DV13 #Filth

    Works with any shape

    drawCircle() drawPath() drawPath

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    30/96

    Animation

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    31/96

    #DV13 #Filth

    Animation APIs

    View properties: ViewPropertyAnimator

    Everything else: ObjectAnimator

    view.animate().alpha(0).translationX(-500);

    ObjectAnimator.ofFloat(view, "someProperty", 0).s

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    32/96

    #DV13 #Filth

    Timing is Everything

    Make those animations short!

    And non-linear

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    33/96

    ListViewAnimation!

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    34/96

    #DV13 #Filth

    ListView Animations

    Recycling containers are tricky

    - Views != items

    Avoid per-frame layout

    Determine before/after

    - animate those changes

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    35/96

    #DV13 #Filth

    Shadowed Background

    protectedvoidonDraw(Canvascanvas) {

    if(mShowing) { if(mUpdateBounds) { mShadowedBackground.setBounds(0, 0 getWidth(), mOpenAreaHeight); } canvas.save(); canvas.translate(0, mOpenAreaTop); mShadowedBackground.draw(canvas); canvas.restore(); }}

    Thursday, November 14, 13

    d d bl

  • 7/27/2019 Filthy Rich Android

    36/96

    #DV13 #Filth

    Adapters and Stable IDspublicclassStableArrayAdapter extendsArrayAdapter { // ... other methods...

    @Override

    publiclonggetItemId(intposition) { Stringitem =getItem(position); returnmIdMap.get(item); }

    @Override publicbooleanhasStableIds() { returntrue; }}

    Thursday, November 14, 13

    S i i M /F d

  • 7/27/2019 Filthy Rich Android

    37/96

    #DV13 #Filth

    Swiping: Move/Fade

    publicbooleanonTouch(finalViewv, MotionEventevent) { switch(event.getAction()) { // skipping DOWN/CANCEL/UP events

    caseMotionEvent.ACTION_MOVE: { if(!mSwiping) { if(deltaXAbs >mSwipeSlop) { mSwiping =true; mListView.requestDisallowInterceptTouchEvent(true) mBackgroundContainer.showBackground(v.getTop(), v.getHeight()); }

    } if(mSwiping) { v.setTranslationX((x -mDownX)); v.setAlpha(1-deltaXAbs /v.getWidth()); } } break; }}

    Thursday, November 14, 13

    A i t t

  • 7/27/2019 Filthy Rich Android

    38/96

    #DV13 #Filth

    Animate out

    v.animate().setDuration(duration). alpha(endAlpha).translationX(endX) withEndAction(newRunnable() { @Override publicvoidrun() { v.setAlpha(1); v.setTranslationX(0);

    animateRemoval(mListView, } });

    Thursday, November 14, 13

    A i t l i th

  • 7/27/2019 Filthy Rich Android

    39/96

    #DV13 #Filth

    Animate closing the gapprivatevoidanimateRemoval(finalListViewlistview, ViewviewToRemove) { // [ Get startTop for all views ]

    // Delete the item from the adapter intposition =mListView.getPositionForView(viewToRemove);

    mAdapter.remove(mAdapter.getItem(position));

    finalViewTreeObserverobserver =listview.getViewTreeObserver(); observer.addOnPreDrawListener(newViewTreeObserver.OnPreDrawListener() { publicbooleanonPreDraw() { observer.removeOnPreDrawListener(this); for(inti =0; i

  • 7/27/2019 Filthy Rich Android

    40/96

    CircularReveal!

    Thursday, November 14, 13

    Circular reveal

  • 7/27/2019 Filthy Rich Android

    41/96

    #DV13 #Filth

    Circular reveal

    Thursday, November 14, 13

    Circular reveal

  • 7/27/2019 Filthy Rich Android

    42/96

    #DV13 #Filth

    Circular reveal

    Technique similar to images with rounded corners

    - Uses a BitmapShader

    The mask is not a vector shape

    Uses an ALPHA_8 bitmap as the mask

    - Converted from any type of bitmap

    Thursday, November 14, 13

    Circular reveal

  • 7/27/2019 Filthy Rich Android

    43/96

    #DV13 #Filth

    Circular reveal

    ALPHA_8

    bitmap mask

    Bitmaptexture

    Thursday, November 14, 13

    Capturing the content

  • 7/27/2019 Filthy Rich Android

    44/96

    #DV13 #Filth

    Capturing the content

    privatestaticBitmapcreateBitmap(Viewtarg Bitmapb =Bitmap.createBitmap( target.getWidth(), target.getHeight( Bitmap.Config.ARGB_8888); Canvasc =newCanvas(b);

    target.draw(c); returnb;}

    Thursday, November 14, 13

    Loading the alpha mask

  • 7/27/2019 Filthy Rich Android

    45/96

    #DV13 #Filth

    Loading the alpha mask

    privateBitmaploadAsAlphaMask(intmaskId) { // Attempt to load the bitmap as an alpha mask

    BitmapFactory.Optionsopts =newBitmapFactory opts.inPreferredConfig =Bitmap.Config.ALPHA_8; Bitmapb =BitmapFactory.decodeResource( mRes, maskId, opts); // If it failed, extract the alpha if(b.getConfig() ==Bitmap.Config.ALPHA_8) {

    returnb; } else{ returnb.extractAlpha(); }}

    Thursday, November 14, 13

    Setting up the shader

  • 7/27/2019 Filthy Rich Android

    46/96

    #DV13 #Filth

    Setting up the shader

    privatevoidcreateShader() { Viewtarget =getRootView().findViewById(mTarg mTargetBitmap =createBitmap(target); ShadertargetShader =newBitmapShader(mTarget Shader.TileMode.CLAMP, Shader.TileMode.CLA

    mPaint.setShader(targetShader);}

    Thursday, November 14, 13

    Drawing the spotlight

  • 7/27/2019 Filthy Rich Android

    47/96

    #DV13 #Filth

    Drawing the spotlight

    protectedvoidonDraw(Canvascanvas) { mMatrix.setScale( 1.0f/mMaskScale, 1.0f/mMaskScale) mMatrix.preTranslate(-getMaskX(), -getMas

    mPaint.getShader().setLocalMatrix(mMatrix

    canvas.translate(getMaskX(), getMaskY()); canvas.scale(mMaskScale, mMaskScale); canvas.drawBitmap(mMask, 0.0f, 0.0f, mPai}

    Thursday, November 14, 13

    Animating the spotlight

  • 7/27/2019 Filthy Rich Android

    48/96

    #DV13 #Filth

    Animating the spotlight

    Thursday, November 14, 13

    Animating the spotlight

  • 7/27/2019 Filthy Rich Android

    49/96

    #DV13 #Filth

    Animating the spotlight

    Move left & scale up

    Thursday, November 14, 13

    Animating the spotlight

  • 7/27/2019 Filthy Rich Android

    50/96

    #DV13 #Filth

    Animating the spotlight

    Move to center & scale up

    Thursday, November 14, 13

    Setting up the animations

  • 7/27/2019 Filthy Rich Android

    51/96

    #DV13 #Filth

    Setting up the animations

    moveLeft =ObjectAnimator.ofFloat(spot, "maskX", leftscaleUp =ObjectAnimator.ofFloat(spot, "maskScale", moveCenter =ObjectAnimator.ofFloat(spot, "maskX", centmoveUp =ObjectAnimator.ofFloat(spot, "maskY", centscaleUp2 =ObjectAnimator.ofFloat(spot, "maskScale",

    Thursday, November 14, 13

    Choreographing

  • 7/27/2019 Filthy Rich Android

    52/96

    #DV13 #Filth

    Choreographing

    AnimatorSetset =newAnimatorSet()set.play(moveLeft).with(scaleUp);set.play(moveCenter).after(scaleUp)set.play(moveUp).after(scaleUp);set.play(scaleUp2).after(scaleUp);set.start();

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    53/96

    #DV13 #Filth

    Android 4.4Photo Editor

    Thursday, November 14, 13

    Filter reveal

  • 7/27/2019 Filthy Rich Android

    54/96

    #DV13 #Filth

    te e ea

    Same exact implementation as before

    Draws the spotlight on top of original photo

    Spots position depends on where you tapped the button

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    55/96

    #DV13 #Filth

    Google Now

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    56/96

    #DV13 #FilthThursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    57/96

    #DV13 #FilthThursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    58/96

    #DV13 #Filth

    Noantialiasing!

    Thursday, November 14, 13

    Path clipping

  • 7/27/2019 Filthy Rich Android

    59/96

    #DV13 #Filth

    pp g

    Pathclip =newPath();clip.addCircle(x, y, radius, Path.Direction.CW);canvas.clipPath(clip);drawContent();

    Thursday, November 14, 13

    Path clipping

  • 7/27/2019 Filthy Rich Android

    60/96

    #DV13 #Filth

    Pros

    - Easy to implement

    - Uses less memory

    - Faster to setup (no Bitmap copy)

    Cons

    - Android 4.3+ only with hardware acceleration

    - No antialiasing- Can be very expensive

    - Increases overdraw

    Thursday, November 14, 13

    A t

  • 7/27/2019 Filthy Rich Android

    61/96

    ActivityTransitions!

    Thursday, November 14, 13

    Custom Activity Transitions

  • 7/27/2019 Filthy Rich Android

    62/96

    #DV13 #Filth

    Standard window animations

    - default: scale/fade

    - customize: slide, fade, scale

    - Also thumbnail scale/crossfade

    ... But thats it

    Totally custom requires in-activity animations

    Thursday, November 14, 13

    Custom Activity Transitions

  • 7/27/2019 Filthy Rich Android

    63/96

    #DV13 #Filth

    Disable window animations

    Animate exiting activity

    Launch new activity with transparent window

    Animate content when activity comes up

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    64/96

    Thursday, November 14, 13

    Grayscale thumbnails

  • 7/27/2019 Filthy Rich Android

    65/96

    #DV13 #Filth

    ColorMatrixgrayMatrix =newColorMatrix();grayMatrix.setSaturation(0);ColorMatrixColorFiltergrayscaleFilter = newColorMatrixColorFilter(grayMatrix);

    thumbnailDrawable.setColorFilter(grayscaleFil

    Thursday, November 14, 13

    Drop shadow container

  • 7/27/2019 Filthy Rich Android

    66/96

    #DV13 #Filth

    protectedvoidonDraw(Canvascanvas) { for(inti =0; i

  • 7/27/2019 Filthy Rich Android

    67/96

    #DV13 #Filth

    publicvoidsetShadowDepth(floatdepth) { if(depth !=mShadowDepth) { mShadowDepth =depth; mShadowPaint.setAlpha( (int) (100+150*(1-mShadowDepth) invalidate(); }

    }

    Thursday, November 14, 13

    Transparent activity background

  • 7/27/2019 Filthy Rich Android

    68/96

    #DV13 #Filth

    true true @android:color/transparen

    Thursday, November 14, 13

    Launch sub-activity

  • 7/27/2019 Filthy Rich Android

    69/96

    #DV13 #Filth

    int[] screenLocation =newint[2];v.getLocationOnScreen(screenLocation);PictureDatainfo =mPicturesData.get(v);

    intorientation =getResources().getConfiguration().orientati

    IntentsubActivity =newIntent(ActivityAnimations.this, PictureDetailsActivity.class);subActivity.putExtra(PACKAGE+".orientation", orientation). putExtra(PACKAGE+".resourceId", info.resourceId). putExtra(PACKAGE+".left", screenLocation[0]). putExtra(PACKAGE+".top", screenLocation[1]).

    putExtra(PACKAGE+".width", v.getWidth()). putExtra(PACKAGE+".height", v.getHeight()). putExtra(PACKAGE+".description", info.description);startActivity(subActivity);

    overridePendingTransition(0, 0);

    Thursday, November 14, 13

    Get animation start values

  • 7/27/2019 Filthy Rich Android

    70/96

    #DV13 #Filth

    Bundlebundle =getIntent().getExtras();Bitmapbitmap =BitmapUtils.getBitmap(getResources(), bundle.getInt(PACKAGE_NAME+".resourceId"));Stringdescription =bundle.getString(PACKAGE_NAME+".descriptifinalintthumbnailTop =bundle.getInt(PACKAGE_NAME+".top");finalintthumbnailLeft =bundle.getInt(PACKAGE_NAME+".left")finalintthumbnailWidth =bundle.getInt(PACKAGE_NAME+".width"finalintthumbnailHeight =bundle.getInt(PACKAGE_NAME+".heighmOriginalOrientation =bundle.getInt(PACKAGE_NAME+".orientatio

    Thursday, November 14, 13

    Get animation end values

  • 7/27/2019 Filthy Rich Android

    71/96

    #DV13 #Filth

    ViewTreeObserverobserver =mImageView.getViewTreeObserver();observer.addOnPreDrawListener(newViewTreeObserver.OnPreDrawListe @Override

    publicbooleanonPreDraw() { mImageView.getViewTreeObserver().removeOnPreDrawListener( int[] screenLocation =newint[2]; mImageView.getLocationOnScreen(screenLocation); mLeftDelta =thumbnailLeft -screenLocation[0]; mTopDelta =thumbnailTop -screenLocation[1]; mWidthScale =(float) thumbnailWidth /mImageView.getWidt mHeightScale =(float) thumbnailHeight /mImageView.getHe

    runEnterAnimation();

    returntrue; }});

    Thursday, November 14, 13

    Animate thumbnail & descriptionmImageView setPivotX(0);

  • 7/27/2019 Filthy Rich Android

    72/96

    #DV13 #Filth

    mImageView.setPivotX(0);mImageView.setPivotY(0);mImageView.setScaleX(mWidthScale);mImageView.setScaleY(mHeightScale);mImageView.setTranslationX(mLeftDelta);mImageView.setTranslationY(mTopDelta);mTextView.setAlpha(0);

    mImageView.animate().setDuration(duration). scaleX(1).scaleY(1). translationX(0).translationY(0). setInterpolator(sDecelerator). withEndAction(newRunnable() {

    publicvoidrun() { mTextView.setTranslationY(-mTextView.getHeight mTextView.animate().setDuration(duration/2). translationY(0).alpha(1). setInterpolator(sDecelerator); } });

    Thursday, November 14, 13

    Fade in black background

  • 7/27/2019 Filthy Rich Android

    73/96

    #DV13 #Filth

    ObjectAnimator.ofInt(mBackground, "alpha", 0, start();

    Thursday, November 14, 13

    Colorize thumbnail

  • 7/27/2019 Filthy Rich Android

    74/96

    #DV13 #Filth

    ObjectAnimatorcolorizer =ObjectAnimator.ofFl

    PictureDetailsActivity.this, "saturation",colorizer.start();

    publicvoidsetSaturation(floatvalue) { colorizerMatrix.setSaturation(value);

    ColorMatrixColorFiltercolorizerFilter =newColorMatrixColorFilter(colorizerMa

    mBitmapDrawable.setColorFilter(colorizerFi}

    Thursday, November 14, 13

    Animate drop shadow

  • 7/27/2019 Filthy Rich Android

    75/96

    #DV13 #Filth

    ObjectAnimatorshadowAnim =ObjectAnimator.of mShadowLayout, "shadowDepth", 0, 1);shadowAnim.start();

    Thursday, November 14, 13

    Animate back to main activity

  • 7/27/2019 Filthy Rich Android

    76/96

    #DV13 #Filth

    @OverridepublicvoidonBackPressed() {

    runExitAnimation(newRunnable() { publicvoidrun() { finish(); } });}

    @Overridepublicvoidfinish() { super.finish(); overridePendingTransition(0, 0);}

    Thursday, November 14, 13

    Foldi

  • 7/27/2019 Filthy Rich Android

    77/96

    FoldingLayout!

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    78/96

    #DV13 #Filth

    Fan Fare

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    79/96

    #DV13 #FilthThursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    80/96

    #DV13 #Filth

    Matrix.setPolyToPoly()

    Thursday, November 14, 13

    for(intx =0; x

  • 7/27/2019 Filthy Rich Android

    81/96

    #DV13 #Filth

    src =mFoldRectArray[x]; canvas.save(); canvas.concat(mMatrix[x]);

    canvas.clipRect(0, 0, src.width(), src.height()); canvas.translate(-src.left, 0); super.dispatchDraw(canvas); if(x %2==0) { canvas.drawRect(0, 0, mFoldW, mFoldH, mSolidS } else{ canvas.drawRect(0, 0, mFoldW, mFoldH, mSoftSh } canvas.restore();}

    Thursday, November 14, 13

    for(intx =0; x

  • 7/27/2019 Filthy Rich Android

    82/96

    #DV13 #Filth

    src =mFoldRectArray[x]; canvas.save(); canvas.concat(mMatrix[x]);

    canvas.clipRect(0, 0, src.width(), src.height()); canvas.translate(-src.left, 0); super.dispatchDraw(canvas); if(x %2==0) { canvas.drawRect(0, 0, mFoldW, mFoldH, mSolidS } else{ canvas.drawRect(0, 0, mFoldW, mFoldH, mSoftSh } canvas.restore();}

    Thursday, November 14, 13

    for(intx =0; x

  • 7/27/2019 Filthy Rich Android

    83/96

    #DV13 #Filth

    src =mFoldRectArray[x]; canvas.save(); canvas.concat(mMatrix[x]);

    canvas.clipRect(0, 0, src.width(), src.height()); canvas.translate(-src.left, 0); super.dispatchDraw(canvas); if(x %2==0) { canvas.drawRect(0, 0, mFoldW, mFoldH, mSolidS } else{ canvas.drawRect(0, 0, mFoldW, mFoldH, mSoftSh } canvas.restore();}

    Thursday, November 14, 13

    for(intx =0; x

  • 7/27/2019 Filthy Rich Android

    84/96

    #DV13 #Filth

    src =mFoldRectArray[x]; canvas.save(); canvas.concat(mMatrix[x]);

    canvas.clipRect(0, 0, src.width(), src.height()); canvas.translate(-src.left, 0); super.dispatchDraw(canvas); if(x %2==0) { canvas.drawRect(0, 0, mFoldW, mFoldH, mSolidS } else{ canvas.drawRect(0, 0, mFoldW, mFoldH, mSoftSh

    } canvas.restore();}

    Thursday, November 14, 13

    Color Filters

  • 7/27/2019 Filthy Rich Android

    85/96

    #DV13 #Filth

    Can be used to modify a shader

    Subclasses of ColorFilter

    - ColorMatrixColorFilter

    - LightingColorFilter

    - PorterDu!ColorFilter

    Thursday, November 14, 13

    Sepia Effect

  • 7/27/2019 Filthy Rich Android

    86/96

    #DV13 #Filth

    ColorMatrixm1 =newColorMatrix();ColorMatrixm2 =newColorMatrix();

    m1.setSaturation(0.1f);m2.setScale(1f, 0.95f, 0.82f, 1.0f);

    m1.setConcat(m2, m1);

    mSepiaPaint.setColorFilter( newColorMatrixColorFilter(m1));

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    87/96

    Performance

    Thursday, November 14, 13

    Smoother is Better

    C i t t f t

  • 7/27/2019 Filthy Rich Android

    88/96

    #DV13 #Filth

    Consistent frame rate

    Avoid hiccups

    Avoid large steps over few frames

    Thursday, November 14, 13

    Only Draw What You Need (ODWYN)

    P f i lid t (l t b) i lid t ()

  • 7/27/2019 Filthy Rich Android

    89/96

    #DV13 #Filth

    Prefer invalidate(l, t, r, b) over invalidate()

    Only invalidate custom views that actually change

    Let the framework invalidate standard views

    Thursday, November 14, 13

    Avoid Overdraw

    Developer options > Show Overdraw

  • 7/27/2019 Filthy Rich Android

    90/96

    #DV13 #Filth

    Developer options -> Show Overdraw

    Window background vs. opaque containers vs. opaque vi

    Thursday, November 14, 13

    Get Off that UI Thread!

    Avoid expensive operations on UI thread

  • 7/27/2019 Filthy Rich Android

    91/96

    #DV13 #Filth

    Avoid expensive operations on UI thread

    - network, database, bitmaps, ...

    AsyncTask is your friend

    Thursday, November 14, 13

    Avoid Garbage Collection

    especially during animations

  • 7/27/2019 Filthy Rich Android

    92/96

    #DV13 #Filth

    ... especiallyduring animations

    Lots of small objects will eventually cause GC

    Avoid Iterators, temporary objects- Consider cached objects for temporaries

    Use Allocation Tracker in DDMS

    Thursday, November 14, 13

    clipPath

    Not always the fastest way to clip to a path

  • 7/27/2019 Filthy Rich Android

    93/96

    #DV13 #Filth

    Not always the fastest way to clip to a path

    Doesnt support antialiasing

    Try BitmapShader

    Thursday, November 14, 13

    Consider Time Travel

    Go see Android Performance Workshop 2 days ago

  • 7/27/2019 Filthy Rich Android

    94/96

    #DV13 #Filth

    Go see Android Performance Workshop 2 days ago

    - Memory

    - Performance tips- Tools

    - Case studies

    Thursday, November 14, 13

    For More Information

    ChetRomain:

  • 7/27/2019 Filthy Rich Android

    95/96

    #DV13 #Filth

    Google I/O talks

    Parleys.com talks

    Devbytes on YouTube

    graphics-geek.blogspot.com

    google.com/+ChetHaase

    @chethaase

    curious-creature.org

    google.com/+RomainGuy

    @romainguy

    Thursday, November 14, 13

  • 7/27/2019 Filthy Rich Android

    96/96

    #DV13 #Filth

    Filthy Rich Clients: Developing

    Animated and Graphical E!ects

    Thursday, November 14, 13