efficient android layouts
play

Efficient Android Layouts Dan Lew Give me the place to stand, and I - PowerPoint PPT Presentation

Efficient Android Layouts Dan Lew Give me the place to stand, and I shall move the earth. ~Archimedes Give me a standing desk, and I shall write an Android app. ~Me ViewGroups Complex ConstraintLayout RelativeLayout


  1. Efficient Android Layouts Dan Lew

  2. “Give me the place to stand, and I shall move the earth.” ~Archimedes

  3. “Give me a standing desk, and I shall write an Android app.” ~Me

  4. ViewGroups

  5. Complex ConstraintLayout RelativeLayout LinearLayout FrameLayout Simple

  6. RelativeLayout / ConstraintLayout • Position views relative to each other • RelativeLayout: Slow • ConstraintLayout: Alpha

  7. LinearLayout • Stack views vertically/horizontally • Weight distribution

  8. But I <3 RelativeLayout • LinearLayout == sometimes slow • RelativeLayout == always slow • ConstraintLayout == savior • Profile!

  9. FrameLayout • Positioning based on parent bounds • Overlapping Views • Clickable item backgrounds • Toggle container

  10. 
 
 < LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="horizontal" 
 > 
 < include 
 layout="@layout/avatar_view" 
 android:layout_width="48dp" 
 android:layout_height="48dp" 
 /> 
 <!-- Rest of layout here... --> 
 </ LinearLayout >

  11. 
 
 < LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="horizontal" 
 > 
 < include 
 layout="@layout/avatar_view" 
 android:layout_width="48dp" 
 android:layout_height="48dp" 
 /> 
 <!-- Rest of layout here... --> 
 </ LinearLayout >

  12. 
 
 < LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="horizontal" 
 > 
 < com.trello.view.AvatarView 
 android:id="@+id/avatar_view" 
 android:layout_width="48dp" 
 android:layout_height="48dp" 
 /> 
 <!-- Rest of layout here... --> 
 </ LinearLayout >

  13. 
 
 
 
 
 public class AvatarView extends FrameLayout { 
 ImageView icon ; 
 TextView initials ; 
 public AvatarView(Context context, AttributeSet attrs) { 
 super (context, attrs); 
 LayoutInflater. from (context).inflate(R.layout. view_avatar , this ); 
 icon = (ImageView) findViewById(R.id. icon ); 
 initials = (TextView) findViewById(R.id. initials ); 
 } 
 public void bind(Member member) { 
 // ...Load icon into ImageView... 
 // OR 
 // ...Setup initials in TextView... 
 } 
 }

  14. 
 
 
 < FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 > 
 < TextView 
 android:id="@+id/initials" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 /> 
 < ImageView 
 android:id="@+id/icon" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 /> 
 </ FrameLayout >

  15. AvatarView (FrameLayout) FrameLayout TextView ImageView

  16. 
 
 
 
 
 public class AvatarView extends FrameLayout { 
 ImageView icon ; 
 TextView initials ; 
 public AvatarView(Context context, AttributeSet attrs) { 
 super (context, attrs); 
 LayoutInflater. from (context).inflate(R.layout. view_avatar , this ); 
 icon = (TextView) findViewById(R.id. icon ); 
 initials = (TextView) findViewById(R.id.initials); 
 } 
 public void bind(Member member) { 
 // ...Load icon into ImageView... 
 // OR 
 // ...Setup initials in TextView... 
 } 
 }

  17. 
 
 
 < merge xmlns:android="http://schemas.android.com/apk/res/android" 
 > 
 < TextView 
 android:id="@+id/initials" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 /> 
 < ImageView 
 android:id="@+id/icon" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 /> 
 </ merge >

  18. AvatarView (Framelayout) TextView ImageView

  19. Custom Drawing

  20. Step #1: onMeasure() (…sometimes you can skip this…)

  21. onMeasure() • onMeasure() signature void onMeasure(int widthMeasureSpec, int heightMeasureSpec) • measureSpec - packed integer int widthMode = MeasureSpec . getMode(widthMeasureSpec); int widthSize = MeasureSpec . getSize(widthMeasureSpec); int heightMode = MeasureSpec . getMode(heightMeasureSpec); int heightSize = MeasureSpec . getSize(heightMeasureSpec);

  22. MeasureSpec • EXACTLY - Must be that size • AT_MOST - Maximum width • UNDEFINED - Ideal width

  23. onMeasure() protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec . getMode(widthMeasureSpec); int widthSize = MeasureSpec . getSize(widthMeasureSpec); int width; if (widthMode == MeasureSpec . EXACTLY) { width = widthSize; } else { int desiredWidth = 500; // Whatever calculation you want if (widthMode == MeasureSpec . AT_MOST) { width = Math . min(desiredWidth, widthSize); } else { width = desiredWidth; } } // ...to be continued... }

  24. onMeasure() @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width; int height; // ...Calculate width and height... setMeasuredDimension(width, height); }

  25. Step #2: onDraw() (this is up to you)

  26. Custom Drawables • onMeasure() -> getIntrinsicHeight() / getIntrinsicWidth() • onDraw() -> draw() • https://speakerdeck.com/cyrilmottier/mastering-android-drawables

  27. Styles

  28. Styles • No style < View android:background=“#FF0000” /> • Style <!--- some_layout.xml --> < View style="@style/MyStyle" /> <!--- styles.xml --> 
 < style name="MyStyle" > 
 < item name="android:background" >#FF0000</ item > 
 </ style >

  29. Efficient • Semantically identical Views • All styled Views should change at once

  30. 
 Not Efficient • Single-use styles • Coincidentally using the same attributes < TextView 
 android:id="@+id/title" 
 android:textColor="@color/blue_200" 
 android:textColorHint=“@color/grey_500" /> 
 < TextView 
 android:id="@+id/body" 
 android:textColor="@color/blue_200" 
 android:textColorHint=“@color/grey_500" />

  31. 
 Not Efficient • Single-use styles • Coincidentally using the same attributes < TextView 
 android:id="@+id/title" 
 android:textColor="@color/blue_200" 
 android:textColorHint=“@color/grey_500" /> 
 < TextView 
 android:id="@+id/body" 
 android:textColor="@color/blue_200" 
 android:textColorHint=“@color/grey_500" />

  32. 
 Not Efficient • Single-use styles • Coincidentally using the same attributes < TextView 
 android:id="@+id/title" 
 android:textColor="@color/blue_200" 
 android:textColorHint=“@color/grey_500" /> 
 < TextView 
 android:id="@+id/body" 
 android:textColor="@color/blue_200" 
 android:textColorHint=“@color/grey_500" />

  33. 
 static final int NUM_COLUMNS = 3; 
 static final int NUM_RETRIES = 3; static final int NUM_THREE = 3;

  34. 
 // static final int NUM_COLUMNS = 3; 
 // static final int NUM_RETRIES = 3; 
 static final int NUM_THREE = 3;

  35. Themes

  36. Themes • Affect multiple Views at once • Default styles • Configure system-created Views

  37. • Application < application 
 android:theme="@style/Theme.AppCompat" > • Activity < activity 
 android:theme=“@style/Theme.AppCompat.Light” > • View < Toolbar 
 android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
 app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
 />

  38. AppCompat • Material on all devices • Baseline themes/styles • Enables View theming pre-Lollipop

  39. < style name="ColorTheme" parent="Theme.AppCompat" > 
 < item name="colorPrimary" >#F00</ item > 
 < item name="colorPrimaryDark" >#0F0</ item > 
 < item name="colorControlNormal" >#00F</ item > 
 </ style >

  40. 
 < style name="AppTheme" parent="Theme.AppCompat" > 
 < item name="buttonStyle" >@style/MyButton</ item > 
 < item name="android:spinnerItemStyle" >@style/MySpinnerItem</ item > 
 < item name="android:textAppearance" >@style/MyText</ item > 
 < item name="android:textAppearanceInverse" >@style/MyTextInverse</ item > 
 </ style >

Recommend


More recommend