Upload
somkiat-khitwongwattana
View
953
Download
0
Embed Size (px)
Citation preview
@Akexorcist
Advance Android Layout Walkthrough
การออกแบบเลย์เอาท์ บนแอนดรอยด์เบื้องต้น
Model ViewPOJO Layout
Activity/Fragment
Java XML
Java
MVC in Android
Controller
View Group
View
View
View GroupLinear Layout
Frame Layout
Relative Layout
Coordinator Layout
Toolbar
Button
Text View
Card View
Recycler View
Progress Bar
View
มองเรื่องเลย์เอาท์ให้เป็น 3 มิติ
y
x
z
y
x
Linear Layout (Vertical)
z
y
x
Linear Layout (Vertical)
z
y
x
Linear Layout (Vertical)
z
y
x
Linear Layout (Horizontal)
z
y
x
Frame Layout
z
y
x
Frame Layout
z
y
x
1
1
2
3
2
3
z
Relative Layout
y
x
AA BC
BC
zRelative Layout
View Group
View
Match Parent และ
Wrap Content
Code Mania 11
OK
WTF!?
Width & Height
Wrap Content
Code Mania 11
Width
Match Parent
OK
WTF!?
Height
Wrap Content
Code Mania 11
OK
Width & Height
Match Parent
Code Mania 11 OK
Width
Match Parent
Height
Wrap Content
Android Auto
Android Design Layout
Android Studio
2.0 Beta 5
Horizontal
Linear Layout Width : Match Parent Height : Wrap Content
Button Width : 0dp Height : Match Parent Weight : 1
Margin และ Padding
Code Mania 11
Code Mania 11Margin
Code Mania 11Margin
Padding
Code Mania 11
Button และ Image Button
Button Image Button
background
text src
background
+ OK = OK
+ =
OK
+ =
+ =
+ =
+ =
+ =
+ =
3+2 || 3x2
Drawable Resources
มีให้ใช้โคตรเยอะ
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
ic_food_online
ic_delivery
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
Original
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.... <item android:width="40dp" android:height="40dp" android:drawable="@drawable/ic_activation_01" android:gravity="center" /> <item android:width="30dp" android:height="30dp" android:drawable="@drawable/ic_activation_02" android:gravity="center" /> <item android:width="20dp" android:height="20dp" android:drawable="@drawable/ic_activation_03" android:gravity="center" /> </layer-list>
+ + =
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.... <item android:drawable="@drawable/btn_ok_pressed" android:state_enabled="true" android:state_pressed="true" /> <item android:drawable="@drawable/btn_ok_disable" android:state_enabled="false" /> <item android:drawable="@drawable/btn_ok_normal" /> </selector>
Button Button Button
Normal State
Pressed State
Disable State
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
ImageView ivScore = (ImageView) findViewById(R.id.iv_asd); int score = ...; ...
if(score == 0) { ivScore.setImageResource(R.drawable.ic_score_bad); } =else if(score == 1) { ivScore.setImageResource(R.drawable.ic_score_ok); } else if(score == 2) { ivScore.setImageResource(R.drawable.ic_score_good); }
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android... <item android:drawable="@drawable/ic_score_bad" android:maxLevel="0" /> <item android:drawable="@drawable/ic_score_ok" android:maxLevel="1" /> <item android:drawable="@drawable/ic_score_good" android:maxLevel="2" /> </level-list>
ImageView ivScore = (ImageView) findViewById(R.id.iv_score); int score = ...; ... ivScore.setImageLevel(score);
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
ImageView ivScore = (ImageView) findViewById(R.id.iv_score); TransitionDrawable drawable = (TransitionDrawable) ivScore.getDrawable(); ...
drawable.startTransition(1000);drawable.reverseTransition(1000);
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/... <item android:drawable="@drawable/ic_score_very_bad" /> <item android:drawable="@drawable/ic_score_very_good" /> </transition>
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
ImageView ivScore = (ImageView) findViewById(R.id.iv_score); TransitionDrawable drawable = (TransitionDrawable) ivScore.getDrawable(); ...
drawable.reverseTransition(1000);
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/... <item android:drawable="@drawable/ic_score_very_bad" /> <item android:drawable="@drawable/ic_score_very_good" /> </transition>
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/... android:drawable="@drawable/bg_badge" android:insetBottom="10dp" android:insetLeft="10dp" android:insetRight="10dp" android:insetTop="10dp"/>
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/... android:clipOrientation="horizontal" android:drawable="@drawable/ic_rate_very_good" android:gravity="left" />
ImageView ivRate = (ImageView) findViewById(R.id.iv_rate); ClipDrawable drawable = (ClipDrawable) ivRate.getDrawable(); ... drawable.setLevel(5000);
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/... android:drawable="@drawable/ic_code_mania" android:scaleGravity="center" android:scaleHeight="60%" android:scaleWidth="60%" />
Bitmap File Nine-Patch File Layer List State List Level List Transition Drawable Inset Drawable Clip Drawable Scale Drawable Shape Drawable
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/... <stroke android:width="4dp" android:color="#ffffff" android:dashGap="10dp" android:dashWidth="10dp" /> <solid android:color="#237793" /> <corners android:radius="10dp" /> </shape>
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="horizontal" android:gravity="left"> <shape> <solid android:color="#ffd200" /> <corners android:radius="50dp" /> </shape> </clip>
Drawable Mixing
<View>, <Space> และ <ViewStub>
<View android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="#DDDDDD"/>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp">
<ImageView android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/ic_header_notify_01" />
<Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" />
<ImageView android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/ic_header_notify_02" /> </LinearLayout>
<ViewStub android:id="@+id/vs_update_progress" android:layout_width="match_parent" android:layout_height="wrap_content" android:inflatedId="@+id/view_update_progress" android:layout="@layout/view_update_info_progress" />
<include> กับ <merge>
<include layout="@layout/view_user_info" android:layout_width="match_parent" android:layout_height="wrap_content" />
<LinearLayout>
<ImageView>
<TextView>
<Button>
<LinearLayout>
<include>
<LinearLayout>
<TextView>
<LinearLayout>
<LinearLayout>
<TextView>
<LinearLayout>
<ImageView>
<TextView>
<Button>
<merge>
<ImageView>
<TextView>
<Button>
<LinearLayout>
<include>
<LinearLayout>
<TextView>
<LinearLayout>
<LinearLayout>
<TextView>
<ImageView>
<TextView>
<Button>
ใช้ Style ดูสิ
ชีวิตจะได้ง่ายขึ้น
<style name="NextzyButton"> <item name="android:textSize">16sp</item> <item name="android:textColor">#FFFFFF</item> <item name="android:minWidth">100dp</item> <item name="android:minHeight">48dp</item> </style>
<style name="NextzyButton.Blue" parent="NextzyButton"> <item name="android:background">@drawable/shape_nextzy_button_blue</item> </style>
<style name="NextzyButton.Green" parent="NextzyButton"> <item name="android:background">@drawable/shape_nextzy_button_green</item> </style>
<Button style="@style/NextzyButton.Blue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" />
Cancel
Cancel
<Button style="@style/NextzyButton.Green" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" />
Developer options ช่วยคุณได้
Show layout boundaries
Window Animation scale 5x
Transition Animation scale 5x
Animator duration scale 5x
Overdraw 4x or more
Overdraw 3x
Overdraw 2x
Overdraw 1x
Debug GPU overdraw
Tips เล็ก Tricks น้อย
Android Layout Drawing Process
• Measure
• Layout
• Draw
?
?
?
?
?
?
Android Layout Drawing Process
• Measure
• Layout
• Draw
Android Layout Drawing Process
• Measure
• Layout
• Draw
View Inflation worked on the UI ThreadExtremely View Inflation == Block the UI Thread
Hierarchy Viewer Android Device Monitor
Is RelativeLayout expensive?Yes, if you're using nested RelativeLayout.
But single RelativeLayout is cheaper than nested LinearLayout.
RelativeLayout LinearLayout
Total view count <= 80 views
Nested deep level <= 10 levels
More android:layout _ weight
More Expensive
==
Use tint color with icon image
Original android:tint="#000000" android:tint="#ffcc00"
RecyclerView Master Complex Lists
Use it!!!!!
ScrollView for some items RecyclerView for many items
ScrollView RecyclerView
Avoid various dimension values Better way, try to use global values
<dimen name="default_margin_padding_extra_small">1dp</dimen> <dimen name="default_margin_padding_small">2dp</dimen> <dimen name="default_margin_padding">4dp</dimen> <dimen name="default_margin_padding_large">8dp</dimen> <dimen name="default_margin_padding_extra_large">16dp</dimen>
Shadow in Material Theme (Lollipop+)
Button
Margin >= 10dp
Button
Margin < 10dp
Vector Drawable Say goodbye to bitmap
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="80dp" android:height="80dp" android:viewportWidth="80" android:viewportHeight="80"> <path android:pathData="M0 0h24v24H0z" /> <path android:fillColor="#FFFFFF" android:pathData="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z" /> </vector>
SVG >> VectorDrawable http://inloop.github.io/svg2android/
Vector Drawable Compat Yeah! It's also supported on pre-Lollipop
ทํายังไงให้รองรับ หน้าจอได้หลายขนาด?
Too much fragmentation!
DP : Unit in Android world
1,920x1,080 PX
640x360 DP
Nexus 5X
Stay flexible design
Fixed Size
Dynamic Size
Scro
llabl
e
Bucket of various densitiesLDPI MDPI TVDPI HDPI
280DPI XHDPI 360DPI 400DPI 420DPI XXHDPI 560DPI
XXXHDPI
120 160 213 240 280 320 360 400 420 480 560 640
Bucket of various densitiesLDPI MDPI TVDPI HDPI
280DPI XHDPI 360DPI 400DPI 420DPI XXHDPI 560DPI
XXXHDPI
120 160 213 240 280 320 360 400 420 480 560 640
0.75 1 - 2 - 3 - - - 4 - 6
Bucket of various densitiesLDPI MDPI TVDPI HDPI
280DPI XHDPI 360DPI 400DPI 420DPI XXHDPI 560DPI
XXXHDPI
120 160 213 240 280 320 360 400 420 480 560 640
0.75 1 - 2 - 3 - - - 4 - 6
Bucket of various densitiesLDPI MDPI TVDPI HDPI
280DPI XHDPI 360DPI 400DPI 420DPI XXHDPI 560DPI
XXXHDPI
120 160 213 240 280 320 360 400 420 480 560 640
75x75 113x113
- 150x150
- 225x225
- - -
300x300 -
450x450
Android Drawable Importer
Which density should be supported
Regular ImageApp Icon
MDPI HDPI
XHDPI XXHDPI
XXXHDPI
MDPI HDPI
XHDPI XXHDPI
ใช้ Vector แทน Bitmap เถ๊อะ!! (แต่ภาพบางอย่างก็เลี่ยงไม่ได้เนอะ)