ในเลย์เอาต์ที่อิงตามมุมมอง คุณต้องจัดการอินพุตการสัมผัสของผู้ใช้ภายใน
InProgressStrokesView นอกเหนือจาก
MotionEventPredictor
หากต้องการให้การวาดภาพมีประสิทธิภาพสูงสุด ให้ใช้วิธีการ
startStroke(), addToStroke()
และ finishStroke() ของคลาส
InProgressStrokesView โดยส่งออบเจ็กต์
MotionEvent เป็นอินพุต
ตั้งค่าคอมโพเนนต์ UI
สำหรับเลย์เอาต์ที่อิงตามมุมมอง ให้เพิ่ม
InProgressStrokesViewลงในลำดับชั้นของมุมมอง<FrameLayout> <ScrollView android:id="@+id/my_content" android:width="match_parent" android:height="match_parent" > <!-- Your content here. --> </ScrollView> <androidx.ink.authoring.InProgressStrokesView android:id="@+id/in_progress_strokes_view" android:width="match_parent" android:height="match_parent" /> </FrameLayout>Instantiate
InProgressStrokesViewภายในเมธอด
onCreate()ของกิจกรรมหรือ Fragment ให้ รับการอ้างอิงไปยังInProgressStrokesViewและ ตั้งค่า Listener การแตะเพื่อจัดการอินพุตของผู้ใช้ภายในเมธอด [
onCreate()][ink-draw-include6] ของกิจกรรมหรือส่วนย่อย ขอรับข้อมูลอ้างอิงInProgressStrokesViewและสร้าง แตะ Listener เพื่อจัดการอินพุตของผู้ใช้class MyActivity : View.OnTouchListener { private lateinit var contentView: ScrollView private lateinit var inProgressStrokesView: InProgressStrokesView private lateinit var predictor: MotionEventPredictor // ... other variables override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) predictor = MotionEventPredictor.newInstance(contentView) contentView = findViewById(R.id.my_content) contentView.setOnTouchListener(touchListener) inProgressStrokesView = findViewById(R.id.in_progress_strokes_view) } // ... (touchListener implementation) }จัดการเหตุการณ์การสัมผัส
เมื่อสร้างคอมโพเนนต์ UI แล้ว คุณจะเริ่มวาดโดยอิงตาม เหตุการณ์การแตะได้
MotionEventactionInProgressStrokesViewmethodคำอธิบาย
เริ่มการแสดงผลเส้น
ขยายเส้น
ป้อนข้อมูลให้เสร็จ เตรียมพร้อมที่จะสรุปเรขาคณิตของเส้น
ยกเลิกการลากเส้น
class MyActivity : View.OnTouchListener { private lateinit var contentView: ScrollView private lateinit var inProgressStrokesView: InProgressStrokesView private var pointerId = -1 private var strokeId: InProgressStrokeId? = null private lateinit var predictor: MotionEventPredictor override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) contentView = findViewById(R.id.my_content) predictor = MotionEventPredictor.create(contentView) contentView.setOnTouchListener(touchListener) inProgressStrokesView = findViewById(R.id.in_progress_strokes_view) } private val touchListener = { view: View, event: MotionEvent -> predictor.record(event) when (event.actionMasked) { MotionEvent.ACTION_DOWN -> { // First pointer - treat it as inking. view.requestUnbufferedDispatch(event) val pointerIndex = event.actionIndex pointerIdToStrokeId[event.getPointerId(pointerIndex)] = inProgressStrokesView.startStroke(event, pointerId) return true } MotionEvent.ACTION_POINTER_DOWN -> { val stroke = strokeId ?: return false inProgressStrokesView.cancelStroke(stroke, event) strokeId = null pointerId = -1 return false } MotionEvent.ACTION_MOVE -> { val predictedEvent = predictor.predict() try { for (pointerIndex in 0 until pointerCount) { val strokeId = pointerIdToStrokeId[event.getPointerId(pointerIndex)] ?: continue inProgressStrokesView.addToStroke(event, pointerId, strokeId, predictedEvent) } finally { predictedEvent?.recycle() } } } MotionEvent.ACTION_UP -> { val pointerIndex = event.actionIndex val strokeId = pointerIdToStrokeId[event.getPointerId(pointerIndex)] ?: return false inProgressStrokesView.finishStroke(event, pointerId, strokeId) return true } MotionEvent.ACTION_CANCEL -> { val pointerIndex = event.actionIndex val strokeId = pointerIdToStrokeId[event.getPointerId(pointerIndex)] ?: return false inProgressStrokesView.cancelStroke(strokeId, event) return true } } return false } }จัดการสโตรกที่วาดเสร็จแล้ว
หลังจาก
finishStroke()เส้นจะเกือบเสร็จสมบูรณ์ ระบบจะประมวลผลลายเส้นจนเสร็จสมบูรณ์และแอปพลิเคชันของคุณจะเข้าถึงลายเส้นได้ เมื่อไม่มีลายเส้นอื่นๆ ที่อยู่ระหว่างดำเนินการ ซึ่งจะช่วยให้มั่นใจได้ว่าการวาดทั้งหมด จะเสร็จสมบูรณ์ก่อนส่งลายเส้นไปยังไคลเอ็นต์หากต้องการดึงลายเส้นที่วาดเสร็จแล้ว คุณมี 2 ตัวเลือกดังนี้
- ใช้
InProgressStrokesFinishedListenerอินเทอร์เฟซภายในกิจกรรมหรือ ViewModel และลงทะเบียน Listener ด้วยInProgressStrokesViewโดยการเรียกใช้addFinishedStrokesListener - โทรหา
InProgressStrokesView.getFinishedStrokes()เพื่อรับจังหวะการตีทั้งหมดที่เสร็จสมบูรณ์โดยตรง
class MyActivity : ComponentActivity(), InProgressStrokesFinishedListener { ... private val finishedStrokesState = mutableStateOf(emptySet<Stroke>()) override fun onCreate(savedInstanceState: Bundle?) { ... inProgressStrokesView.addFinishedStrokesListener(this) } // ... (handle touch events) @UiThread override fun onStrokesFinished(strokes: Map<InProgressStrokeId, Stroke>) { finishedStrokesState.value += strokes.values inProgressStrokesView.removeFinishedStrokes(strokes.keys) } }เมื่อดึงเส้นที่วาดเสร็จแล้ว คุณจะใช้
ViewStrokeRendererเพื่อวาดเส้นเหล่านั้นได้โดยทำดังนี้class DrawingView(context: Context) : View(context) { private val viewStrokeRenderer = ViewStrokeRenderer(myCanvasStrokeRenderer, this) override fun onDraw(canvas: Canvas) { viewStrokeRenderer.drawWithStrokes(canvas) { scope -> canvas.scale(myZoomLevel) canvas.rotate(myRotation) canvas.translate(myPanX, myPanY) scope.drawStroke(myStroke) // Draw other objects including more strokes, apply more transformations, ... } } }- ใช้