في التصميمات المستندة إلى طرق العرض، عليك التعامل مع إدخالات اللمس الخاصة بالمستخدمين داخل
InProgressStrokesView بالإضافة إلى
MotionEventPredictor.
لتحقيق أفضل أداء في الرسم، استخدِم الطرق
startStroke() وaddToStroke()
وfinishStroke() للفئة
InProgressStrokesView، مع تمرير عناصر
MotionEvent كمدخلات:
إعداد مكوّن واجهة المستخدم
بالنسبة إلى التصميمات المستندة إلى العرض، أضِف
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()للنشاط أو الجزء، احصل على مرجع إلىInProgressStrokesViewواضبط أداة معالجة اللمس لإدارة إدخال المستخدم.ضمن طريقة [
onCreate()][ink-draw-include6] للنشاط أو المقتطف، احصل على إشارة إلىInProgressStrokesViewوأنشئ معالجًا لللمس لإدارة إدخال المستخدم.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) }التعامل مع أحداث اللمس
بعد إنشاء عناصر واجهة المستخدم، يمكنك بدء الرسم استنادًا إلى أحداث اللمس.
MotionEventإجراءطريقة
InProgressStrokesViewالوصف
بدء عرض ضربات الفرشاة
تمديد الخط
إنهاء عمليات الإدخال والاستعداد لإنهاء شكل الضربة
إلغاء الضربة
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()، تكون السكتة الدماغية قد اكتملت تقريبًا. تتم معالجة الضربة بالكامل وتصبح متاحة لتطبيقك عندما لا تكون هناك ضربات أخرى قيد التقدم. يضمن ذلك إكمال جميع عمليات الرسم قبل تسليم الضربة إلى العميل.لاسترداد الضربات المنتهية، لديك خياران:
- نفِّذ واجهة
InProgressStrokesFinishedListenerفي نشاطك أو ViewModel، وسجِّل المتلقّي باستخدام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, ... } } }- نفِّذ واجهة