android ui tips & tricks

32
Android UI Tips & Tricks Shem Magnezi

Upload: droidcontlv

Post on 13-Nov-2014

408 views

Category:

Technology


2 download

DESCRIPTION

Shem will share development tips while explaining how things work under-the-hood. As part of his talk, he will demonstrate the right way of working with images, custom views, ListViews and Animations, with an emphasis of how to make your app feel slick and fast on all Android devices.

TRANSCRIPT

Page 1: Android UI Tips & Tricks

Android UI Tips & Tricks

Shem Magnezi

Page 2: Android UI Tips & Tricks

Making your good app great

Know your app

Understand what you

need

No magic/ generic

solutions

You know how to write a good

app

Looks good Feel slick

Not gonna talk about

viral/ design/ downloads

etc...

Page 3: Android UI Tips & Tricks

Agenda

● Working with images● Bring your views into life with

animations● Upgrade your lists views

Page 4: Android UI Tips & Tricks

Working with images

Page 5: Android UI Tips & Tricks

Images in memory

Bitmap memory size:Bitmap.getWidth() * Bitmap.getHeight() * Bitmap.config

Determine how much the bitmap gonna take:Image.width * Image.height * Options.config / Options.sampleSize

Page 6: Android UI Tips & Tricks

Cache Cache Cache

● Use cache for performance● Be careful not using too much memory

Page 7: Android UI Tips & Tricks

Determine your cache size

● Approximate per-application memory: getSystemService(Context.ACTIVITY_SERVICE).getMemoryClass()

● Pay attention to: onTrimMemory(int level) on your Application

● Profile your memory usage live

Page 8: Android UI Tips & Tricks

Loading the proper image type

For small image views work with thumbnails:MediaStore.Images.Thumbnails.getThumbnail(

..., int kind, ...)

MINI_KIND: 512 x 384

MICRO_KIND: 96 x 96

Page 9: Android UI Tips & Tricks

Sample size

Original size is probably too big, so load smaller size.

Original

inSampleSize=2

memory/4

Page 10: Android UI Tips & Tricks

Determine the right sample size

● Get the original image size using: options.inJustDecodeBounds = true;

● Get the view that gonna present the image● Find the minimum sample_size so:

o image.width / sample_size > view.width o image.height / sample_size > view.heighto it also prefer that sample_size will be power of 2 for

faster/ easier decoding

Page 11: Android UI Tips & Tricks

Find your view size

Sometimes your view size is 0 (cause is not yet drawn), so you should wait until the system will draw it:

view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

public void onGlobalLayout() {//load image for the right size

}});

}

Page 12: Android UI Tips & Tricks

Determine image sizeCENTER_CROP

float scale = Math.max(viewW / imgW, viewH / imgH)

float scaledWidth = scaale * viewW;

float scaledHeight = scale * viewHt;

CENTER_INSIDE

float scale = Math.min(viewW / imgW, viewH / imgH)

float scaledWidth = scaale * viewW;

float scaledHeight = scale * viewHt;

Page 13: Android UI Tips & Tricks

Make your cache a bit smarterget(Item image, Size size) {

cached = getImage(image);if (cached != null) {

if (cached.size >= size) {

//saved time!

} else {//maybe

display a lower //resolution until loading

//the full image}

} else {//photo not in cache,

but we//did our best}}

put(Item image, Size size) {if (size < MICRO_KIND_SIZE) {

//load micro kind thumbnail

} else if (size < MINI_KIND_SIZE) {

//load mini kind thumbnail

} else {//read the full image

with the//right sample size

}}

Page 14: Android UI Tips & Tricks

Bitmap config

ARG_565 has no alpha channel and is it in lower quality

But:● It’s ~x2 faster to load● It consume half of the

memory● Most of the time you

won’t see any differencesource: Romain Guy

Page 15: Android UI Tips & Tricks

Animations

Page 16: Android UI Tips & Tricks

Interpolator

Sometimes you can use interpolator instead of couple of sequenced animations.For example, the built-in bounce animation on android.

Page 17: Android UI Tips & Tricks

Between-activities animationsSet activity style:<item name="android:windowBackground">@android:color/transparent</item>

When moving to this activity:startActivity(intent);overridePendingTransition(0, 0);

Do the animation:ViewTreeObserver observer = animationImage.getViewTreeObserver();observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

public boolean onPreDraw() {animationImage.getViewTreeObserver().removeOnPreDrawListener(this); runEnterAnimation(back, startBounds);}});

Page 18: Android UI Tips & Tricks

Pre drawer listener?

Very useful for animations!● Create enter animation to your activity● Create animation to your view when

it’s added to the screen● Animate list items when the list

changes

Page 19: Android UI Tips & Tricks

Smart image animation

Page 20: Android UI Tips & Tricks

Case #1Scaling animation for the image view:ObjectAnimator.ofFloat(image_1, "scaleY", 1, 1.5f);

<ImageViewandroid:id="@+id/image_1" android:layout_width="225dp"android:layout_height="150dp"android:scaleType="centerCrop"/>

When animating the view there is no re-layout and the image not preserving it’s scale type

Page 21: Android UI Tips & Tricks

Case #2Use a frame and do a reverse scaling to the inner image:<RelativeLayout android:id="@+id/image_2"

android:layout_width="225dp"android:layout_height="150dp"> <ImageView android:id="@+id/inner_image"android:layout_width="225dp"android:layout_height="300dp"android:layout_marginTop="-75dp" android:layout_marginBottom="-

75dp"/></RelativeLayout>

anim.playTogether(ObjectAnimator.ofFloat(image_2, "scaleY", 1,

1.5f), ObjectAnimator.ofFloat(inner, "scaleY", 1f, 0.6666f));

● Lots of calculations

● The animation is not linear

● Need an extra view

Page 22: Android UI Tips & Tricks

Case #3Use an extra image as the target view:anim.playTogether(ObjectAnimator.ofFloat(image_3, "scaleY", 0.6666f, 1f),ObjectAnimator.ofFloat(image_3, "alpha", 0, 1));

<ImageViewandroid:id="@+id/image_3" android:layout_width="225dp"android:layout_height="225dp"android:scaleType="centerCrop"/>

● You are losing the original view

● The animation isn’t smooth

Page 23: Android UI Tips & Tricks

Case #4Implement you own Animation:public class ExpandAnimation extends Animation {

protected void applyTransformation(float inp ...) {...if (inp < 1.0f) {

lp.height =(int)(start + (end - start)* inp);mAnimatedView.requestLayout();

}}

<ImageView android:id="@+id/image_4"android:layout_width="225dp"

android:layout_height="150dp" android:scaleType="centerCrop" />

Page 24: Android UI Tips & Tricks

Working with Lists

Page 25: Android UI Tips & Tricks

The basic things

● Reuse items● ViewHolder pattern● Long tasks should run in background

with AsyncTask● Cancel view loading tasks using

RecyclerListener

● Use ListFragment

Page 26: Android UI Tips & Tricks

Profile your drawing

● Design your layout as flat as you can● Avoid over drawing or nested weights● Profile your list using GPU overdraw

and GPU Rendering in developer options

Page 27: Android UI Tips & Tricks

Empty view in your ListFragment

Use android:id="@android:id/empty"

for the case the list is empty

<ListView android:id="@android:id/list" … /><RelativeLayout android:id="@android:id/empty" ... />

Page 28: Android UI Tips & Tricks

Save each item state

In your adapter:Set<Integer> opened = HashSet<Integer>();

On widget opened:opened.add(item.getId());

In getView():view.setOpened(opened.contains(item.getId());

Page 29: Android UI Tips & Tricks

Scrolled view inside ListViewYou sometime want to put a view that can be scrolled by himself as one of your listview items- for example putting a grid view of images.For doing it you must let layout manager that this view must take it’s full size:

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,

MeasureSpec.AT_MOST);

super.onMeasure(widthMeasureSpec, heightSpec);

getLayoutParams().height = getMeasuredHeight();

}

source: stackoverflow.com

Page 30: Android UI Tips & Tricks

Smart scrollbar for easy navigation

● Put a relative view that contains your list view and set him as a OnScrollListener

● On onScroll calc the right position of your scroller view using totalItemCount and visibleItemCount

● On draw put your scroller view using setTranslationY

Page 31: Android UI Tips & Tricks

Smart scrollbar for easy navigationYou can even add a behavior for dragging the scroller using onTouchEvent:public boolean onTouchEvent(MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {if (//event in scroll bar view)

mDragging = true;} else if (me.getAction() == MotionEvent.ACTION_UP) {

if (mDragging) mDragging = false;} else if (me.getAction() == MotionEvent.ACTION_MOVE) {

if (mDragging)mList.setSelectionFromTop(//calc the right item index, 0);}}

Page 32: Android UI Tips & Tricks

</presentation>

Thank you.