Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Abstract
 UI Concepts Sriram Ramani [email protected]

Slide 3

Slide 3 text

Giant ListViews

Slide 4

Slide 4 text

Stories

Slide 5

Slide 5 text

Stories

Slide 6

Slide 6 text

Stories

Slide 7

Slide 7 text

Stories

Slide 8

Slide 8 text

SHOCK SPOCK A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user.

Slide 9

Slide 9 text

ListView Recycling

Slide 10

Slide 10 text

ListView Recycling ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 8 ITEM 8

Slide 11

Slide 11 text

ListView Recycling bind the model measure layout addView getView()

Slide 12

Slide 12 text

ListView Recycling USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME

Slide 13

Slide 13 text

Break the rows

Slide 14

Slide 14 text

SHOCK SPOCK A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user.

Slide 15

Slide 15 text

ListView Recycling USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. USER NAME A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user.

Slide 16

Slide 16 text

public enum ITEM_TYPES { HEADER, CONTENT, SECONDARY_INFO, FEEDBACK_BAR } @Override public int getViewTypeCount() { return ITEM_TYPES.values().length; } @Override public int getItemViewType(int position) { return ITEM_TYPES.values()[position % getViewTypeCount()]; } @Override public View getView(int position, View convertView, ViewGroup parent) { // Bind based on the item type. } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Slide 17

Slide 17 text

Advantages ▪ Faster binding time ▪ Less time to measure ▪ Less time to draw each row ▪ More re-usable rows

Slide 18

Slide 18 text

Custom ViewGroups

Slide 19

Slide 19 text

Typical Header

Slide 20

Slide 20 text

Typical Header Shock Spock 2 hr • San Francisco, CA

Slide 21

Slide 21 text

LinearLayout of LinearLayouts

Slide 22

Slide 22 text

LinearLayout weights Shock Spock 2 hr • San Francisco, CA Thumbnail LinearLayout (Outer) Title Subtitle Menu LinearLayout (Inner)

Slide 23

Slide 23 text

LinearLayout weights > LinearLayout (Outer) > Thumbnail > LinearLayout (Inner) > Title > Subtitle > Title > Subtitle > Menu > LinearLayout (Inner) > Title > Subtitle Shock Spock 2 hr • San Francisco, CA

Slide 24

Slide 24 text

RelativeLayout

Slide 25

Slide 25 text

RelativeLayout Shock Spock 2 hr • San Francisco, CA Title Subtitle Thumbnail Menu RelativeLayout

Slide 26

Slide 26 text

RelativeLayout > RelativeLayout > Menu > Thumbnail > Subtitle > Title > Title > Subtitle > Menu > Thumbnail Shock Spock 2 hr • San Francisco, CA

Slide 27

Slide 27 text

Custom ViewGroup

Slide 28

Slide 28 text

Custom ViewGroup > CustomViewGroup > Thumbnail > Menu > Title > Subtitle Shock Spock 2 hr • San Francisco, CA

Slide 29

Slide 29 text

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthConstraints = getPaddingLeft() + getPaddingRight(); int heightConstraints = getPaddingTop() + getPaddingBottom(); // Measure the thumbnail. measureChildWithMargins( mThumbnailView, widthMeasureSpec, widthConstraints, heightMeasureSpec, heightConstraints); widthConstraints += mThumbnailView.getMeasuredWidth(); // Measure the title. measureChildWithMargins( mTitleView, widthMeasureSpec, widthConstraints, heightMeasureSpec, heightConstraints); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Slide 30

Slide 30 text

@Override protected void measureChildWithMargins( View child, int parentWidthMeasureSpec, int widthConstraints, int parentHeightMeasureSpec, int heightConstraints) { MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, widthConstraints + lp.leftMargin + lp.rightMargin, lp.width); int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, heightConstraints + lp.topMargin + lp.bottomMargin, lp.height); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Slide 31

Slide 31 text

SHOCK SPOCK A piece of text that extends couple of lines. This is the core of the app as this provides the information to the user. 1 2 3 4 5

Slide 32

Slide 32 text

Sub-views

Slide 33

Slide 33 text

Sub-views LinearLayout ImageView TextView Drawable Layout

Slide 34

Slide 34 text

TextViews Bacon ipsum dolor sit amet spare ribs pork tongue, hamburger biltong rump shoulder turkey ham hock beef tri-tip pork chop jerky fatback.

Slide 35

Slide 35 text

TextViews Bacon ipsum dolor sit amet spare ribs pork tongue, hamburger biltong rump shoulder turkey ham hock beef tri-tip pork chop jerky fatback.

Slide 36

Slide 36 text

ListView Recycling ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 8 ITEM 8

Slide 37

Slide 37 text

@Override public void setText(CharSequence text) { // Store the text. checkForRelayout(); } private void checkForRelayout() { // Make new layout for the new text. makeNewLayout(want, …, width, …); } 1 2 3 4 5 6 7 8 9 10 11 12

Slide 38

Slide 38 text

Text Layout Caching

Slide 39

Slide 39 text

public class TextLayoutView extends View { private Layout mLayout; public void setText(CharSequence text, String key) { Layout layout = SHARED_LAYOUT_CACHE.get(key); if (layout == null) { // Better to do this in onMeasure() mLayout = new StaticLayout(…); } else { mLayout = layout; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mLayout.draw(canvas); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

Slide 40

Slide 40 text

Advantages ▪ Less object creation ▪ Layout measuring cost is saved ▪ Works with Spannables too ▪ Can hack it work for ClickableSpans

Slide 41

Slide 41 text

Watch out ▪ Orientation change ▪ Locale change ▪ Same text in a different context / color

Slide 42

Slide 42 text

public class TextLayoutView extends View { private Layout mLayout; public void setText(CharSequence text, String key) { Layout layout = SHARED_LAYOUT_CACHE.get(key); if (layout == null) { // Better to do this in onMeasure() mLayout = new StaticLayout(…); } else { mLayout = layout; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mLayout.draw(canvas); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

Slide 43

Slide 43 text

PictureDrawable

Slide 44

Slide 44 text

public class TextLayoutView extends View { private Layout mLayout; private Picture mPicture; private boolean mRecorded = false; @Override protected void onDraw(Canvas canvas) { if (!mRecorded) { Canvas pictureCanvas = mPicture.beginRecording( canvas.getWidth(), canvas.getHeight()); super.onDraw(pictureCanvas); mLayout.draw(pictureCanvas); mPicture.endRecording(); mRecorded = true; } mPicture.draw(canvas); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Slide 45

Slide 45 text

Sprites

Slide 46

Slide 46 text

Glyphs

Slide 47

Slide 47 text

Texture Atlas

Slide 48

Slide 48 text

Batching & Merging ONE TWO

Slide 49

Slide 49 text

Batching & Merging ONE TWO

Slide 50

Slide 50 text

private void drawAPortion() { // Draw the bitmap. canvas.drawBitmap(mBitmap, mSourceRect, mDestinationRect, null); } 1 2 3 4 5

Slide 51

Slide 51 text

public class SpriteImageView extends ImageView { private WeakReference mBitmap; @Override public void onDraw(Canvas canvas) { // Get the destination rectangle. getDrawingRect(mDestinationRect); // Draw the bitmap. canvas.drawBitmap(mBitmap.get(), mSourceRect, mDestinationRect, null); } public void setCoordinates(int left, int top, int width, int height) { mSourceRect.set(left, top, left + width, top + height); invalidate(); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Slide 52

Slide 52 text

Advantages ▪ Pay the cost of reading bitmap once ▪ Need not be in Android resource cache ▪ Less commands sent to GPU ▪ Same texture re-used

Slide 53

Slide 53 text

Color Tinting

Slide 54

Slide 54 text

Glyphs

Slide 55

Slide 55 text

Tinting COLOR FILTER + =

Slide 56

Slide 56 text

PorterDuff Mode SRC_OVER

Slide 57

Slide 57 text

PorterDuff Mode DST_OVER

Slide 58

Slide 58 text

PorterDuff Mode SRC_IN

Slide 59

Slide 59 text

PorterDuff Mode SRC_IN

Slide 60

Slide 60 text

private void tintGlyph(int tintColor) { // Create a color filter. ColorFilter colorFilter = new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN); // Set it on the drawable. mDrawable.setColorFilter(colorFilter); } 1 2 3 4 5 6 7 8 9

Slide 61

Slide 61 text

State Changes

Slide 62

Slide 62 text

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

Slide 63

Slide 63 text

public class TintImageView extends ImageView { private ColorStateList mTintColor; @Override protected void drawableStateChanged() { super.drawableStateChanged(); if (mTintColor != null) { // Get the color for the state. int[] state = getDrawableState(); int tintColor = mTintColor.getColorForState(state, 0); // Create a color filter. ColorFilter colorFilter = new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN); // Set it on the image. setColorFilter(colorFilter); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

Slide 64

Slide 64 text

Advantages ▪ Cuts down resources in half (or even more) ▪ Can be combined with sprites ▪ Only one bitmap is loaded even for StateListDrawable

Slide 65

Slide 65 text

That’s all folks!