SlideShare a Scribd company logo
1 of 45
Making It Fit
How Android Measures and Draws Views
Paul Lammertsma
CTO
Components?
Custom components?
Custom components?
Why not just…
• Sometimes you can
– Beware of using lots of ViewGroups
– Beware of unnecessary layouting
• Sometimes you simply can’t
…write it out in a layout?
<LinearLayout …
android:orientation=”horizontal">
<LinearLayout …
android:orientation="vertical”>
…
</LinearLayout>
<LinearLayout …
android:orientation="vertical”>
…
</LinearLayout>
</LinearLayout>
Model
Activity
t1 = new TextView(context);
t1.setBackground(d);
t1.setTextColor(c);
t2 = new TextView(context);
t2.setBackground(d);
t2.setTextColor(c);
t3 = new TextView(context);
t3.setBackground(d);
t3.setTextColor(c);
View
res/layout
View
res/layout
new TextView(context)<TextView …/>
Why not just…
• Keep your views and models separated!
…write it out in code?
Why not just…
We will!
…write it out in some clumsy
combination of a layout and code?
At the root of any component…
android.widget.View
“The basic building block of all Android’s UI components.”
—d.android.com
public class FontTextView extends TextView {
public FontTextView(Context context) {
super(context);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
public void setTypeface(String typeface) {
FontUtil.setTypeface(this, typeface);
}
FontTextView
Simple constructor to use when creating a view from
code.
Constructor that is called when inflating a view from
XML.
Perform inflation from XML and apply a class-specific
base style.
extends View
public class FontUtil {
public static void setTypeface(TextView view, String typefaceName) {
Typeface typeface = Typeface.createFromAsset(
view.getContext().getAssets(),
"fonts/" + typefaceName);
view.setTypeface(typeface);
}
}
FontUtil
We should probably reuse
typefaces.
public static void setTypeface(TextView view, String typefaceName) {
Typeface typeface =
getTypeface(view.getContext(), typefaceName);
view.setTypeface(typeface);
}
public static Typeface getTypeface(Context context, String typefaceName) {
return Typeface.createFromAsset(
context.getAssets(),
"fonts/" + typefaceName);
}
FontUtil
private static final Map<String, Typeface> FONTS = new HashMap<String, Typeface>();
public static void setTypeface(TextView view, String typefaceName) {
view.setTypeface(getTypeface(view.getContext(), typefaceName));
}
public static Typeface getTypeface(Context context, String typefaceName) {
Typeface typeface = FONTS.get(typefaceName);
if (typeface == null) {
typeface = Typeface.createFromAsset(
context.getAssets(),
"fonts/" + typefaceName);
FONTS.put(typefaceName, typeface);
}
return typeface;
}
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.pixplicity.droidconfr.widgets.FontTextView
style="@style/SampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Layout
Provide the fully qualified name to the
custom component.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FontTextView">
<attr name="typeface" format="string" />
</declare-styleable>
</resources>
Attributes
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="typeface" format="string" />
<declare-styleable name="FontTextView">
<attr name="typeface" />
</declare-styleable>
</resources>
Definition
Reference
public class FontTextView extends TextView {
public FontTextView(Context context) {
super(context);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
…
}
FontTextView
init(context, null, 0);
init(context, attrs, 0);
init(context, attrs, defStyle);
private void init(Context context, AttributeSet attrs, int defStyle) {
if (attrs != null) {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.FontTextView, defStyle, 0);
final String typeface =
a.getString(R.styleable.FontTextView_typeface);
a.recycle();
if (typeface != null) {
setTypeface(typeface);
}
}
}
public void setTypeface(String typeface) {
FontUtil.setTypeface(this, typeface);
}
FontTextViewSetting attributes directly from the layout, or
indirectly from the style.
<declare-styleable name="FontTextView">
<attr name="typeface" />
</declare-styleable>Setting attributes through code.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.pixplicity.droidconfr.widgets.FontTextView
style="@style/SampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app=
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.pixplicity.droidconfr.widgets.FontTextView
style="@style/SampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app=
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.pixplicity.droidconfr.widgets.FontTextView
style="@style/SampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:typeface= />
</LinearLayout>
Layout
Add a namespace declaration for our
package…
…so we can use it here.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.pixplicity.droidconfr.widgets.FontTextView
style="@style/SampleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:typeface="Abel-Regular.ttf" />
</LinearLayout>
Layout
/apk/res/com.pixplicity.droidconfr
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="SampleText" parent="@android:style/Widget.TextView">
<item name="android:text">@string/pangram</item>
<item name="android:textSize">18sp</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="SampleText" parent="@android:style/Widget.TextView">
<item name="android:text">@string/pangram</item>
<item name="android:textSize">18sp</item>
<item name="com.pixplicity.droidconfr:typeface"> </item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="SampleText" parent="@android:style/Widget.TextView">
<item name="android:text">@string/pangram</item>
<item name="android:textSize">18sp</item>
<item name="com.pixplicity.droidconfr:typeface">Abel-Regular.ttf</item>
</style>
</resources>
Styles
Provide the package name.
public class SimpleAnimatedView extends View {
private final Paint mPaintFg = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintLn = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintBg = new Paint(Paint.ANTI_ALIAS_FLAG);
…
public void init(Context context, AttributeSet attrs, int defStyle) {
mPaintBg.setStyle(Paint.Style.FILL);
mPaintBg.setColor(Color.argb(128, 233, 233, 233));
mPaintLn.setStyle(Paint.Style.STROKE);
mPaintLn.setColor(Color.argb(128, 187, 187, 187));
mPaintLn.setStrokeWidth(2);
mPaintFg.setStyle(Paint.Style.FILL);
mPaintFg.setColor(Color.argb(255, 0, 153, 204));
}
}
SimpleAnimatedView
Allocate objects you intend to use
in draw & layout once…
…and reference them.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(width, height);
}
SimpleAnimatedView
Information about how big the
ViewParent wants this View to be.
MeasureSpec is a packed int
containing a size and a mode code.
MeasureSpec.makeMeasureSpec(
widthInPx,
MeasureSpec.EXACTLY);
Contract: call before returning.
widthInPx = MeasureSpec.getSize(
widthMeasureSpec);
widthMode = MeasureSpec.getMode(
widthMeasureSpec);
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Measure text width
int w = (int) mTextPaint.measureText(mText)
+ getPaddingLeft() + getPaddingRight();
// Measure text height
int h = (int) (-mTextPaint.ascent(mText) + mTextPaint.descent(mText))
+ getPaddingLeft() + getPaddingRight();
setMeasuredDimension(w, h);
}
SimpleTextView
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Try for a width based on our minimum
int minW = getSuggestedMinimumWidth();
int w = resolveSizeAndState(minW, widthMeasureSpec, 0);
// Set the height according to the width as our control should be
// square
int minH = MeasureSpec.getSize(w);
int h = resolveSizeAndState(minH, heightMeasureSpec, 0);
setMeasuredDimension(w, h);
}
SimpleAnimatedView
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Determine horizontal and vertical padding
int paddingX = getPaddingLeft() + getPaddingRight();
int paddingY = getPaddingBottom() + getPaddingTop();
// Try for a width based on our minimum including horizontal padding
int minW = getSuggestedMinimumWidth() + paddingX;
int w = resolveSizeAndState(minW, widthMeasureSpec, 0);
// Set the height according to the width as our control should be
// square, again compensating for padding
int minH = MeasureSpec.getSize(w) - paddingX + paddingY;
int h = resolveSizeAndState(minH, heightMeasureSpec, 0);
setMeasuredDimension(w, h);
}
SimpleAnimatedView
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
SimpleAnimatedView
Information about where the ViewParent
wants the View to be.
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Typically for ViewGroups; we won’t override onLayout for our View
super.onLayout(changed, l, t, r, b);
}
SimpleAnimatedView
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// Set the drawing location, accounting for padding
mRect.left = getPaddingLeft();
mRect.top = getPaddingTop();
float diameter = Math.min(
w - mRect.left - getPaddingRight(),
h - mRect.top - getPaddingBottom());
mRect.right = mRect.left + diameter;
mRect.bottom = mRect.top + diameter;
mRadius = diameter / 2;
}
SimpleAnimatedView
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(
mRect.left + mRadius,
mRect.top + mRadius,
mRadius, mPaintBg);
canvas.drawCircle(
mRect.left + mRadius,
mRect.top + mRadius,
mRadius, mPaintLn);
canvas.drawArc(
mRect,
mStartAngle,
mSweepAngle - mStartAngle,
true, mPaintFg);
}
SimpleAnimatedView
protected final Runnable animator = new Runnable() {
@Override
public void run() {
// Change some parameters used in onDraw()
mSweepAngle++;
nextFrame();
invalidate();
}
};
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
protected void nextFrame() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
postDelayed(animator, 16);
} else {
postOnAnimation(animator);
}
}
SimpleAnimatedView
Invokes redrawing of the
View.
Schedule drawing the next
frame.
Bonus: ADT
What we’ve done
• Wrote a custom component
• Created custom components in layouts
• Define custom attributes
• Use styles with custom attributes
• Custom measuring
• Custom drawing
TypedArray a;
try {
a = context.obtainStyledAttributes(
attrs, R.styleable.FontTextView, defStyle, 0);
final String typeface =
a.getString(R.styleable.FontTextView_typeface);
} finally {
if (a != null) a.recycle();
}
TypedArray a;
try {
a = context.obtainStyledAttributes(
attrs, R.styleable.FontTextView, defStyle, 0);
final String typeface =
a.getString(R.styleable.FontTextView_typeface);
} finally {
}
Things to be wary of
• Don’t forget to recycle AttributeSets
Things to be wary of
• Avoid object allocations in draw/layout operations
– In other words, listen to Lint!
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
canvas.drawArc(new RectF(0, 0, mSize, mSize), 0, mAngle, true, paint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
canvas.drawArc(new RectF(0, 0, mSize, mSize), 0, mAngle, true, paint);
}
Things to be wary of
private void nextFrame() {
postDelayed(animator, 16);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void nextFrame() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
postDelayed(animator, 16);
} else {
postOnAnimation(animator);
}
}
• Perform draw events in V-sync for JB
Other resources than me
d.android.com
Training
Other resources than me
d.android.com
Guide
Other resources than me
AndroidViews.net
Other resources than me
Smooth animations
blog.jayway.com
Use the Choreographer on JB:
postOnAnimation(this);
Other resources than me
DevAppsDirect
Resources that are me
Grab the code at:
github.com/pflammertsma/droidconfr
Making It Fit
How Android Measures and Draws Views
Paul Lammertsma
CTO

More Related Content

Similar to Making it fit - DroidCon Paris 18 june 2013

Android Custom views
Android Custom views   Android Custom views
Android Custom views Matej Vukosav
 
Responsive mobile design in practice
Responsive mobile design in practiceResponsive mobile design in practice
Responsive mobile design in practiceKirill Grouchnikov
 
View groups containers
View groups containersView groups containers
View groups containersMani Selvaraj
 
Cocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design PatternsCocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design PatternsMaciej Burda
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
React native app with type script tutorial
React native app with type script tutorialReact native app with type script tutorial
React native app with type script tutorialKaty Slemon
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Mario Jorge Pereira
 
Android Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetAndroid Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetPrajyot Mainkar
 
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Codemotion
 
Academy PRO: React native - building first scenes
Academy PRO: React native - building first scenesAcademy PRO: React native - building first scenes
Academy PRO: React native - building first scenesBinary Studio
 
Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino KovacInfinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino KovacInfinum
 
Android App Development - 04 Views and layouts
Android App Development - 04 Views and layoutsAndroid App Development - 04 Views and layouts
Android App Development - 04 Views and layoutsDiego Grancini
 
Kotlin Mullets
Kotlin MulletsKotlin Mullets
Kotlin MulletsJames Ward
 
A mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutesA mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutesJames Pearce
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in AndroidRobert Cooper
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentanistar sung
 

Similar to Making it fit - DroidCon Paris 18 june 2013 (20)

Android 2
Android 2Android 2
Android 2
 
Android Custom views
Android Custom views   Android Custom views
Android Custom views
 
Responsive mobile design in practice
Responsive mobile design in practiceResponsive mobile design in practice
Responsive mobile design in practice
 
View groups containers
View groups containersView groups containers
View groups containers
 
Custom View
Custom ViewCustom View
Custom View
 
Cocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design PatternsCocoa Heads Tricity - Design Patterns
Cocoa Heads Tricity - Design Patterns
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
React native app with type script tutorial
React native app with type script tutorialReact native app with type script tutorial
React native app with type script tutorial
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
 
Android Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection WidgetAndroid Tutorials - Powering with Selection Widget
Android Tutorials - Powering with Selection Widget
 
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
Academy PRO: React native - building first scenes
Academy PRO: React native - building first scenesAcademy PRO: React native - building first scenes
Academy PRO: React native - building first scenes
 
Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino KovacInfinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
Infinum Android Talks #16 - How to shoot your self in the foot by Dino Kovac
 
Android App Development - 04 Views and layouts
Android App Development - 04 Views and layoutsAndroid App Development - 04 Views and layouts
Android App Development - 04 Views and layouts
 
Kotlin Mullets
Kotlin MulletsKotlin Mullets
Kotlin Mullets
 
A mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutesA mobile web app for Android in 75 minutes
A mobile web app for Android in 75 minutes
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 

More from Paris Android User Group

Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014Paris Android User Group
 
Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014Paris Android User Group
 
Extending your apps to wearables - DroidCon Paris 2014
Extending your apps to wearables -  DroidCon Paris 2014Extending your apps to wearables -  DroidCon Paris 2014
Extending your apps to wearables - DroidCon Paris 2014Paris Android User Group
 
Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014Paris Android User Group
 
Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014Paris Android User Group
 
Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014Paris Android User Group
 
Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014Paris Android User Group
 
Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014Paris Android User Group
 
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014Paris Android User Group
 
maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014Paris Android User Group
 
Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Paris Android User Group
 
Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014Paris Android User Group
 
Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014Paris Android User Group
 
Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014Paris Android User Group
 
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014Paris Android User Group
 
What's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet HaaseWhat's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet HaaseParis Android User Group
 
Efficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas RoardEfficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas RoardParis Android User Group
 

More from Paris Android User Group (20)

Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014
 
Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014
 
Extending your apps to wearables - DroidCon Paris 2014
Extending your apps to wearables -  DroidCon Paris 2014Extending your apps to wearables -  DroidCon Paris 2014
Extending your apps to wearables - DroidCon Paris 2014
 
Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014
 
Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014
 
Framing the canvas - DroidCon Paris 2014
Framing the canvas - DroidCon Paris 2014Framing the canvas - DroidCon Paris 2014
Framing the canvas - DroidCon Paris 2014
 
Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014
 
Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014
 
Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014
 
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
 
Buildsystem.mk - DroidCon Paris 2014
Buildsystem.mk - DroidCon Paris 2014Buildsystem.mk - DroidCon Paris 2014
Buildsystem.mk - DroidCon Paris 2014
 
maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014
 
Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014
 
Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014
 
Death to passwords - DroidCon Paris 2014
Death to passwords - DroidCon Paris 2014Death to passwords - DroidCon Paris 2014
Death to passwords - DroidCon Paris 2014
 
Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014
 
Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014
 
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
 
What's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet HaaseWhat's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet Haase
 
Efficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas RoardEfficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas Roard
 

Making it fit - DroidCon Paris 18 june 2013

Editor's Notes

  1. Roman Nurik’sWizardPager (not really a custom component; an extension of Fragments with a model): https://plus.google.com/113735310430199015092/posts/6cVymZvn3f4
  2. Roman Nurik’sWizardPager (not really a custom component; an extension of Fragments with a model): https://plus.google.com/113735310430199015092/posts/6cVymZvn3f4
  3. If you’re trying to make something pretty, like a fancy animation that would otherwise need constant layouting, consider a custom componentIf you’re trying to position graphics in a particular way, you might otherwise end up with lots of (nested) ViewGroups
  4. Adhere to MVCThis also avoids DRY code
  5. Except, it won’t be clumsyIt will be all polymorphic and fit nicely in the MVC pattern
  6. Our example
  7. The basic building block of all Android’s UI components
  8. onMeasure determines a size for a View (and for ViewGroup, its children recursively)
  9. onMeasure determines a size for a View (and for ViewGroup, its children recursively)
  10. onMeasure determines a size for a View (and for ViewGroup, its children recursively)
  11. onMeasure determines a size for a View (and for ViewGroup, its children recursively)
  12. onMeasure determines a size for a View (and for ViewGroup, its children recursively)
  13. onMeasure determines a size for a View (and for ViewGroup, its children recursively)
  14. From DevBytes with Chet Haase: https://plus.google.com/104755487586666698979/posts/dXABXJHBa8n
  15. Feb 21, 2013 by Rich Hyndman: https://plus.google.com/115995639636688350464/posts/EJ8sqwP7jxU
  16. By Anders Ericsson: http://www.jayway.com/2012/08/29/creating-custom-android-views-part-3-animating-your-custom-views-smoothly/