สร้างคอมโพเนนต์มุมมองที่กำหนดเอง

ลองใช้วิธีแบบ Compose
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีทำงานกับเลย์เอาต์ใน Compose

Android มีโมเดลแบบแยกส่วนที่ซับซ้อนและทรงพลังสำหรับการสร้าง UI โดยอิงตามคลาสเลย์เอาต์พื้นฐาน View และ ViewGroup แพลตฟอร์มนี้มีคลาสย่อย View และ ViewGroup ที่สร้างไว้ล่วงหน้าหลากหลาย ซึ่งเรียกว่าวิดเจ็ตและเลย์เอาต์ตามลำดับ ซึ่งคุณสามารถใช้เพื่อสร้าง UI ได้

วิดเจ็ตที่พร้อมใช้งานบางส่วน ได้แก่ Button, TextView, EditText, ListView, CheckBox, RadioButton, Gallery, Spinner และวิดเจ็ตที่มีวัตถุประสงค์พิเศษเพิ่มเติม AutoCompleteTextView, ImageSwitcher และ TextSwitcher

เลย์เอาต์ที่มีให้ใช้งาน ได้แก่ LinearLayout FrameLayout RelativeLayout และอื่นๆ ดูตัวอย่างเพิ่มเติมได้ที่เลย์เอาต์ที่พบบ่อย

หากไม่มีวิดเจ็ตหรือเลย์เอาต์ที่สร้างไว้ล่วงหน้าที่ตรงกับความต้องการ คุณก็สร้างViewคลาสย่อยของคุณเองได้ หากต้องการปรับเปลี่ยนวิดเจ็ตหรือเลย์เอาต์ที่มีอยู่เล็กน้อย คุณสามารถสร้างคลาสย่อยของวิดเจ็ตหรือเลย์เอาต์และแทนที่เมธอดของวิดเจ็ตหรือเลย์เอาต์นั้นได้

การสร้างViewคลาสย่อยของคุณเองช่วยให้คุณควบคุมลักษณะที่ปรากฏและ ฟังก์ชันขององค์ประกอบหน้าจอได้อย่างแม่นยำ เพื่อให้เห็นภาพการควบคุมที่คุณจะได้รับเมื่อใช้มุมมองที่กำหนดเอง ต่อไปนี้คือ ตัวอย่างบางส่วนของสิ่งที่คุณทำได้ด้วยมุมมองที่กำหนดเอง

  • คุณสามารถสร้างViewประเภทที่เรนเดอร์แบบกำหนดเองทั้งหมดได้ เช่น ปุ่ม "ระดับเสียง ควบคุม" ที่เรนเดอร์โดยใช้กราฟิก 2 มิติ ซึ่งคล้ายกับการควบคุมอิเล็กทรอนิกส์แบบอนาล็อก
  • คุณสามารถรวมกลุ่มViewคอมโพเนนต์เป็นคอมโพเนนต์ใหม่รายการเดียวได้ เช่น เพื่อ สร้างสิ่งที่คล้ายกับช่องตัวเลือกรวม (การผสมผสานระหว่างรายการป๊อปอัปและช่องข้อความที่ป้อนได้อย่างอิสระ) ตัวควบคุม ตัวเลือกแบบ 2 บานหน้าต่าง (บานหน้าต่างด้านซ้ายและด้านขวาที่มีรายการในแต่ละบานหน้าต่าง ซึ่งคุณสามารถกำหนด ใหม่ได้ว่ารายการใดอยู่ในรายการใด) และอื่นๆ
  • คุณสามารถลบล้างวิธีแสดงผลคอมโพเนนต์ EditText บนหน้าจอได้ แอปตัวอย่าง NotePad ใช้คุณสมบัตินี้เพื่อสร้างหน้าสมุดจดบันทึกที่มีเส้นบรรทัด
  • คุณสามารถบันทึกเหตุการณ์อื่นๆ เช่น การกดแป้น และจัดการเหตุการณ์เหล่านั้นในลักษณะที่กำหนดเองได้ เช่น สำหรับเกม

ส่วนต่อไปนี้จะอธิบายวิธีสร้างมุมมองที่กำหนดเองและใช้วิวเหล่านั้นในแอปพลิเคชัน ดูข้อมูลอ้างอิงโดยละเอียดได้ที่คลาส View

วิธีการพื้นฐาน

ภาพรวมระดับสูงของสิ่งที่คุณจำเป็นต้องทราบเพื่อสร้างView คอมโพเนนต์ของคุณเองมีดังนี้

  1. ขยายViewคลาสหรือคลาสย่อยที่มีอยู่ด้วยคลาสของคุณเอง
  2. ลบล้างเมธอดบางรายการจากคลาสแม่ เมธอดของคลาสแม่ที่จะลบล้างจะเริ่มต้นด้วย on เช่น onDraw() onMeasure() และ onKeyDown() ซึ่งคล้ายกับเหตุการณ์ on ใน Activity หรือ ListActivity ที่คุณ ลบล้างสำหรับฮุกฟังก์ชันการทำงานอื่นๆ และวงจรของแอป
  3. ใช้คลาสส่วนขยายใหม่ เมื่อเสร็จแล้ว คุณจะใช้คลาสส่วนขยายใหม่แทน มุมมองที่ใช้เป็นพื้นฐานได้

คอมโพเนนต์ที่ปรับแต่งอย่างเต็มที่

คุณสามารถสร้างคอมโพเนนต์แบบกราฟิกที่ปรับแต่งได้อย่างเต็มที่ซึ่งจะปรากฏตามที่คุณต้องการ คุณอาจต้องการมิเตอร์ VU แบบกราฟิกที่มีลักษณะเหมือนมาตรวัดแบบอนาล็อกเก่า หรือมุมมองข้อความสำหรับร้องตาม ซึ่งมีลูกบอลเด้งไปตามคำขณะที่คุณร้องตามเครื่องคาราโอเกะ คุณอาจต้องการ สิ่งที่คอมโพเนนต์ในตัวทำไม่ได้ ไม่ว่าจะรวมกันอย่างไรก็ตาม

โชคดีที่คุณสามารถสร้างคอมโพเนนต์ที่มีลักษณะและทำงานได้ตามต้องการ โดยมีเพียงจินตนาการ ขนาดหน้าจอ และความสามารถในการประมวลผลที่มีอยู่เท่านั้นที่จำกัดการสร้างสรรค์ของคุณ ทั้งนี้โปรดทราบว่าแอปพลิเคชันของคุณอาจต้องทำงานบนอุปกรณ์ที่มีกำลังไฟน้อยกว่าเวิร์กสเตชันเดสก์ท็อปของคุณอย่างมาก

หากต้องการสร้างคอมโพเนนต์ที่ปรับแต่งอย่างเต็มรูปแบบ ให้พิจารณาสิ่งต่อไปนี้

  • มุมมองทั่วไปที่สุดที่คุณขยายได้คือ View ดังนั้นโดยปกติคุณจะเริ่มต้นด้วยการขยาย มุมมองนี้เพื่อสร้างคอมโพเนนต์ใหม่ที่เหนือกว่า
  • คุณสามารถระบุตัวสร้างซึ่งรับแอตทริบิวต์และพารามิเตอร์จาก XML ได้ และคุณสามารถ ใช้แอตทริบิวต์และพารามิเตอร์ของคุณเอง เช่น สีและช่วงของมิเตอร์ VU หรือ ความกว้างและการลดทอนของเข็ม
  • คุณอาจต้องการสร้างเครื่องฟังกิจกรรม ตัวช่วยเข้าถึงพร็อพเพอร์ตี้ และตัวแก้ไขของคุณเอง รวมถึง ลักษณะการทำงานที่ซับซ้อนยิ่งขึ้นในคลาสคอมโพเนนต์
  • คุณเกือบจะต้องการลบล้าง onMeasure() และอาจต้องลบล้าง onDraw() ด้วยหากต้องการให้คอมโพเนนต์แสดงบางอย่าง แม้ว่าทั้ง 2 จะมีลักษณะการทำงานเริ่มต้น แต่ onDraw() เริ่มต้นจะไม่ทำอะไร และ onMeasure() เริ่มต้นจะตั้งค่าขนาดเป็น 100x100 เสมอ ซึ่งคุณอาจไม่ต้องการ
  • นอกจากนี้ คุณยังลบล้างวิธีการ on อื่นๆ ได้ตามต้องการ

ขยาย onDraw() และ onMeasure()

onDraw() วิธีนี้จะแสดง Canvas ซึ่งคุณสามารถ ใช้เพื่อสร้างสิ่งต่างๆ ได้ตามต้องการ ไม่ว่าจะเป็นกราฟิก 2 มิติ คอมโพเนนต์มาตรฐานหรือคอมโพเนนต์ที่กำหนดเองอื่นๆ ข้อความที่มีสไตล์ หรือ สิ่งอื่นๆ ที่คุณนึกออก

onMeasure() จะซับซ้อนกว่าเล็กน้อย onMeasure() เป็นส่วนสำคัญ ของสัญญาการแสดงผลระหว่างคอมโพเนนต์กับคอนเทนเนอร์ onMeasure() ต้อง ลบล้างเพื่อรายงานการวัดชิ้นส่วนที่ประกอบอยู่อย่างมีประสิทธิภาพและแม่นยำ ข้อกำหนดด้านขีดจำกัดจากองค์ประกอบระดับบนสุดทำให้กระบวนการนี้มีความซับซ้อนขึ้นเล็กน้อย ซึ่งจะส่งไปยังเมธอด onMeasure() และข้อกำหนดในการเรียกเมธอด setMeasuredDimension() ด้วยความกว้างและความสูงที่วัดได้เมื่อคำนวณแล้ว หากคุณไม่เรียกใช้เมธอดนี้จากเมธอด onMeasure() ที่ลบล้าง จะทำให้เกิดข้อยกเว้นในเวลาที่ทำการวัด

ในระดับสูง การติดตั้งใช้งาน onMeasure() จะมีลักษณะดังนี้

  • ระบบจะเรียกใช้เมธอด onMeasure() ที่ลบล้างพร้อมข้อกำหนดความกว้างและความสูง ซึ่งจะถือเป็นข้อกำหนดสำหรับการจำกัดการวัดความกว้างและความสูง ที่คุณสร้างขึ้น widthMeasureSpec และ heightMeasureSpec เป็นพารามิเตอร์ทั้งคู่เป็นรหัสจำนวนเต็มที่แสดงมิติข้อมูล คุณสามารถดูข้อมูลอ้างอิงทั้งหมดเกี่ยวกับข้อจำกัดประเภทต่างๆ ที่ข้อกำหนดเหล่านี้อาจกำหนดได้ในเอกสารอ้างอิงที่ส่วนView.onMeasure(int, int) เอกสารอ้างอิงนี้ยังอธิบายการทำงานของการวัดผลทั้งหมดด้วย
  • เมธอด onMeasure() ของคอมโพเนนต์จะคำนวณความกว้างและความสูงของการวัด ซึ่งจำเป็นต่อการแสดงผลคอมโพเนนต์ โดยต้องพยายามให้เป็นไปตามข้อกำหนดที่ส่งมา แม้ว่าจะเกินข้อกำหนดได้ก็ตาม ในกรณีนี้ ผู้ปกครองสามารถเลือกสิ่งที่ต้องทำได้ ซึ่งรวมถึง การตัด เลื่อน ทิ้งข้อยกเว้น หรือขอให้ onMeasure() ลองอีกครั้ง อาจใช้ข้อกำหนดเฉพาะการวัดที่แตกต่างกัน
  • เมื่อคํานวณความกว้างและความสูงแล้ว ให้เรียกใช้เมธอด setMeasuredDimension(int width, int height) โดยใช้การวัดที่คํานวณแล้ว หากไม่ดำเนินการนี้จะทำให้เกิดข้อยกเว้น

ต่อไปนี้เป็นสรุปของวิธีการมาตรฐานอื่นๆ ที่เฟรมเวิร์กเรียกใช้ในมุมมอง

หมวดหมู่ เมธอด คำอธิบาย
การสร้างวิดีโอ ผู้ผลิต มีรูปแบบของตัวสร้างที่เรียกใช้เมื่อสร้างมุมมองจากโค้ด และรูปแบบที่เรียกใช้เมื่อขยายมุมมองจากไฟล์เลย์เอาต์ รูปแบบที่ 2 จะแยกวิเคราะห์และใช้แอตทริบิวต์ที่กำหนดไว้ในไฟล์เลย์เอาต์
onFinishInflate() เรียกใช้หลังจากที่ขยายมุมมองและองค์ประกอบย่อยทั้งหมดจาก XML
การจัดวาง onMeasure(int, int) เรียกใช้เพื่อกำหนดข้อกำหนดด้านขนาดสำหรับมุมมองนี้และ องค์ประกอบย่อยทั้งหมด
onLayout(boolean, int, int, int, int) เรียกใช้เมื่อมุมมองนี้ต้องกำหนดขนาดและตำแหน่งให้กับองค์ประกอบย่อยทั้งหมด
onSizeChanged(int, int, int, int) เรียกใช้เมื่อมีการเปลี่ยนขนาดของมุมมองนี้
การวาด onDraw(Canvas) เรียกใช้เมื่อมุมมองต้องแสดงเนื้อหา
การประมวลผลเหตุการณ์ onKeyDown(int, KeyEvent) เรียกใช้เมื่อเกิดเหตุการณ์กดแป้น
onKeyUp(int, KeyEvent) เรียกใช้เมื่อเกิดเหตุการณ์กดปุ่มขึ้น
onTrackballEvent(MotionEvent) เรียกใช้เมื่อเกิดเหตุการณ์การเคลื่อนที่ของแทร็กบอล
onTouchEvent(MotionEvent) เรียกใช้เมื่อเกิดเหตุการณ์การเคลื่อนไหวบนหน้าจอสัมผัส
โฟกัส onFocusChanged(boolean, int, Rect) เรียกใช้เมื่อมุมมองได้รับหรือสูญเสียโฟกัส
onWindowFocusChanged(boolean) เรียกใช้เมื่อหน้าต่างที่มีมุมมองได้รับหรือสูญเสียโฟกัส
การแนบ onAttachedToWindow() เรียกใช้เมื่อแนบมุมมองกับหน้าต่าง
onDetachedFromWindow() เรียกใช้เมื่อเลิกเชื่อมต่อมุมมองจากหน้าต่าง
onWindowVisibilityChanged(int) เรียกใช้เมื่อมีการเปลี่ยนระดับการเข้าถึงของหน้าต่างที่มีมุมมอง

การควบคุมแบบผสม

หากไม่ต้องการสร้างคอมโพเนนต์ที่กำหนดเองทั้งหมด แต่ต้องการรวมคอมโพเนนต์ที่นำกลับมาใช้ใหม่ซึ่งประกอบด้วยกลุ่มของตัวควบคุมที่มีอยู่ การสร้างคอมโพเนนต์แบบผสม (หรือตัวควบคุมแบบผสม) อาจเป็นตัวเลือกที่ดีที่สุด กล่าวโดยสรุปคือ การดำเนินการนี้จะรวมการควบคุมหรือมุมมองที่ละเอียดมากขึ้นหลายรายการไว้ในกลุ่มรายการเชิงตรรกะที่สามารถถือเป็นรายการเดียวได้ ตัวอย่างเช่น ช่องตัวเลือกรวมอาจเป็นการรวมกันของฟิลด์EditTextบรรทัดเดียว และปุ่มที่อยู่ติดกันพร้อมรายการป๊อปอัปที่แนบมา หากผู้ใช้แตะปุ่มและเลือกรายการจาก รายการ ระบบจะป้อนข้อมูลลงในช่อง EditText แต่ผู้ใช้ก็พิมพ์ข้อความลงในEditText ได้โดยตรงหากต้องการ

ใน Android มีมุมมองอื่นๆ อีก 2 มุมมองที่พร้อมใช้งานเพื่อทำสิ่งนี้ ได้แก่ Spinner และ AutoCompleteTextView ไม่ว่าจะอย่างไรก็ตาม แนวคิดสำหรับช่องตัวเลือกรวมนี้ก็เป็นตัวอย่างที่ดี

หากต้องการสร้างคอมโพเนนต์แบบผสม ให้ทำดังนี้

  • เช่นเดียวกับ Activity ให้ใช้แนวทางแบบประกาศ (อิงตาม XML) เพื่อสร้างคอมโพเนนต์ที่อยู่ในคอนเทนเนอร์ หรือฝังคอมโพเนนต์แบบเป็นโปรแกรมจากโค้ด จุดเริ่มต้นปกติคือ Layout บางประเภท ดังนั้นให้สร้างคลาสที่ขยาย Layout ในกรณีของช่องตัวเลือกรวม คุณอาจใช้ LinearLayout ที่มี การวางแนวแนวนอน คุณสามารถซ้อนเลย์เอาต์อื่นๆ ไว้ภายในได้ เพื่อให้คอมโพเนนต์แบบผสมมีความซับซ้อนและมีโครงสร้างตามต้องการ
  • ในตัวสร้างสำหรับคลาสใหม่ ให้ใช้พารามิเตอร์ใดก็ตามที่คลาสแม่คาดหวังและส่ง พารามิเตอร์เหล่านั้นไปยังตัวสร้างคลาสแม่ก่อน จากนั้นคุณจะตั้งค่ามุมมองอื่นๆ ให้ใช้ ภายในคอมโพเนนต์ใหม่ได้ ส่วนนี้คือที่ที่คุณสร้างEditTextฟิลด์และ รายการป๊อปอัป คุณอาจนำแอตทริบิวต์และพารามิเตอร์ของคุณเองไปใส่ใน XML ที่ตัวสร้าง สามารถดึงและใช้ได้
  • คุณเลือกสร้าง Listener สำหรับเหตุการณ์ที่มุมมองที่ฝังอาจสร้างขึ้นได้ ตัวอย่างเช่น เมธอด Listener สำหรับฟังก์ชันรอคลิกรายการเพื่ออัปเดตเนื้อหาของ EditText หากมีการเลือกรายการ
  • ไม่บังคับ: สร้างพร็อพเพอร์ตี้ของคุณเองด้วยตัวช่วยเข้าถึงและตัวแก้ไข เช่น ตั้งค่า EditText ในคอมโพเนนต์ตอนแรกและค้นหาเนื้อหาเมื่อจำเป็น
  • (ไม่บังคับ) ลบล้าง onDraw() และ onMeasure() โดยปกติแล้วไม่จำเป็นต้องดำเนินการนี้เมื่อ ขยาย Layout เนื่องจากเลย์เอาต์มีลักษณะการทำงานเริ่มต้นที่น่าจะทำงานได้ดี
  • คุณจะลบล้างเมธอดอื่นๆ ของ on เช่น onKeyDown() ก็ได้ เช่น เพื่อเลือกค่าเริ่มต้นบางค่าจากรายการป๊อปอัปของช่องตัวเลือกรวมเมื่อแตะคีย์หนึ่งๆ

การใช้ Layout เป็นพื้นฐานสำหรับการควบคุมที่กำหนดเองมีข้อดีหลายประการ ซึ่งรวมถึงข้อดีต่อไปนี้

  • คุณระบุเลย์เอาต์ได้โดยใช้ไฟล์ XML แบบประกาศ เช่นเดียวกับหน้าจอกิจกรรม หรือจะสร้างมุมมองแบบเป็นโปรแกรมและซ้อนไว้ในเลย์เอาต์จากโค้ดก็ได้
  • เมธอด onDraw() และ onMeasure() รวมถึงเมธอดอื่นๆ ส่วนใหญ่ on มีลักษณะการทำงานที่เหมาะสม คุณจึงไม่ต้องแทนที่เมธอดเหล่านั้น
  • คุณสร้างมุมมองแบบผสมที่ซับซ้อนได้ตามต้องการอย่างรวดเร็ว และนำกลับมาใช้ใหม่ได้ราวกับเป็นคอมโพเนนต์เดียว

แก้ไขประเภทมุมมองที่มีอยู่

หากมีคอมโพเนนต์ที่คล้ายกับสิ่งที่คุณต้องการ คุณสามารถขยายคอมโพเนนต์นั้นและลบล้าง ลักษณะการทำงานที่คุณต้องการเปลี่ยนแปลงได้ คุณสามารถทำทุกอย่างได้เหมือนกับคอมโพเนนต์ที่ปรับแต่งอย่างเต็มที่ แต่การเริ่มต้นด้วยคลาสที่มีความเฉพาะเจาะจงมากขึ้นในลำดับชั้น View จะช่วยให้คุณได้ลักษณะการทำงานบางอย่างที่ตรงกับความต้องการโดยไม่ต้องเสียค่าใช้จ่าย

ตัวอย่างเช่น แอปตัวอย่าง NotePad แสดงให้เห็นถึงหลายๆ ด้านของการใช้แพลตฟอร์ม Android ซึ่งรวมถึงการขยายมุมมองของ EditText เพื่อสร้างสมุดโน้ตแบบมีเส้น นี่ไม่ใช่ตัวอย่างที่สมบูรณ์แบบ และ API สำหรับ การดำเนินการนี้อาจมีการเปลี่ยนแปลง แต่ก็แสดงให้เห็นถึงหลักการ

หากยังไม่ได้ดำเนินการ ให้นำเข้าตัวอย่าง NotePad ไปยัง Android Studio หรือดู แหล่งที่มาโดยใช้ลิงก์ที่ระบุ โดยเฉพาะอย่างยิ่ง โปรดดูคำจำกัดความของ LinedEditText ในไฟล์ NoteEditor.java

สิ่งที่ควรทราบในไฟล์นี้มีดังนี้

  1. คำจำกัดความ

    โดยกำหนดคลาสด้วยบรรทัดต่อไปนี้
    public static class LinedEditText extends EditText

    LinedEditText ได้รับการกำหนดให้เป็นคลาสภายในกิจกรรม NoteEditor แต่เป็นแบบสาธารณะเพื่อให้เข้าถึงได้เป็น NoteEditor.LinedEditText จากภายนอกคลาส NoteEditor

    นอกจากนี้ LinedEditText ยังเป็น static ซึ่งหมายความว่าไม่ได้สร้าง สิ่งที่เรียกว่า "วิธีการสังเคราะห์" ที่ช่วยให้เข้าถึงข้อมูลจากคลาสหลักได้ ซึ่งหมายความว่า จะทำงานเป็นคลาสแยกต่างหากแทนที่จะเป็นสิ่งที่เกี่ยวข้องกับ NoteEditor อย่างใกล้ชิด ซึ่งเป็นวิธีที่สะอาดกว่าในการสร้างคลาสภายในหากไม่จำเป็นต้องเข้าถึงสถานะจาก คลาสภายนอก ซึ่งจะช่วยให้คลาสที่สร้างมีขนาดเล็กและใช้จากคลาสอื่นๆ ได้ง่าย ขึ้น

    LinedEditText ขยาย EditText ซึ่งเป็นมุมมองที่จะปรับแต่งในกรณีนี้ เมื่อเสร็จแล้ว ชั้นเรียนใหม่จะแทนที่EditText มุมมองปกติได้

  2. การเริ่มต้นคลาส

    เช่นเคย ระบบจะเรียกใช้ฟังก์ชัน super ก่อน นี่ไม่ใช่ตัวสร้างเริ่มต้น แต่เป็นตัวสร้างที่มีพารามิเตอร์ EditText จะสร้างขึ้นด้วยพารามิเตอร์เหล่านี้เมื่อมีการ ขยายจากไฟล์เลย์เอาต์ XML ดังนั้น เครื่องมือสร้างจึงต้องรับค่าเหล่านั้นและส่งต่อไปยัง เครื่องมือสร้างคลาสแม่ด้วย

  3. เมธอดที่ลบล้าง

    ตัวอย่างนี้จะลบล้างเฉพาะเมธอด onDraw() แต่คุณอาจต้องลบล้างเมธอดอื่นๆ ด้วยเมื่อสร้างคอมโพเนนต์ที่กำหนดเอง

    สำหรับตัวอย่างนี้ การลบล้างเมธอด onDraw() จะช่วยให้คุณวาดเส้นสีน้ำเงินบน EditText Canvas ของมุมมองได้ ระบบจะส่ง Canvas ไปยังเมธอด onDraw() ที่ลบล้าง ระบบจะเรียกใช้เมธอด super.onDraw() ก่อนที่เมธอด จะสิ้นสุด ต้องเรียกใช้เมธอดของคลาสแม่ ในกรณีนี้ ให้เรียกใช้ที่ท้ายบรรทัดหลังจาก วาดเส้นที่ต้องการรวม

  4. คอมโพเนนต์ที่กำหนดเอง

    ตอนนี้คุณมีคอมโพเนนต์ที่กำหนดเองแล้ว แต่จะใช้ได้อย่างไร ในตัวอย่าง NotePad เราใช้คอมโพเนนต์ที่กำหนดเองจากเลย์เอาต์แบบประกาศโดยตรง ดังนั้นให้ดูที่ note_editor.xml ในโฟลเดอร์ res/layout

    <view xmlns:android="http://schemas.android.com/apk/res/android"
        class="com.example.android.notepad.NoteEditor$LinedEditText"
        android:id="@+id/note"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:padding="5dp"
        android:scrollbars="vertical"
        android:fadingEdge="vertical"
        android:gravity="top"
        android:textSize="22sp"
        android:capitalize="sentences"
    />

    ระบบจะสร้างคอมโพเนนต์ที่กำหนดเองเป็นมุมมองทั่วไปใน XML และระบุคลาส โดยใช้แพ็กเกจแบบเต็ม ระบบจะอ้างอิงคลาสในที่คุณกำหนดโดยใช้รูปแบบ NoteEditor$LinedEditText ซึ่งเป็นวิธีมาตรฐานในการอ้างอิงคลาสใน ในภาษาการเขียนโปรแกรม Java

    หากไม่ได้กำหนดคอมโพเนนต์มุมมองที่กำหนดเองเป็นคลาสภายใน คุณสามารถประกาศคอมโพเนนต์มุมมอง ด้วยชื่อองค์ประกอบ XML และยกเว้นแอตทริบิวต์ class เช่น

    <com.example.android.notepad.LinedEditText
      id="@+id/note"
      ... />

    โปรดสังเกตว่าตอนนี้LinedEditTextคลาสเป็นไฟล์คลาสแยกต่างหากแล้ว เมื่อ คลาสซ้อนอยู่ในคลาส NoteEditor เทคนิคนี้จะใช้ไม่ได้

    แอตทริบิวต์และพารามิเตอร์อื่นๆ ในคําจํากัดความคือแอตทริบิวต์และพารามิเตอร์ที่ส่งไปยังตัวสร้างคอมโพเนนต์ที่กําหนดเอง แล้วส่งต่อไปยังตัวสร้าง EditText ดังนั้นจึงเป็นพารามิเตอร์เดียวกันกับที่คุณใช้สําหรับมุมมอง EditText คุณยังเพิ่มพารามิเตอร์ของคุณเองได้ด้วย

การสร้างคอมโพเนนต์ที่กำหนดเองจะซับซ้อนเท่าที่คุณต้องการเท่านั้น

คอมโพเนนต์ที่ซับซ้อนกว่าจะลบล้างonเมธอดได้มากขึ้น และนำเมธอดตัวช่วยของตัวเองมาใช้ ซึ่งจะปรับแต่งพร็อพเพอร์ตี้และลักษณะการทำงานได้อย่างมาก ทุกสิ่งเป็นไปได้ เพียงแค่จินตนาการและสิ่งที่ต้องการให้คอมโพเนนต์ทำ