YOU ARE DOWNLOADING DOCUMENT

Please tick the box to continue:

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.


Related Documents