#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

#AndroidStudio ตอนที่ 7 การมีภาพประกอบบทความแบบเป็นพื้นหลัง และแยกเฟรม เปลี่ยนบทความด้ายการลากซ้ายขวา และเปลี่ยนปุ่มลอยทับ

#AndroidStudio ตอนที่ 7 การมีภาพประกอบบทความแบบเป็นพื้นหลัง
และแยกเฟรม 
เปลี่ยนบทความด้ายการลากซ้ายขวา และเปลี่ยนปุ่มลอยทับ

<introduction>
อารัมภบท
การแสดงข้อมูลก็ต้องมีภาพประกอบสิครับ เป็นเรื่องที่ต่อยอดมาจาก ตอนที่ 5 เล่าเรื่องแสดงข้อมูล และ ตอนที่ 6 เล่าเรื่องแสดงภาพ ตอนนี้จึงนำภาพกับข้อมูลมาแสดงร่วมกัน แต่ตอนนี้เล่าไว้เพียง 2 แบบ คือการแสดงแบบแยกเฟรม กับภาพและข้อความซ้อนกันเหมือนเป็น Background

สิ่งที่น่าสนใจในตอนนี้ คือ การใช้ Navigation แบบลากไปด้านข้างแบบ Swipe Views  ผ่าน ViewPager และการใช้ FloatingActionButton ที่ทำให้ปุ่มรอรับคำสั่งเหนือข้อความ เป็นสิ่งที่มีมาใน Tabbed Activity ทำให้หยิบมาใช้ได้เลย ในตอนนี้ผมได้สร้าง  layout_main.xml แล้วก็เพิ่ม ScrollView คลุม TextView จะได้เลื่อนขึ้นลงได้ และใช้ FrameLayout แบ่งส่วนว่าส่วนไหนควรแสดงภาพ หรือแสดงบทความ

สรุปกระบวนการได้ 8 ขั้นตอน ประกอบด้วย 1) เลือก Tabbed Activity 2) ทำให้กดเลือกบทความจาก string-array 3) การเปลี่ยนภาพประกอบบทความตามเลข Section 4) สร้าง Layout ใหม่ไว้ใช้งาน 5) ทำให้บทความเลื่อนลงมาผ่าน ScrollView 6) ทำให้กดปุ่ม email แล้วเรียก Layout ใหม่ 7) การเปลี่ยนภาพ email เป็น media_play 8) การใช้ FrameLayout แยกส่วนของภาพ และบทความ
</introduction>

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

<process>
กระบวนการในการพัฒนา APP
เพื่อแสดงบทความ หรือข้อมูล โดยมีภาพประกอบแบบซ้อนข้อความ และแบ่งเฟรม สามารถเลือกบทความต่อไป หรือข้อความที่เหลือผ่านการลากจอภาพทั้ง Vertical (ScrollView) และ Horizontal (Next Article)
มีขั้นตอน ดังนี้

1. เลือก Tabbed Activity
สร้าง New Project แบบ Tabbed Activity ชื่อ imageinarticle
และมี Navigation Style แบบ Swipe Views (View Page)
ที่ Android Studio เตรียมทั้ง Layout และ Activity มาให้แล้ว
พบว่า ใน Layout มี activity_main.xml และ fragment_main.xml
ทดสอบใช้งานใน Smart phone พบว่า
– หน้าหลักมี icon:email และ icon:Toolbar
– คลิ๊ก email จะมี Notification ขึ้นมาว่า Replace with your own action
– คลิ๊ก Toolbar ที่มุมบนขวา ก็จะพบกับคำว่า Settings
– ลากจอไปด้านซ้าย พบหน้าข้อมูลว่า section 2 และ 3 แล้วลากกลับไปขวาก็จะหยุดที่ section 1
– การแสดงทั้ง 3 หน้าเรียกมาจาก fragment_main.xml แต่ใช้ setText ทำให้ข้อความต่างกัน
– โดยหน้าควบคุม Navigation คือ activity_main.xml มีโครงสร้าง Layout สรุปดังนี้

<CoordinatorLayout ..>
<AppBarLayout ..><Toolbar ..></Toolbar></AppBarLayout>
<ViewPager />
<FloatingActionButton />
</CoordinatorLayout>

ส่วนหน้าเนื้อหา fragment_main.xml มีโครงสร้าง Layout สรุปได้ดังนี้

<RelativeLayout ..>
<TextView.. />
</RelativeLayout>

2. ทำให้กดเลือกบทความจาก string-array
เพื่อให้การทดสอบเห็นผลชัดเจน จึงไปหาบทความมา 3 เรื่อง เป็นตัวอย่างสำหรับทำแอพ
แล้วเปิด strings.xml เพื่อส่งบทความเข้าไปใน tag:string-array ตั้งชื่อว่า data
แล้วไปเปิด MainActivity.java
มองหา textView.setText(..) ให้เพิ่ม และ เปลี่ยนเป็น ดังนี้

import android.content.res.Resources;
Resources res = getResources();
String[] mData = res.getStringArray(R.array.data);
textView.setText(mData[getArguments().getInt(ARG_SECTION_NUMBER) – 1]);

ส่วนใน strings.xml ให้นำบทความที่หามาได้ ไปเพิ่มข้อมูลใน strings.xml

<string-array name=”data”>
<item>บทความที่ 611 …</item>
<item>บทความที่ 610 …</item>
<item>บทความที่ 609 …</item>
</string-array>

เพียงเท่านี้บทความทั้ง 3 ก็จะถูกเรียกผ่าน Navigation แบบ ViewPager เรียบร้อยแล้ว

https://gist.github.com/thaiall/4dae3e80398ec868806937fe9ff1e862

3. การเปลี่ยนภาพประกอบบทความตามเลข Section
มีขั้นตอนดังนี้
– เริ่มจากนำภาพ lp01.jpg ถึง lp05.jpg เข้า drawable
– เพิ่ม ImageView เข้า fragment_main.xml ให้อยู่ก่อน TextView

<ImageView
android:id=”@+id/imageView”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
app:srcCompat=”@drawable/lp01″ />

– เปลี่ยนค่า width กับ height จะได้ภาพขนาดเล็กประกอบบทความ เช่น 48dp กับ 64dp
– เพิ่ม code ต่อท้าย textView.setText(..) เพื่อให้ภาพเปลี่ยนไปพร้อมข้อมูล

import android.widget.ImageView;
ImageView mImageView = (ImageView) rootView.findViewById(R.id.imageView);
int getV = getArguments().getInt(ARG_SECTION_NUMBER);
String[] List2 ={“lp0”,String.valueOf(getV)};
Resources resimg = getResources();
String mDrawableName = android.text.TextUtils.join(“”, List2);;
//int resID = resimg.getIdentifier(mDrawableName , “drawable”, getPackageName());
int resID = resimg.getIdentifier(mDrawableName , “drawable”, “com.thaiall.www.imageinarticle”);
mImageView.setImageResource(resID);

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

4. สร้าง Layout ใหม่ไว้ใช้งาน
อยากได้หน้าใหม่ layout ใหม่สำหรับข้อมูลใหม่
– เข้า strings.xml ไปหาคัดลอกบทความที่ 4 เพิ่มแบบ string ตั้งชื่อว่า data4
– เพิ่มหน้า Layout ใหม่ โดยคลิ๊กขวาใน Project Window
สั่ง New, XML, Layout XML File, “layout_main
แล้วกด Finish จะได้แฟ้มชื่อ layout_main.xml
เข้าไปดู Tab:Text ในแฟ้มนี้พบว่ามีเพียง <LinearLayout ..></LinearLayout>
จึงไป Tab:Design แล้วลาก TextView จาก Palette ไปวางใน LinearLayout
แล้วเพิ่มหรือแทนที่คุณสมบัตินี้ android:text=”@string/data4″

5. ทำให้บทความเลื่อนลงมาผ่าน ScrollView
หากทดสอบจะพบว่าข้อมูลเกิน 1 หน้า แต่ Scroll ลงไปข้อมูลส่วนที่เหลือไม่ได้
จึงเพิ่ม ScrollView คลุม TextView ทั้งใน layout_main.xml และ fragment_main.xml

<ScrollView android:layout_width=”wrap_content” android:layout_height=”wrap_content”>
<TextView … ที่นี่ />
</ScrollView>

เมื่อใส่ Tag แล้วก็ทดสอบ Run ข้อมูล 3 หน้า น่าจะเลื่อนลงไปด้านล่างได้แล้ว
ส่วนหน้าใหม่ยังทดสอบไม่ได้ เพราะยังไม่กำหนดให้ layout ใด ๆ ถูกเรียกมาแสดง

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

6. ทำให้กดปุ่ม email แล้วเรียก Layout ใหม่
ปรับแก้ปุ่ม email ให้เรียก layout_main.xml ที่สร้างใหม่มาแสดง
แก้ไขโดยทำหมายเหตุ หน้าคำสั่งที่สั่งแสดง Notification

// Snackbar.make(view, “Replace with your own action”, Snackbar.LENGTH_LONG)
// .setAction(“Action”, null).show();

แล้วเพิ่ม method เรียก layout มาแสดง

setContentView(R.layout.layout_main);

7. การเปลี่ยนภาพ email เป็น media_play
ตอนนี้ปุ่ม email ก็มีหน้าที่เรียก layout_main.xml มาแสดงแล้ว
ดูรายการภาพที่คล้าย ic_dialog_email ที่
http://gae.darshancomputing.com/android/1.5-drawables.html
พบ ic_media_play

8. การใช้ FrameLayout แยกส่วนของภาพ และบทความ
ขณะนี้ข้อมูลใน layout_main.xml ยังไม่มีภาพประกอบ
จึงวางแผนว่าจะแบ่งเป็น 2 ซีก คือ ซ้ายกับขวา ให้ซ้ายแสดงภาพ 3 ภาพ
ส่วนขวาเป็นข้อมูลที่ scroll ได้เหมือนเดิม

<LinearLayout..>
<FrameLayout..>
<ImageView.. android:scaleType=”fitStart” />
<ImageView.. />
<ImageView.. android:scaleType=”fitEnd” />
</FrameLayout>
<FrameLayout..>
<ScrollView..><TextView.. /></ScrollView>
</FrameLayout>
</LinearLayout>

https://gist.github.com/thaiall/78ba38a6ef837a5e9bd44c22c1ca0d38

</process>

<website_guide>
+ http://abhiandroid.com/ui/html
+ https://gist.github.com/Kishanjvaghela/
+ https://medium.com/../android-textview-and-image-loading-from-url
+ https://stackoverflow.com/../getdrawable-deprecated-api-22
+ https://stackoverflow.com/../display-inline-images-from-html
+ https://stackoverflow.com/../display-image-in-androids-textview
+ https://developer.android.com/reference/android/text/Html.html
+ http://stacktips.com/tutorials/../display-html-in-android-textview
+ https://developer.android.com/../string-resource.html
+ https://developer.android.com/../arrays.html
+ https://google-developer-training.gitbooks.io/..
+ http://www.thaiall.com/android
</website_guide>

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