Android และ ChromeOS มี API มากมายที่จะช่วยคุณสร้างแอปที่นำเสนอ
ผู้ใช้ได้รับประสบการณ์ที่ยอดเยี่ยมสำหรับสไตลัส
การเปิดเผยชั้นเรียน MotionEvent
รายการ
ข้อมูลเกี่ยวกับการโต้ตอบของสไตลัสกับหน้าจอ รวมถึงแรงกดของสไตลัส
การวางแนว การเอียง การวางเมาส์ และฝ่ามือ กราฟิกและการเคลื่อนไหวที่มีเวลาในการตอบสนองต่ำ
ไลบรารีการคาดการณ์จะเพิ่มประสิทธิภาพการแสดงผลบนหน้าจอของสไตลัสเพื่อมอบ
ที่เป็นธรรมชาติเหมือนใช้ปากกาและกระดาษ
MotionEvent
คลาส MotionEvent
แสดงการโต้ตอบอินพุตของผู้ใช้ เช่น ตำแหน่ง
และการเคลื่อนไหวของตัวชี้แบบสัมผัสบนหน้าจอ สำหรับอินพุตสไตลัส MotionEvent
นอกจากนี้ยังจะแสดงข้อมูลความดัน การวางแนว การเอียง และการวางเมาส์เหนือ
ข้อมูลเหตุการณ์
วันที่如需访问 MotionEvent
数据,请为组件添加 pointerInput
修饰符:
@Composable
fun Greeting() {
Text(
text = "Hello, Android!", textAlign = TextAlign.Center, style = TextStyle(fontSize = 5.em),
modifier = Modifier
.pointerInput(Unit) {
awaitEachGesture {
while (true) {
val event = awaitPointerEvent()
event.changes.forEach { println(it) }
}
}
},
)
}
ออบเจ็กต์ MotionEvent
ให้ข้อมูลที่เกี่ยวข้องกับด้านต่างๆ ต่อไปนี้ของ UI
กิจกรรม:
- การทำงาน: การโต้ตอบทางกายภาพกับอุปกรณ์ เช่น การแตะหน้าจอ การย้ายตัวชี้เหนือพื้นผิวหน้าจอ การเลื่อนตัวชี้เหนือหน้าจอ แพลตฟอร์ม
- เคอร์เซอร์: ตัวระบุของวัตถุที่โต้ตอบกับหน้าจอ เช่น นิ้ว สไตลัส, เมาส์
- แกน: ประเภทข้อมูล เช่น พิกัด x และ y, ความดัน, การเอียง, การวางแนว และลอยอยู่ (ระยะทาง)
การดำเนินการ
หากต้องการใช้การรองรับสไตลัส คุณต้องเข้าใจสิ่งที่ผู้ใช้ทำ ที่มีประสิทธิภาพสูง
MotionEvent
มีค่าคงที่ ACTION
ที่หลากหลายซึ่งเป็นตัวกำหนดการเคลื่อนไหว
กิจกรรม การดำเนินการที่สำคัญที่สุดสำหรับสไตลัสมีดังนี้
การทำงาน | คำอธิบาย |
---|---|
ACTION_DOWN ACTION_POINTER_DOWN |
เคอร์เซอร์สัมผัสหน้าจอแล้ว |
การดำเนินการ | เคอร์เซอร์กำลังเคลื่อนไหวบนหน้าจอ |
ACTION_UP ACTION_POINTER_UP |
เคอร์เซอร์ไม่สัมผัสกับหน้าจออีกต่อไป |
การดำเนินการยกเลิก | ควรยกเลิกชุดการเคลื่อนไหวก่อนหน้าหรือปัจจุบันเมื่อใด |
แอปของคุณจะทำงานต่างๆ ได้ เช่น การเริ่มเส้นโครงร่างใหม่เมื่อ ACTION_DOWN
เกิดขึ้น โดยวาดเส้นโครงร่างด้วย ACTION_MOVE,
และสิ้นสุดเส้นโครงร่างเมื่อ
ทริกเกอร์ ACTION_UP
แล้ว
ชุดของการกระทำ MotionEvent
จาก ACTION_DOWN
เป็น ACTION_UP
สำหรับ
เรียกว่าชุดการเคลื่อนไหว
เคอร์เซอร์
หน้าจอส่วนใหญ่เป็นแบบมัลติทัช โดยระบบจะกำหนดตัวชี้ให้กับนิ้วแต่ละนิ้ว สไตลัส เมาส์ หรือวัตถุชี้ตำแหน่งอื่นๆ ที่โต้ตอบกับหน้าจอ ตัวชี้ ดัชนีช่วยให้คุณสามารถดูข้อมูลแกนสำหรับตัวชี้ที่ต้องการ เช่น เมื่อนิ้วแรกแตะบนหน้าจอหรือนิ้วที่สอง
ช่วงดัชนีเคอร์เซอร์มีตั้งแต่ 0 จนถึงจำนวนเคอร์เซอร์ที่แสดงผลโดย
MotionEvent#pointerCount()
ลบ 1
คุณเข้าถึงค่าแกนของเคอร์เซอร์ได้ด้วยเมธอด getAxisValue(axis,
pointerIndex)
เมื่อละเว้นดัชนีตัวชี้ ระบบจะแสดงค่าสำหรับดัชนีแรก
ตัวชี้, ตัวชี้ศูนย์ (0)
ออบเจ็กต์ MotionEvent
มีข้อมูลเกี่ยวกับประเภทของตัวชี้ที่ใช้อยู่ คุณ
รับประเภทตัวชี้ได้โดยทำซ้ำผ่านดัชนีตัวชี้และการเรียก
เวลา
getToolType(pointerIndex)
ดูข้อมูลเพิ่มเติมเกี่ยวกับเคอร์เซอร์ได้ที่จัดการมัลติทัช ท่าทางสัมผัส
อินพุตสไตลัส
คุณกรองหาอินพุตสไตลัสได้ด้วย
TOOL_TYPE_STYLUS
val isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex)
สไตลัสยังสามารถรายงานได้ว่ามีการใช้เป็นยางลบ
TOOL_TYPE_ERASER
val isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex)
ข้อมูลแกนสไตลัส
ACTION_DOWN
และ ACTION_MOVE
ให้ข้อมูลแกนเกี่ยวกับสไตลัส ซึ่งได้แก่ x และ
พิกัด y ความดัน การวางแนว การเอียง และการลอยตัว
MotionEvent
API จะเตรียมการเข้าถึงข้อมูลนี้ไว้ให้
getAxisValue(int)
,
โดยที่พารามิเตอร์เป็นตัวระบุแกนต่อไปนี้
Axis | ผลลัพธ์ getAxisValue() |
---|---|
AXIS_X |
พิกัด X ของเหตุการณ์การเคลื่อนไหว |
AXIS_Y |
พิกัด Y ของเหตุการณ์การเคลื่อนไหว |
AXIS_PRESSURE |
สำหรับหน้าจอสัมผัสหรือทัชแพด แรงกดที่ใช้นิ้ว สไตลัส หรือตัวชี้อื่นๆ สำหรับเมาส์หรือแทร็กบอล ให้ใช้ 1 หากกดปุ่มหลัก มิฉะนั้นจะเป็น 0 |
AXIS_ORIENTATION |
สำหรับหน้าจอสัมผัสหรือทัชแพด จะมีการวางแนวของนิ้วมือ สไตลัส หรือตัวชี้อื่นๆ ที่สัมพันธ์กับระนาบแนวตั้งของอุปกรณ์ |
AXIS_TILT |
มุมเอียงของสไตลัสเป็นเรเดียน |
AXIS_DISTANCE |
ระยะห่างของสไตลัสจากหน้าจอ |
ตัวอย่างเช่น MotionEvent.getAxisValue(AXIS_X)
จะแสดงผลพิกัด x ของ
ตัวชี้แรก
โปรดดูหัวข้อจัดการมัลติทัช ท่าทางสัมผัส
ตำแหน่ง
คุณสามารถเรียกพิกัด x และ y ของตัวชี้ได้ด้วยการเรียกต่อไปนี้:
MotionEvent#getAxisValue(AXIS_X)
หรือMotionEvent#getX()
MotionEvent#getAxisValue(AXIS_Y)
หรือMotionEvent#getY()
![สไตลัสกำลังวาดบนหน้าจอโดยแมปพิกัด x และ y ไว้](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_x_y_coordinates.png?authuser=9&hl=th)
ความกดอากาศ
คุณสามารถดูความกดดันตัวชี้ได้ด้วย
MotionEvent#getAxisValue(AXIS_PRESSURE)
หรือสำหรับตัวชี้แรก
MotionEvent#getPressure()
ค่าแรงดันสำหรับหน้าจอสัมผัสหรือทัชแพดคือค่าระหว่าง 0 (no กด) และ 1 แต่อาจแสดงผลค่าที่สูงกว่า ทั้งนี้ขึ้นอยู่กับหน้าจอ การเทียบมาตรฐาน
![เส้นสไตลัสแสดงถึงความดันต่ำไปสูงอย่างต่อเนื่อง โรคหลอดเลือดสมองแคบและจางทางด้านซ้ายแสดงถึงความกดอากาศต่ำ เส้นโครงร่างกว้างขึ้นและมืดจากซ้ายไปขวาจนกว่าจะกว้างที่สุดและมืดที่สุดฝั่งขวาสุด แสดงถึงความกดอากาศสูงสุด](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_pressure.png?authuser=9&hl=th)
การวางแนว
การวางแนวจะระบุว่าสไตลัสกำลังชี้ไปในทิศทางใด
คุณดึงข้อมูลการวางแนวของเคอร์เซอร์ได้โดยใช้ getAxisValue(AXIS_ORIENTATION)
หรือ
getOrientation()
(สำหรับตัวชี้ตัวแรก)
สำหรับสไตลัส การวางแนวจะส่งคืนค่าเป็นค่าเรเดียนระหว่าง 0 ถึงพาย (π) ตามเข็มนาฬิกา หรือ 0 ถึง -pi ทวนเข็มนาฬิกา
การวางแนวช่วยให้คุณใช้แปรงในชีวิตจริงได้ ตัวอย่างเช่น หาก สไตลัสแสดงถึงแปรงแบน ความกว้างของแปรงแบนจะขึ้นอยู่กับ การวางแนวของสไตลัส
![](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_orientation.png?authuser=9&hl=th)
ทิลท์
การเอียงจะวัดความเอียงของสไตลัสโดยสัมพันธ์กับหน้าจอ
การเอียงจะแสดงมุมบวกของสไตลัสเป็นเรเดียน โดยที่ 0 เท่ากับ ตั้งฉากกับหน้าจอ และ π/2 แบนบนพื้นผิว
สามารถดึงข้อมูลมุมเอียงได้โดยใช้ getAxisValue(AXIS_TILT)
(ไม่มีทางลัดสำหรับ
เคอร์เซอร์ตัวแรก)
การเอียงสามารถใช้เพื่อทำให้ได้เครื่องมือในชีวิตจริงที่ใกล้เคียงที่สุดเท่าที่จะทำได้ เช่น ที่เลียนแบบการลงสีด้วยดินสอเอียง
![สไตลัสเอียงจากพื้นผิวหน้าจอประมาณ 40 องศา](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_tilt.png?authuser=9&hl=th)
วางเมาส์
ระยะห่างของสไตลัสจากหน้าจอสามารถวัดได้ด้วย
getAxisValue(AXIS_DISTANCE)
เมธอดแสดงค่าจาก 0.0 (ติดต่อกับ
หน้าจอ) เป็นค่าที่สูงขึ้นเมื่อสไตลัสเลื่อนออกจากหน้าจอ โฮเวอร์
ระยะห่างระหว่างหน้าจอกับปลายนิ้ว (จุด) ของสไตลัสขึ้นอยู่กับ
ผู้ผลิตทั้งหน้าจอและสไตลัส เนื่องจากการติดตั้งใช้งานอาจ
ปรับเปลี่ยนได้ อย่าใช้ค่าที่แน่นอนสำหรับฟังก์ชันการทำงานที่สำคัญของแอป
การวางเมาส์เหนือสไตลัสสามารถใช้เพื่อดูตัวอย่างขนาดแปรงหรือบ่งชี้ว่า จะถูกเลือก
![](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_hover.png?authuser=9&hl=th)
หมายเหตุ: Compose มีตัวแก้ไขที่ส่งผลต่อสถานะแบบอินเทอร์แอกทีฟขององค์ประกอบ UI ดังนี้
hoverable
: กำหนดค่าคอมโพเนนต์ให้วางเมาส์เหนือองค์ประกอบได้โดยใช้ตัวชี้ในเหตุการณ์การเข้าและออกindication
: วาดเอฟเฟกต์ภาพสำหรับคอมโพเนนต์นี้เมื่อมีการโต้ตอบ
การปฏิเสธฝ่ามือ การนำทาง และข้อมูลที่ไม่ต้องการ
บางครั้งหน้าจอแบบมัลติทัชอาจบันทึกการสัมผัสที่ไม่พึงประสงค์ เช่น เมื่อ
ตามปกติแล้ว ผู้ใช้จะวางมืออยู่บนหน้าจอเพื่อให้การสนับสนุนขณะเขียนด้วยลายมือ
การปฏิเสธปาล์มเป็นกลไกที่จะตรวจจับพฤติกรรมนี้และแจ้งให้คุณทราบว่า
ระบบควรยกเลิก MotionEvent
ชุดสุดท้ายแล้ว
ดังนั้น คุณจึงต้องเก็บประวัติข้อมูลจากผู้ใช้ เพื่อไม่ให้เกิดการสัมผัสที่ไม่พึงประสงค์ สามารถถูกนำออกจากหน้าจอ และข้อมูลที่ถูกต้องของผู้ใช้สามารถ แสดงผลอีกครั้ง
ACTION_CANCEL และ FLAG_CANCELED
ACTION_CANCEL
และ
FLAG_CANCELED
คือ
ทั้งคู่ออกแบบมาเพื่อแจ้งให้คุณทราบว่า MotionEvent
ชุดก่อนหน้าควร
ยกเลิกตั้งแต่ ACTION_DOWN
ที่แล้ว เพื่อให้คุณสามารถเลิกทำ
เส้นสำหรับแอปพลิเคชันวาดภาพสำหรับตัวชี้ที่ระบุ
การดำเนินการยกเลิก
เพิ่มใน Android 1.0 (API ระดับ 1) แล้ว
ACTION_CANCEL
บ่งชี้ว่าควรยกเลิกเหตุการณ์การเคลื่อนไหวชุดก่อนหน้า
ACTION_CANCEL
จะทริกเกอร์เมื่อตรวจพบสิ่งต่อไปนี้
- ท่าทางสัมผัสสำหรับการนำทาง
- การปฏิเสธปาล์ม
เมื่อ ACTION_CANCEL
ทริกเกอร์ คุณควรระบุตัวชี้ที่ใช้งานอยู่ด้วย
getPointerId(getActionIndex())
จากนั้นลบเส้นโครงร่างที่สร้างด้วยตัวชี้นั้นออกจากประวัติการป้อนข้อมูล แล้วแสดงผลฉากอีกครั้ง
FLAG_CANCELED
เพิ่มใน Android 13 (API ระดับ 33) แล้ว
FLAG_CANCELED
ชี้ให้เห็นว่าตัวชี้ที่เพิ่มขึ้นเป็นการแตะโดยไม่ได้ตั้งใจ ธงคือ
ซึ่งมักจะเกิดขึ้นเมื่อผู้ใช้แตะหน้าจอโดยไม่ตั้งใจ เช่น การจับ
หรือวางฝ่ามือลงบนหน้าจอ
คุณเข้าถึงค่า Flag ดังนี้
val cancel = (event.flags and FLAG_CANCELED) == FLAG_CANCELED
หากตั้งค่าไว้ คุณจะต้องเลิกทำ MotionEvent
จากชุดสุดท้าย
ACTION_DOWN
จากจุดนี้
ซึ่งเหมือนกับ ACTION_CANCEL
คุณจะพบเครื่องหมายดังกล่าวได้ด้วย getPointerId(actionIndex)
MotionEvent
ชุด การแตะแบบใช้ฝ่ามือถูกยกเลิกและการแสดงผลอีกครั้ง
ท่าทางสัมผัสแบบเต็มหน้าจอ ขอบต่อขอบ และการนำทาง
หากแอปแบบเต็มหน้าจอและมีองค์ประกอบที่ดำเนินการได้อยู่ใกล้กับขอบ เช่น แคนวาสของแอปวาดภาพหรือจดโน้ต เลื่อนจากด้านล่างของหน้าจอไปยัง แสดงการนำทางหรือย้ายแอปไปที่พื้นหลังอาจทำให้เกิด บนผืนผ้าใบที่ไม่พึงประสงค์
หากต้องการป้องกันไม่ให้ท่าทางสัมผัสทำให้เกิดการแตะที่ไม่ต้องการในแอป คุณสามารถทำดังนี้
ข้อได้เปรียบของตัวอย่างและ
ACTION_CANCEL
ดูการปฏิเสธฝ่ามือ การนำทาง และการป้อนข้อมูลที่ไม่พึงประสงค์ด้วย
ใช้เมนู
setSystemBarsBehavior()
วิธีการและ
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
จาก
WindowInsetsController
วิธีป้องกันไม่ให้ท่าทางสัมผัสการนำทางก่อให้เกิดกิจกรรมการแตะที่ไม่พึงประสงค์
// Configure the behavior of the hidden system bars.
windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการด้านการตั้งค่าและท่าทางสัมผัสได้ที่
- ซ่อนแถบระบบสำหรับโหมดใหญ่พิเศษ
- ตรวจสอบความเข้ากันได้กับการนำทางด้วยท่าทางสัมผัส
- แสดงเนื้อหาแบบไร้ขอบในแอป
เวลาในการตอบสนองต่ำ
เวลาในการตอบสนองคือเวลาที่ฮาร์ดแวร์ ระบบ และแอปพลิเคชันต้องการในการประมวลผล และแสดงผลข้อมูลจากผู้ใช้
เวลาในการตอบสนอง = การประมวลผลอินพุตฮาร์ดแวร์และระบบปฏิบัติการ + การประมวลผลแอป + การจัดวางองค์ประกอบของระบบ
- การแสดงภาพฮาร์ดแวร์
![เวลาในการตอบสนองทำให้เส้นโครงร่างที่แสดงผลช้ากว่าตำแหน่งสไตลัส ช่องว่างระหว่างเส้นโครงร่างที่แสดงและตำแหน่งสไตลัสแสดงถึงเวลาในการตอบสนอง](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_latency.png?authuser=9&hl=th)
แหล่งที่มาของเวลาในการตอบสนอง
- กำลังลงทะเบียนสไตลัสด้วยหน้าจอสัมผัส (ฮาร์ดแวร์): การเชื่อมต่อไร้สายเริ่มต้น เมื่อสไตลัสและระบบปฏิบัติการสื่อสารกันเพื่อลงทะเบียนและซิงค์
- อัตราการสุ่มตัวอย่างการแตะ (ฮาร์ดแวร์): จำนวนครั้งต่อวินาทีบนหน้าจอสัมผัส ตรวจสอบว่าตัวชี้สัมผัสพื้นผิวหรือไม่ มีค่าตั้งแต่ 60 ถึง 1000Hz
- การประมวลผลอินพุต (แอป): การใช้สี เอฟเฟกต์กราฟิก และการเปลี่ยนรูปแบบ ในข้อมูลจากผู้ใช้
- การแสดงผลกราฟิก (ระบบปฏิบัติการ + ฮาร์ดแวร์): การเปลี่ยนบัฟเฟอร์ การประมวลผลด้วยฮาร์ดแวร์
กราฟิกที่มีเวลาในการตอบสนองต่ำ
ไลบรารีกราฟิกที่มีเวลาในการตอบสนองต่ำของ Jetpack ซึ่งช่วยลดเวลาในการประมวลผลระหว่างการป้อนข้อมูลของผู้ใช้และการแสดงผลบนหน้าจอ
ไลบรารีจะลดเวลาในการประมวลผลโดยหลีกเลี่ยงการแสดงผลแบบบัฟเฟอร์หลายตัว ใช้เทคนิคการแสดงผลแบบ Front-Buffers ซึ่งหมายความว่าเขียน หน้าจอ
การแสดงภาพบัฟเฟอร์ด้านหน้า
บัฟเฟอร์ด้านหน้าคือหน่วยความจำที่หน้าจอใช้ในการแสดงผล อยู่ใกล้ที่สุด แอปจะเปลี่ยนไปวาดภาพบนหน้าจอได้โดยตรง ไลบรารีที่มีเวลาในการตอบสนองต่ำจะเปิดใช้ เพื่อแสดงไปยังบัฟเฟอร์ด้านหน้าโดยตรง ซึ่งจะช่วยปรับปรุงประสิทธิภาพโดย เพื่อป้องกันการสลับบัฟเฟอร์ ซึ่งอาจเกิดขึ้นในการแสดงผลแบบบัฟเฟอร์หลายตัวตามปกติ หรือการแสดงภาพบัฟเฟอร์คู่ (กรณีที่พบบ่อยที่สุด)
![แอปเขียนไปยังบัฟเฟอร์หน้าจอและอ่านจากบัฟเฟอร์หน้าจอ](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/front_buffer_rendering.png?authuser=9&hl=th)
![แอปเขียนไปยังโหมดบัฟเฟอร์หลายรายการ ซึ่งสลับกับบัฟเฟอร์หน้าจอ แอปอ่านจากบัฟเฟอร์หน้าจอ](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/multi-buffer_rendering.png?authuser=9&hl=th)
ขณะที่การแสดงผลแบบบัฟเฟอร์หน้าเป็นเทคนิคที่ยอดเยี่ยมในการแสดงผลพื้นที่เล็กๆ ของกราฟ ไม่ได้ออกแบบมาให้ใช้เพื่อรีเฟรชทั้งหน้าจอ ด้วย การแสดงผลแบบฟรอนท์-บัฟเฟอร์ โดยแอปกำลังแสดงเนื้อหาลงในบัฟเฟอร์ที่ จอแสดงผลกำลังอ่านอยู่ จึงมีโอกาสแสดงผล สิ่งประดิษฐ์หรือการฉีกขาด (ดูด้านล่าง)
ไลบรารีที่มีเวลาในการตอบสนองต่ำพร้อมใช้งานตั้งแต่ Android 10 (API ระดับ 29) ขึ้นไป และในอุปกรณ์ ChromeOS ที่ใช้ Android 10 (API ระดับ 29) ขึ้นไป
การขึ้นต่อกัน
ไลบรารีที่มีเวลาในการตอบสนองต่ำมอบคอมโพเนนต์สำหรับการแสดงภาพบัฟเฟอร์ด้านหน้า
การใช้งานของคุณ เพิ่มไลบรารีเป็นทรัพยากร Dependency ในโมดูลของแอป
build.gradle
ไฟล์:
dependencies {
implementation "androidx.graphics:graphics-core:1.0.0-alpha03"
}
Callback ของ GLFrontBufferRenderer
ไลบรารีที่มีเวลาในการตอบสนองต่ำประกอบด้วย
GLFrontBufferRenderer.Callback
ของอินเทอร์เฟซ ซึ่งจะกำหนดวิธีการดังต่อไปนี้
ไลบรารีที่มีเวลาในการตอบสนองต่ำไม่มีความคิดเห็นเกี่ยวกับประเภทข้อมูลที่คุณใช้
GLFrontBufferRenderer
อย่างไรก็ตาม ไลบรารีจะประมวลผลข้อมูลเป็นสตรีมของจุดข้อมูลหลายร้อยจุด ดังนั้น ให้ออกแบบข้อมูลของคุณเพื่อเพิ่มประสิทธิภาพการใช้งานและการจัดสรรหน่วยความจำ
Callback
หากต้องการเปิดใช้การแสดงผล Callback ให้ใช้ GLFrontBufferedRenderer.Callback
และ
ลบล้าง onDrawFrontBufferedLayer()
และ onDrawDoubleBufferedLayer()
GLFrontBufferedRenderer
ใช้ Callback เพื่อแสดงผลข้อมูลของคุณใน
ทางที่ดีที่สุดเท่าที่จะเป็นไปได้
val callback = object: GLFrontBufferedRenderer.Callback<DATA_TYPE> {
override fun onDrawFrontBufferedLayer(
eglManager: EGLManager,
bufferInfo: BufferInfo,
transform: FloatArray,
param: DATA_TYPE
) {
// OpenGL for front buffer, short, affecting small area of the screen.
}
override fun onDrawMultiDoubleBufferedLayer(
eglManager: EGLManager,
bufferInfo: BufferInfo,
transform: FloatArray,
params: Collection<DATA_TYPE>
) {
// OpenGL full scene rendering.
}
}
ประกาศอินสแตนซ์ของ GLFrontBufferedRenderer
จัดเตรียม GLFrontBufferedRenderer
ด้วยการระบุ SurfaceView
และ
Callback ที่คุณสร้างไว้ก่อนหน้านี้ GLFrontBufferedRenderer
เพิ่มประสิทธิภาพการแสดงผล
ข้างหน้าและบัฟเฟอร์คู่โดยใช้ Callback ของคุณ:
var glFrontBufferRenderer = GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks)
การแสดงภาพ
การแสดงผลบัฟเฟอร์ด้านหน้าจะเริ่มเมื่อคุณเรียก
renderFrontBufferedLayer()
ซึ่งจะทริกเกอร์ Callback onDrawFrontBufferedLayer()
การแสดงผลแบบบัฟเฟอร์คู่จะกลับมาทำงานอีกครั้งเมื่อคุณเรียกฟังก์ชัน
commit()
ซึ่งจะทริกเกอร์ Callback onDrawMultiDoubleBufferedLayer()
ในตัวอย่างต่อไปนี้ กระบวนการแสดงผลไปยังบัฟเฟอร์ด้านหน้า (
การแสดงผล) เมื่อผู้ใช้เริ่มวาดบนหน้าจอ (ACTION_DOWN
) และเคลื่อนที่
ตัวชี้ไปรอบๆ (ACTION_MOVE
) กระบวนการแสดงผลเป็นบัฟเฟอร์คู่
เมื่อตัวชี้ออกจากพื้นผิวของหน้าจอ (ACTION_UP
)
คุณสามารถใช้
requestUnbufferedDispatch()
ระบบอินพุตไม่ได้รวมกลุ่มเหตุการณ์การเคลื่อนไหว แต่ส่งแทน
ทันทีที่พร้อมใช้งาน ให้ทำดังนี้
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
// Deliver input events as soon as they arrive.
view.requestUnbufferedDispatch(motionEvent)
// Pointer is in contact with the screen.
glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
}
MotionEvent.ACTION_MOVE -> {
// Pointer is moving.
glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
}
MotionEvent.ACTION_UP -> {
// Pointer is not in contact in the screen.
glFrontBufferRenderer.commit()
}
MotionEvent.CANCEL -> {
// Cancel front buffer; remove last motion set from the screen.
glFrontBufferRenderer.cancel()
}
}
สิ่งที่ควรและไม่ควรทำเกี่ยวกับการแสดงภาพ
พื้นที่เล็กๆ ของหน้าจอ การเขียนด้วยลายมือ การวาดภาพ การร่างภาพ
การอัปเดตแบบเต็มหน้าจอ การเลื่อน การซูม อาจทำให้น้ำตาไหล
น้ำตาไหล
การฉีกขาดเกิดขึ้นเมื่อหน้าจอรีเฟรชขณะบัฟเฟอร์หน้าจอ ที่ถูกแก้ไขในเวลาเดียวกัน หน้าจอบางส่วนแสดงข้อมูลใหม่ ส่วนอีกหน้าจอหนึ่ง แสดงข้อมูลเก่า
![ส่วนบนและล่างของรูปภาพ Android วางไม่ตรงแนวเนื่องจากมีการฉีกขาดเมื่อรีเฟรชหน้าจอ](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/tearing.png?authuser=9&hl=th)
การคาดการณ์การเคลื่อนไหว
การคาดการณ์การเคลื่อนไหว Jetpack การลดไลบรารี เวลาในการตอบสนองที่รับรู้ได้โดยการประมาณเส้นทาง ของโรคหลอดเลือดสมองของผู้ใช้ และระบุชั่วคราว ไปยังตัวแสดงผล
ไลบรารีการคาดการณ์การเคลื่อนไหวได้รับข้อมูลจริงจากผู้ใช้เป็นออบเจ็กต์ MotionEvent
วัตถุต่างๆ มีข้อมูลเกี่ยวกับพิกัด x และ y, ความดัน และเวลา
ซึ่งเครื่องมือคาดการณ์การเคลื่อนไหวใช้ประโยชน์จากเพื่อคาดการณ์ MotionEvent
ในอนาคต
ออบเจ็กต์
ออบเจ็กต์ MotionEvent
ที่คาดการณ์ไว้เป็นเพียงค่าประมาณเท่านั้น เหตุการณ์ที่คาดการณ์อาจลดจำนวน
เวลาในการตอบสนองที่รับรู้ แต่ต้องแทนที่ข้อมูลที่คาดการณ์ไว้ด้วย MotionEvent
จริง
ข้อมูลทันทีที่ได้รับ
ไลบรารีการคาดการณ์การเคลื่อนไหวมีให้บริการใน Android 4.4 (API ระดับ 19) และ และในอุปกรณ์ ChromeOS ที่ใช้ Android 9 (API ระดับ 28) ขึ้นไป
![เวลาในการตอบสนองทำให้เส้นโครงร่างที่แสดงผลช้ากว่าตำแหน่งสไตลัส ช่องว่างระหว่างเส้นโครงร่างและสไตลัสเต็มไปด้วยจุดการคาดคะเน ช่องว่างที่เหลือคือเวลาในการตอบสนองที่รับรู้](https://developer.android.google.cn/static/images/develop/ui/compose/touch-input/stylus-input/advanced-stylus/stylus_reduced_latency.png?authuser=9&hl=th)
การขึ้นต่อกัน
ไลบรารีการคาดการณ์การเคลื่อนไหวจะนำเสนอการใช้การคาดการณ์
เพิ่มไลบรารีเป็นทรัพยากร Dependency ในไฟล์โมดูล build.gradle
ของแอปแล้ว:
dependencies {
implementation "androidx.input:input-motionprediction:1.0.0-beta01"
}
การใช้งาน
ไลบรารีการคาดการณ์การเคลื่อนไหวประกอบด้วย
MotionEventPredictor
ของอินเทอร์เฟซ ซึ่งจะกำหนดวิธีการดังต่อไปนี้
record()
จัดเก็บออบเจ็กต์MotionEvent
รายการเป็นบันทึกการดำเนินการของผู้ใช้predict()
แสดงผลMotionEvent
ที่คาดการณ์ไว้
ประกาศอินสแตนซ์ของ MotionEventPredictor
var motionEventPredictor = MotionEventPredictor.newInstance(view)
ป้อนข้อมูลให้กับตัวคาดการณ์
motionEventPredictor.record(motionEvent)
คาดการณ์
when (motionEvent.action) {
MotionEvent.ACTION_MOVE -> {
val predictedMotionEvent = motionEventPredictor?.predict()
if(predictedMotionEvent != null) {
// use predicted MotionEvent to inject a new artificial point
}
}
}
สิ่งที่ควรและไม่ควรทำสำหรับการคาดการณ์การเคลื่อนไหว
นำจุดการคาดการณ์ออกเมื่อมีการเพิ่มจุดที่คาดการณ์ใหม่
อย่าใช้จุดการคาดการณ์สำหรับการแสดงผลขั้นสุดท้าย
แอปสำหรับจดบันทึก
ChromeOS จะช่วยให้แอปของคุณประกาศการดำเนินการจดโน้ตบางอย่าง
หากต้องการลงทะเบียนแอปเป็นแอปสำหรับจดโน้ตบน ChromeOS โปรดดูการป้อนข้อมูล ความเข้ากันได้
หากต้องการลงทะเบียนแอปเป็นการจดโน้ตใน Android โปรดดูสร้างการจดโน้ต แอป
Android 14 (API ระดับ 34) เปิดตัว
ACTION_CREATE_NOTE
Intent ซึ่งทำให้แอปเริ่มกิจกรรมการจดบันทึกบนล็อก
บนหน้าจอ
การจดจำหมึกดิจิทัลด้วย ML Kit
ด้วยหมึกดิจิทัล ML Kit การจดจำเสียง แอปของคุณสามารถจดจำข้อความที่เขียนด้วยลายมือบนพื้นผิวดิจิทัลหลายร้อยรายการ ภาษา และจำแนกประเภทภาพร่างได้ด้วย
ML Kit มอบ
Ink.Stroke.Builder
เพื่อสร้างออบเจ็กต์ Ink
รายการที่โมเดลแมชชีนเลิร์นนิงสามารถประมวลผลได้
เพื่อแปลงการเขียนด้วยลายมือเป็นข้อความ
นอกจากการจดจำลายมือแล้ว โมเดลยังรับรู้การ ท่าทางสัมผัส เช่น ลบและแวดวง
ดูหมึกดิจิทัล การจดจำ เพื่อดูข้อมูลเพิ่มเติม