#AndroidStudio ตอนที่ 10 สำรวจ Layout และ properties ที่น่าสนใจ 6 Layout

#AndroidStudio ตอนที่ 10 สำรวจ Layout และ properties ที่น่าสนใจ 6 Layout

<introduction>
อารัมภบท
เกิดข้อสงสัย จึงอยากชวนไปสำรวจ ว่ามี Layout อยู่เท่าไรที่เราทำเป็น Root layout เพราะ Theme: Basic Activity เตรียม CoordinatorLayout มาให้เราใช้ ส่วน Empty Activity เตรียม ConstraintLayout มาให้ เมื่อเข้า Layout Editor หรือ UI Builder เพื่อสร้าง UI แล้วเข้าส่วน Design มองใน Palatte หัวข้อ Layouts จะพบ 9 ตัวเลือก คือ ConstraintLayout, GridLayout, FrameLayout LinearLayout(horizontal), LinearLayout(vertical), RelativeLayout, TableLayout, TableRow, และ  อันที่จริงยังมี Layout มากกว่านี้ อาทิ CoordinatorLayout หรือ AppbarLayout เป็นต้น

ขณะสำรวจ และทดสอบในบทบาท ผู้ใช้โปรแกรม Android Studio ทำการสร้าง Layout ก็ย่อมมีปัญหา ไม่ได้อย่างใจหมายหลายครา ทำให้มีโอกาสสืบค้น และได้พบบทความเกี่ยวกับ Layout ที่ akexorcist.com และ devahoy.com พบว่านักเขียนเล่าอะไรหลายอย่างเกี่ยวกับ Android ทำให้เข้าใจขึ้นมาก ลองไปหาอ่านดูนะครับ

สรุปกระบวนการ ได้ 5 ขั้นตอน ประกอบด้วย 1) สร้าง Project แบบ Basic Activity ไว้เรียก Layout อื่น 2) การปรับ orientation ของ LinearLayout เป็น vertical กับ horizontal 3) การแสดงข้อมูล 3 column โดยใช้ TextView บน LinearLayout 4) การสร้าง relativelayout.xml 5) การทำภาพ overlay แบบ RelativeLayout 6) copy overlay.xml แล้ว paste constraintlayout.xml 7) การสร้าง gridlayout.xml 8) การสร้าง tablelayout.xml

ปล. แฟ้ม Project ผมบีบไว้ และแชร์ให้ Download ทั้ง .rar และ .apk ไปทดสอบกัน
ที่ http://www.thaiall.com/android (ผ่าน 4shared.com)

</introduction>

<definition>
นิยามศัพท์

  1. LinearLayout คือ เค้าโครงเพื่อจัดวางวัตถุแบบเรียงลำดับ เลือกเรียงแบบ ตามแนวตั้ง (Vertical) หรือตามแนวนอน (Horizontal) เป็น Default Layout เมื่อสร้าง Layout XML File ขึ้นใหม่
  2. RelativeLayout คือ เค้าโครงเพื่อจัดวางวัตถุที่สัมพันธ์กัน เชื่อมโยง อ้างอิง อาจอ้างอิงวัตถุอื่น หรืออ้างอิง Parent ก็ได้ การใช้ Layout Editor จะช่วยให้จัดวาง เห็นภาพใน Blueprint ทำได้สะดวกขึ้นแทนการเข้าไปกำหนดใน XML file โดยตรง
  3. ConstraintLayout คือ เค้าโครงแบบเพื่อจัดวางวัตถุแบบใหม่ คล้าย RelativeLayout มาก และ Android สนับสนุนให้ใช้ เป็นเค้าโครงที่เหมาะสำหรับนักพัฒนาที่ไม่ถนัด XML file มี Layout Editor ที่รองรับการจัดวางผ่าน Blueprint และลดจำนวนเค้าโครงที่ซับซ้อนได้
  4. GridLayout คือ เค้าโครงเพื่อจัดวางวัตถุแบบต่อเนื่อง ในช่องที่จัดเตรียมเป็นตะแกรง หรือจะหย่อนวัตถุไปตามตาที่กำหนดได้ ตัวอย่างการใช้ คือ Image Gallery หรือการแสดงรายการ App บนสมาร์ทโฟน ก็แสดงเป็น Grid
  5. TableLayout คือ เค้าโครงเพื่อจัดวางวัตถุ โดยกำหนดเป็น Row กับ Column เหมาะกับการวางข้อมูลจากระบบ Database ที่แบ่งข้อมูลเป็น Record กับ Field ไว้แล้ว แต่จะจัดวางเป็นฟอร์มสำหรับ Input ข้อมูลก็สามารถสั่งขยายช่องด้วย span ได้
  6. CoordinatorLayout คือ เค้าโครงเพื่อจัดวางวัตถุที่แตกต่างรูปแบบในหน้าเดียวกัน อาจมีทั้ง Slide, Panel, Button หรือ Stick และ Animate ก็ทำได้
  7. ViewGroup คือ เป็นกลุ่มของ View ที่ทำหน้าที่จัดวางเค้าโครง มี subclass ทั้งแบบ Direct (19 Layout) และ Indirect (63 Layout) หากต้องการหา Layout ที่ตรงกับความต้องการให้เข้ามาดูรายชื่อ subclass แล้วเข้าไปดู description และ method ได้

</definition>

กำลังเล่าเรื่อง การใช้โปรแกรม Android Studio สู่เพื่อนนักพัฒนา ผ่าน Blog

<process>
กระบวนการในการพัฒนา APP
เพื่อสำรวจการใช้งาน Layout แต่ละแบบ ว่าใช้งานแตกต่างกันอย่างไร
มีขั้นตอน ดังนี้

1. สร้าง Project แบบ Basic Activity ไว้เรียก Layout อื่น
ตั้งชื่อว่า layoutsample แล้วเตรียม menu, string, activity, layout
ในตอนนี้เราจะ include Layout แล้วเลือก include ผ่าน ViewFlipper
ตามที่เล่าใน ตอนที่ 9 ข้อ 3 ว่าเราสร้าง Menu ผ่าน ToolBar ได้
แล้วเพิ่ม include คู่กับ visible หรือ gone หลายรายการ
เพื่อคุมการ select ใน Menu ให้ได้ผลตามต้องการ
ตัวอย่างนี้ขอปรับการเลือกควบคุมสลับ visible กับ gone
เป็นการใช้ ViewFlipper คลุมใน activity_main.xml และ MainActivity.java

1.1 เริ่มจากสร้าง linearlayout.xml เปล่า ขึ้นมาก่อน
เพื่อเตรียมไว้เป็นตัวเลือกที่ 1 เพราะตัวเลือกแรก คือ content_main.xml
ที่มีมากับ Basic Activity แล้วแสดงคำว่า Hello world!

1.2 ปรับ code ใน activity_main.xml
เพื่อเพิ่ม ViewFlipper เข้าควบคุมการ include

มองหา
 <include layout="@layout/content_main" />
 เปลี่ยนเป็น
 <ViewFlipper
 android:id="@+id/view_flipper"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <include layout="@layout/content_main" />
 <include layout="@layout/linearlayout" />
 </ViewFlipper>

1.3 ปรับ code ใน MainActivity.java
เพื่อเปลี่ยนจากการใช้ if ไปใช้ switch คุมการ setDisplayedChild ที่ต้องการ

มองหา
 if (id == R.id.action_settings) {
 return true;
 }

เปลี่ยนเป็น
 import android.widget.ViewFlipper;
 ViewFlipper vf = (ViewFlipper) this.findViewById(R.id.view_flipper);
 switch (item.getItemId()) {
 case R.id.content:
 vf.setDisplayedChild(0);
 return true;
 case R.id.linearlayout:
 vf.setDisplayedChild(1);
 return true;
 }

1.4 ไปเพิ่ม <item> ใน menu_main.xml และ <string> ใน strings.xml
เพื่อให้มีตัวเลือกสำหรับการคลิ๊กใน menu
เพื่อเลือก case R.id.content และ case R.id.linearlayout
เพราะขณะนี้มี 2 layout ที่พร้อมทำงานใน menu

1.5 ระหว่างสร้าง string พบการปัดบรรทัดที่มีผลกับ layout
โดยตัวอักษรที่ปัดบรรทัด หรือ Line Break ด้วย \n
ปัญหานี้เล่าใน ตอนที่ 8.1 แต่มาพบ \n ในตอนนี้

<string name="datawith2br">a\nb\nc</string>

2. การปรับ orientation ของ LinearLayout เป็น vertical กับ horizontal
เมื่อสร้าง linearlayout.xml พบว่าค่า default ไม่ได้กำหนดว่า orientation เป็นอะไร
แต่ default เป็น horizontal แม้ไม่ได้กำหนดก็ตาม

2.1 ทดสอบเพิ่ม TextView ที่มี @string/data
ได้เพิ่มแบบไม่กำหนด id จำนวน 20 tag
ปัญหาแรก พบว่า ข้อมูลเบียนกันจนแน่นในแถวเดียว เป็นปัญหาเรื่องตำแหน่ง
หากจำนวนข้อมูลน้อยกว่า 20 tag ก็จะแสดงผลได้ปกติ แต่กรณีนี้มากไป
และไม่ได้จัดเรียงแบบ wrap ลงมาบรรทัดต่อไป
นี่เป็นค่า default ของ orientation ที่เป็นแบบ horizontal
อีกปัญหา พบว่า ทั้งใน emulator และ smart phone
บน emulator จะแสดงคำว่า data ทับ AppbarLayout
บน smartphone จะคำว่า data ถูกทับด้วย AppbarLayout

<TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/data" />

[ปัญหา]
สรุปว่า พบปัญหาการแสดงผลในทั้ง 2 อุปกรณ์
เนื่องจากต้องการให้ตำแหน่งเริ่มต้นแสดงผลต่อจาก Appbarlayout
ไม่ใช่ทับกันไปมา ระหว่าง TextView กับ Appbarlayout แบบนั้น
[วิธีแก้ไข]
เพิ่ม android:layout_marginTop=”?attr/actionBarSize” ใน layout
ทดสอบกับทั้ง linearlayout.xml และ content_main.xml
แม้จะเปลี่ยน wrap_content เป็น match_parent แล้ว ก็ไม่มีปัญหา

2.2 ทดสอบเพิ่ม android:orientation=”vertical”
* ใน layout แบบ ConstraintLayout หรือกำหนด width=”match_parent”
ผล คือ data ทับกันในตำแหน่งเดิม แสดงว่า ไม่รองรับการกำหนดเป็น vertical
* ใน layout แบบ LinearLayout
ผล คือ เรียงต่อกันมาตามแนวนอน บรรทัดละ 1 คำอย่างถูกต้อง
แม้กำหนดเป็น wrap_content ทุกตัวก็ตาม

 

3. การแสดงข้อมูล 3 column โดยใช้ TextView บน LinearLayout
กำหนดให้ แท่งแรกกว้าง 25% (0.25) แท่งที่สอง 50% (0.5) แท่งที่สาม 25% (0.25)
แก้ไขในแฟ้ม linearlayout.xml เดิม
ไปอ่านมาจาก https://devahoy.com/posts/android-layout-linear-layout/

ปรับ properties ที่ใช้ใน TextView ดังนี้

background="#00ff00" คือ สีพื้นเขียว
padding="5dp" คือ ช่องว่างระหว่างตัวอักษรกับขอบใน
gravity="center" คือ อยู่ตรงกลางของ TextView
layout_width="wrap_content" คือ ขนาดเท่าข้อมูล
layout_height="match_parent" คือ ขนาดเต็มจอ
layout_weight="0.50" คือ กว้าง 50%
layout_marginStart="5dp" คือ เว้นว่างทางซ้าย

4. การสร้าง relativelayout.xml
เลือก Layout XML File ที่มี Root Tag = RelativeLayout
แล้วเพิ่มตัวเลือกเข้าไปใน menu จะได้เรียกมาทดสอบได้ง่าย
แก้ให้ครบทุกจุดนะครับ เพราะมีเยอะเลยที่ต้องแก้ให้สอดคล้องกัน
แม้เป็นตัวเลือกที่ 3 แต่ต้องกำหนด vf.setDisplayedChild(2);
อ่านความหมายของ Layout ที่ devahoy.com
เรียบเรียงได้ว่า LinearLayout และ RelativeLayout
ต่างเป็น View Group เหมือน Container มีไว้รวบรวม Child View หรือ Widget
มีสิ่งที่ต่างกันใน 2 Layout คือ การจัดเรียง
ถ้า LinearLayout ก็จัดเรียงแบบ horizontal หรือ vertical
ถ้า RelativeLayout ก็จัดเรียงอย่างมีความสัมพันธ์ ซึ่งกันและกัน
การจัดเรียงค่อนข้างเป็นอิสระ และเชื่อมโยงตามลำดับ ทำให้นึกถึง linked list

ปรับ properties ที่ใช้ใน TextView ดังนี้

id="@+id/tv1" คือ การตั้งชื่อให้ TextView
layout_toEndOf="@+id/tv1" คือ อยู่ต่อท้าย tv1
layout_alignParentStart="true" คือ ตำแหน่งเริ่มซ้ายของจอ
textSize="16sp" คือ ขนาดตัวอักษร 16
layout_below="@+id/tv1" คือ อยู่ข้างล่างต่อจากภาพ tv1
layout_toEndOf="@+id/tv1" คือ เริ่มต่อจากด้านขวาของ tv1
gravity="center|center_vertical" คือ อักษรอยู่กลาง
layout_alignParentEnd="true" คือ ชิดด้านซ้ายของจอภาพ
layout_alignParentBottom="true" คือ ชิดด้านล่างขอจอภาพ

5. การทำภาพ overlay แบบ RelativeLayout
สร้าง Layout ใหม่ชื่อ overlay.xml และ Root Tag = RelativeLayout
ส่งภาพเข้า drawable ผมเตรียมภาพขนาด 360*640 
เพราะโทรศัพท์ของผมขนาดเท่านี้
https://www.whatismyscreenresolution.com/

ปรับ properties ที่ใช้ใน TextView ดังนี้

android:layout_marginTop="?attr/actionBarSize" คือ ของ RelativeLayout
android:contentDescription="@string/data" คือ รายละเอียดของภาพ 
android:scaleType="fitXY" คือ กำหนดให้ภาพพอดีกับตำแหน่ง X และ Y
app:srcCompat="@drawable/lp01" คือ การใส่ภาพจาก drawable
gravity="center" คือ ข้อความอยู่ตรงกลาง
textSize="60sp" คือ ขนาดตัวอักษร
textColor="#000000" คือ สีตัวอักษร
background="#00ff00" คือสีพื้น
alpha="0.3" คือ การกำหนดระดับความโปร่งแสง
layout_alignParentStart="true" คือ ชิดด้านซ้าย

 

6. copy overlay.xml แล้ว paste constraintlayout.xml
เข้าไปอ่าน blog ของ akeorcist.com เห็นชัดเลยว่า
Android เชียร์ให้ใช้ ConstraintLayout แทน RelativeLayout
เพราะจัดการง่ายผ่าน UI Builder และมีขนาดเล็กกว่า
งานที่เคยทำใน RelativeLayout สามารถแปลงเป็น ConstraintLayout อัตโนมัติ
จึงคัดลอก overlay.xml เป็นวางแฟ้มเป็นชื่อใหม่คือ constraintlayout.xml
เข้า design แล้วคลิ๊กที่ RelativeLayout ใน Component Tree
กด Right Click จะมี Convert RelativeLayout to ConstraintLayout มาให้
แล้วมีให้เลือกทำ Flatten Layout Hierarchy
กรณีของผม ต้องปรับรายละเอียดใน ImageView และ TextView
เพราะ layout เปลี่ยน properties ก็ต้องเปลี่ยน เพี้ยนไปบ้าง

ใน ImageView ก็ต้องทำให้ขอบภาพชิดกับของ parent ดังนี้

app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

แต่ข้อความใน TextView ถูกเปลี่ยนให้เชื่อมกับส่วนอื่น ทำให้อยู่ตรงกลางของจอ

app:layout_constraintRight_toRightOf="@+id/imageView"
app:layout_constraintLeft_toLeftOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:layout_constraintBottom_toTopOf="@+id/button"

7. การสร้าง gridlayout.xml
พบว่า GridLayout เป็นเค้าโครงคล้ายตาราง ใส่ข้อมูลเป็นช่องตาม row หรือ column
แล้วมี GridView ที่ช่วยให้การใส่ image เป็น gallery ได้ง่าย
รองรับการใส่ข้อมูลจำนวนมาก มีความเป็นอัตโนมัติผ่านการจัด orientation
Default คือ orientation:horizontal คือ เรียงแนวนอนไปทางขวาจนจบแถว
แล้วขึ้นแถวต่อไป
ขณะทดสอบพบว่า SDK ที่ผมใช้ตัวล่างที่ติดตั้งไว้ คือ API 19
แล้วไม่รองรับ layout_weight in LinearLayout. This is supported in API 21.

ตัวอย่างการใส่ TextView เข้าไปใน Row และ Column ที่กำหนด

<TextView
 android:layout_row="0"
 android:layout_column="0"
 android:id="@+id/textView3"
 android:textSize="16sp"
 android:background="#00ff00"
 android:layout_width="80dp"
 android:layout_height="80dp"
 android:text="@string/data" />

ตัวอย่างการใส่ Button เข้าไปอัตโนมัติ ช่องไหนว่างตาม orientation ก็เข้าไปเลย

<Button
 android:id="@+id/button6"
 android:layout_width="80dp"
 android:layout_height="80dp"
 android:text="@string/data" />

8. การสร้าง tablelayout.xml
เป็นการวางเค้าโครงให้รองรับการใส่ข้อมูลเป็น row กับ column
ทำให้นึกถึงการเขียน Table ในภาษา HTML ที่มี tr กับ td
ทำ span เพื่อขยายพื้นที่ของ cell ได้
เมื่อใส่ TextView ลงไปก็เป็นเพียงข้อมูลที่นำมาต่อกันใน 1 cell
แต่ TextView ที่มี android:layout_weight=”1″ จะมีน้ำหนักเป็น cell
มักต้องใส่ในทุก TextView เพื่อประกาศการเป็น cell

ตัวอย่างการเค้าโครงการวาง Tag ของ TableLayout

<TableLayout>
  <TableRow>
     <TextView android:layout_weight="1">
     <TextView android:layout_weight="1">
  </TableRow>
</TableLayout>

</process>

<website_guide>
https://www.whatismyscreenresolution.com/
http://www.akexorcist.com/..new-android-layout.html
https://devahoy.com/..relative-layout-tutorial/
+ http://www.journaldev.com/..viewflipper-example-tutorial
+ http://www.programcreek.com/..&method=setDisplayedChild
+ https://developer.android.com/../view/ViewGroup.html
https://developer.android.com/guide/topics/ui/layout/grid.html
+ https://developer.android.com/../widget/TableLayout.html
</website_guide>

หมายเหตุ 
ถ้าสนใจติดตามเนื้อหาในบล็อกนี้ สามารถ subscribe ด้วย email ที่อยู่ข้างขวา หรือ click here

#AndroidStudio ตอนที่ 9 Layout ของการแจ้งเตือน และการสร้าง Layout at Runtime และเมนู กับการแสดงภาพต่อตาม Vertical

#AndroidStudio ตอนที่ 9 Layout ของการแจ้งเตือน
และการสร้าง Layout at Runtime และเมนู กับการแสดงภาพต่อตาม Vertical

<introduction>
อารัมภบท
ความตั้งใจครั้งแรก คือ การวาง Layout ของการแจ้งเตือน โดยแสดง ImageView และ TextView คู่กัน เรียงเป็นบรรทัดลงไปแบบ Vertical แต่พอได้ลงไปวาง Layout พบว่า โปรแกรมแนะนำว่าให้ใช้ Drawable ตามที่เคยใช้ใน ตอนที่ 8 ข้อ 8 พอใช้ตามคำแนะนำ ก็พบปัญหา ความตั้งใจจึงเบี่ยงเบนไปเรื่องการทำ Valign=Top ว่าทำอย่างไรให้ภาพอยู่ในตำแหน่ง Top แล้วก็ไปสนใจการใช้ Layout แบบ RelativeLayout จากนั้นก็กลับมาคิดเรื่อง Notification ว่าควรลื่นไหลขณะ Runtime เหมือนที่เห็นใน FB Message
ก็พบว่าการวาง Layout ใน Android ทำได้ 2 แบบ คือ Declare UI elements in XML และ Instantiate layout elements at runtime เมื่อไปค้นดูก็ไปไม่ถึงไหน ได้แค่การสั่งให้สร้าง Layout at Runtime ใหม่ขึ้นมา พร้อมสร้าง TextView และส่งค่าเข้า TextView ที่สร้างขึ้น

ความเดิมตอนที่แล้ว เคยเล่าเรื่องการใช้ Template : Basic Activity ใน ตอนที่ 8 แต่ข้ามเรื่อง Menu ของ Toolbar ใน AppBarLayout ที่มีความสัมพันธ์กับหลายแฟ้ม ครั้งนี้กลับมาสนใจ และเพิ่มไป 3 ตัวเลือก พร้อมกิจกรรมที่ได้ทดสอบมาแล้วข้างต้น ทั้งหมดยังอยู่ใน 1 Main Layout กับ 1 Main Activity เพราะ Android Studio วางโครงสร้างให้ Activity คู่กับ Layout ส่วน Content Layout ในตัวอย่างครั้งนี้ จะถูกเรียกผ่าน Main Layout
ใช้การ include เข้าไป ก็ต้องใช้ setVisibility(View.VISIBLE); ใน Activity กำหนดให้กับ include แต่ละตัว เพราะไม่มีวิธีส่งชื่อ Layout ให้ include โดยตรง

สรุปกระบวนการได้ 5 ขั้นตอน ประกอบด้วย 1) ทำความรู้จัก CoordinatorLayout ที่มีเสน่ห์ มาพร้อม Snackbar 2) การวางภาพคู่กับข้อความ 6 แบบ เลือกใช้ที่ชอบได้เลย 3) ใส่ Activity ให้กับ Menu ใน Toolbar บน AppBarLayout 4) การสร้าง layout at runtime เพื่อ say hello 5) สร้าง Layout สำหรับแสดง ImageView โดยเฉพาะ
</introduction>

กำลังเล่าเรื่อง การใช้โปรแกรม Android Studio สู่เพื่อนนักพัฒนา ผ่าน Blog

<process>
กระบวนการในการพัฒนา APP

เพื่อนำภาพและข้อความนำเสนอต่อกันเรียงลงมาเป็นแถว การจัดการเมนู การสร้าง Layout ช่วง Runtime และการนำภาพมาเรียงต่อกันตาม Vertical
มีขั้นตอน ดังนี้

1. ทำความรู้จัก CoordinatorLayout ที่มีเสน่ห์ มาพร้อม Snackbar
เริ่มต้นก็สร้าง project ใหม่ แล้วเลือก Basic Activity ตั้งชื่อ ว่า layoutofnotification
ยังมี Template อีกมาก ทาง Android แนะนำว่าสามารถ Add Code from a Template คือ เราไม่ต้องเขียน code จาก 0 เค้ามี Template มาให้เลือกตามชอบ เคยมีอยู่ 10 ตอนนี้มี 12 และอาจเพิ่มขึ้น เลือกแล้วก็จะมี file ที่จำเป็น และเรียกใช้งานได้ในระดับหนึ่ง เราเพียงแต่นำมาปรับเพิ่ม พบว่า หน้า activity_main.xml มี Hierarchy ของ Layout ดังนี้
1. CoordinatorLayout เป็น root layout
2. AppBarLayout และภายในมี ToolBar
3. ConstraintLayout ที่ถูก include แฟ้ม content_main.xml
4. FloatingActionButton ลอยอยู่ที่ตำแหน่ง bottom|end
สำหรับ CoordinatorLayout ที่ถูกเลือกใช้นี้
ทำให้เราได้เห็นการใช้ FloatingActionButton ร่วมกับ Snackbar และ AppBarLayout

 

https://gist.github.com/thaiall/7bfcfeb57ac459b0e664f19337438908

 

ใช้โปรแกรม Android Studio ไม่ทันไร ถาม Update อีก 150 MB
รอไร .. 
เครื่องผมเหลือเนื้อที่ตั้งเยอะ 

 

2. การวางภาพคู่กับข้อความ 6 แบบ เลือกใช้ที่ชอบได้เลย
เดิม activity_main.xml จะ include แฟ้ม content_main.xml
แต่ผมลบไปแล้ว ของเดิมมี ConstraintLayout เป็น Root Layout
กับ TextView ที่เขียนว่า Hello World!
แต่ผมต้องการ LinearLayout ที่ทำ ScrollView ได้
จึงสร้าง content1_main.xml
โดยมี Hierarchy ของ Layout สำหรับ 6 คู่ ดังนี้

 <LinearLayout orientation="vertical">
 <LinearLayout>
 <TextView text="@string/information">
 </LinearLayout>
 <ScrollView>
 <LinearLayout orientation="vertical">
 <LinearLayout orientation="vertical">
 <TextView drawableStart />
 <TextView drawableStart />
 <ImageView />
 <TextView />
 </LinearLayout>
 <LinearLayout orientation="horizontal">
 <ImageView />
 <TextView />
 </LinearLayout>
 <RelativeLayout>
 <ImageView />
 <TextView />
 </RelativeLayout>
 <RelativeLayout>
 <ImageView id="@+id/imageView2" />
 <TextView layout_toEndOf="@+id/imageView2" />
 </RelativeLayout>
 </LinearLayout>
 </ScrollView>
 </LinearLayout>

ถ้าดูผลลัพธ์จากกภาพ ดูโครงสร้าง และเห็น code น่าจะนำไปใช้ต่อได้

https://gist.github.com/thaiall/304e6ddd917dd0350aa57fba72955082

3. ใส่ Activity ให้กับ Menu ใน Toolbar บน AppBarLayout
มีขั้นตอนดังนี้
3.1 วางแผนไว้ในใจ ว่าคลิ๊ก 3 จุดที่มุมบนขวา แล้วมีเมนูไหลลงมา
อยากเห็นอะไร ก็ให้เปิด app, res, menu, menu_main.xml
จากนั้นก็เพิ่มตัวเลือกตาม item ที่ต้องการ แต่ title ต้องเปิดแฟ้ม strings.xml พิมพ์ไปพร้อมกัน

<item
 android:id="@+id/content1"
 android:orderInCategory="100"
 android:title="@string/content1"
 app:showAsAction="never" />

 

https://gist.github.com/thaiall/eb8137794add90145d19daa9d1c2c0d8

3.2 เปิด MainActivity.java ขึ้นมาแก้ไข
มองหา method ชื่อ onOptionsItemSelected(MenuItem item)
เดิมจะมี if (id == R.id.action_settings) ผมก็เปลี่ยนไปใช้ switch จะได้สะดวก
ตัวอย่างนี้ต้องปรับการใช้ include ใน activity_main.xml

switch (item.getItemId()) {
 case R.id.content1:
 findViewById(R.id.content1).setVisibility(View.VISIBLE);
 findViewById(R.id.content2).setVisibility(View.GONE);
 return true;
 case R.id.content2:
 findViewById(R.id.content1).setVisibility(View.GONE);
 findViewById(R.id.content2).setVisibility(View.VISIBLE);
 return true;
 case R.id.layoutRuntime:
 layoutRuntime();
 return true;
 default:
 return super.onOptionsItemSelected(item);
 }

 

3.3 แก้ไขการ include เพราะสั่งไปว่าจะ visible หรือ gone

มองหา
 <include layout="@layout/content_main"
เปลี่ยนเป็น
 <include
 android:id="@+id/content1"
 layout="@layout/content1_main"
 android:visibility="visible" />
 <include
 android:id="@+id/content2"
 layout="@layout/content2_main"
 android:visibility="gone" />

 

https://gist.github.com/thaiall/e55bca08d5927c97dd2dec5367771085

 

4. การสร้าง layout at runtime เพื่อ say hello
เนื่องจากที่ผ่าน 8 ตอนเป็นการใช้โปรแกรม Android Studio
ผ่าน Main_Activity.java เท่านั้น และ layout ก็ไม่ได้มีเพิ่มขึ้นเป็นพิเศษ
ไม่มีการควบคุม Layout ผ่าน Main java เลย
แต่ code สร้าง Layout at runtime สำหรับ
ท่านที่ต้องการ Layout แปลกใหม่ กว่าที่มีไว้ ก็สร้างช่วง Runtime ได้
ได้ตัวอย่างมาจาก
http://www.android-examples.com

private void layoutRuntime() {
 LinearLayout linearLayout = new LinearLayout(this);
 TextView ProgrammaticallyTextView = new TextView(this);
 ProgrammaticallyTextView.setText(R.string.helloworld);
 ProgrammaticallyTextView.setTextSize(16);
 ProgrammaticallyTextView.setPadding(30, 250, 30, 100);
 linearLayout.addView(ProgrammaticallyTextView);
 this.setContentView(linearLayout, new LinearLayout.LayoutParams(
 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
 }

 

5. สร้าง Layout สำหรับแสดง ImageView โดยเฉพาะ
ใช้ภาพตัวอย่างจาก http://www.thaiall.com/actress/missgrand2017/
หากมีข่าวประกาศ หนังสือ รายงาน พรบ. หรือภาพสาวงาม จะนำมาเรียงต่อกัน
ให้เพื่อนชมผ่าน app บน Android ก็ส่งเข้าไปเลยครับ
ตอนผมทดสอบบน Smartphone มีปัญหาเรื่องจำนวนภาพเยอะ
ใช้ภาพเยอะ ๆ แล้ว error ส่งผ่าน Command line
เชื่อมผ่านเปิดแอพ WiFi ADB ซึ่งบนนั้นอาจมี Bug น่ะครับ
แต่แฟ้ม app-debug.apk นี้ส่งเข้า emulator ได้ผลปกติ
เรื่องสำคัญ คือ properties ของ ImageView เพื่อให้ลงจอภาพพอดี
โดยเฉพาะ scaleType กับ adjustViewBounds

<LinearLayout orientation="vertical">
 <ScrollView>
 <LinearLayout orientation="vertical">
 <ImageView
 android:id="@+id/imageView1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:scaleType="fitCenter"
 android:adjustViewBounds="true"
 android:contentDescription="@string/data"
 app:srcCompat="@drawable/thai1" />
 </LinearLayout>
 </ScrollView>
 </LinearLayout>

 

https://gist.github.com/thaiall/41e86984b4cabe35392e29fc05107f60

</process>

<website_guide>
+ https://developer.android.com/training/basics/firstapp/
+ http://www.techotopia.com/..User_Interface_in_Java_Code
+ https://stackoverflow.com/..without-setcontentviewr-layout-main
+ https://stackoverflow.com/..button-click-in-android
+ https://stackoverflow.com/..when-button-is-pressed
+ https://stackoverflow.com/..layout-in-android (viewstub)
+ https://developer.android.com/../declaring-layout
+ https://www.androidhive.info/..design-snackbar-example/
+ http://www.android-examples.com/..programmatically-example/
+ https://stackoverflow.com/..layout-on-java-code (setVisibility(View.GONE); and <ViewFlipper>)
+ https://developer.android.com/training/appbar/actions.html
+ https://developer.android.com/guide/topics/ui/menus.html
</website_guide>

หมายเหตุ 
ถ้าสนใจติดตามเนื้อหาในบล็อกนี้ สามารถ subscribe ด้วย email ที่อยู่ข้างขวา หรือ click here