Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Efficient Android Layouts (GOTO Conference)

Daniel Lew
October 03, 2016

Efficient Android Layouts (GOTO Conference)

Talk given about Android layouts at GOTO Conference Copenhagen in 2016.

Daniel Lew

October 03, 2016
Tweet

More Decks by Daniel Lew

Other Decks in Programming

Transcript

  1. RelativeLayout / ConstraintLayout • Position views relative to each other

    • RelativeLayout: Slow • ConstraintLayout: Alpha
  2. But I <3 RelativeLayout • LinearLayout == sometimes slow •

    RelativeLayout == always slow • ConstraintLayout == savior • Profile!
  3. FrameLayout • Positioning based on parent bounds • Overlapping Views

    • Clickable item backgrounds • Toggle container
  4. 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...
 }
 }
  5. 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...
 }
 }
  6. <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>
  7. 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);
  8. MeasureSpec • EXACTLY - Must be that size • AT_MOST

    - Maximum width • UNDEFINED - Ideal width
  9. 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... }
  10. onMeasure() @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int

    width; int height; // ...Calculate width and height... setMeasuredDimension(width, height); }
  11. Custom Drawables • onMeasure() -> getIntrinsicHeight() / getIntrinsicWidth() • onDraw()

    -> draw() • https://speakerdeck.com/cyrilmottier/mastering-android-drawables
  12. 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>
  13. 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" />
  14. 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" />
  15. 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" />
  16. static final int NUM_COLUMNS = 3;
 
 static final int

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

    final int NUM_RETRIES = 3;
 static final int NUM_THREE = 3;
  18. • 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"
 />
  19. int square() {
 return 8 * 8;
 }
 int squareLarge()

    {
 return 16 * 16;
 } int square(int num) {
 return num * num;
 } VS
  20. <style name="WelcomeText" parent="TextAppearance.AppCompat">
 <item name="android:textSize">24sp</item> <item name="android:textColor">#FF00FF</item>
 </style> <style name="WelcomeText"

    parent="TextAppearance.AppCompat">
 <item name="android:textSize">16sp</item> <item name="android:textColor">#FF00FF</item>
 </style>
  21. Button Outline <?xml version="1.0" encoding="utf-8"?>
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle"
 >
 


    <solid android:color="@color/transparent" />
 
 <stroke
 android:width="1dp"
 android:color="@color/white"
 />
 
 <corners android:radius="@dimen/corner_radius_tiny" />
 
 </shape>
  22. Button Selector <?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 
 <item>
 <selector>


    <item android:state_pressed="true">
 <shape android:shape="rectangle">
 <solid android:color="@color/blue_200" />
 
 <corners android:radius="@dimen/corner_radius_tiny" />
 </shape>
 </item>
 
 <item android:drawable="@color/transparent" />
 </selector>
 </item>
 
 <item android:drawable="@drawable/btn_welcome_outline" />
 
 </layer-list>
  23. <?xml version="1.0" encoding="utf-8"?>
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
 android:color="@color/blue_200"
 >
 
 <item android:drawable="@drawable/btn_welcome_outline"

    />
 
 <item android:id="@android:id/mask">
 <shape android:shape="rectangle">
 <solid android:color="@color/white" />
 <corners android:radius="@dimen/corner_radius_tiny" />
 </shape>
 </item>
 
 </ripple> Button Selector (v21)
  24. SVG -> VectorDrawable • Android Studio: New Vector Asset •

    Victor: github.com/trello/victor android {
 sourceSets {
 main {
 svg.srcDir 'src/main/svg'
 }
 }
 }
  25. vs

  26. Tinting Images • XML • Simple drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); • Comprehensive

    Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
 DrawableCompat.setTint(wrappedDrawable, color); Not backwards compatible