মাল্টি-টাচ অঙ্গভঙ্গি পরিচালনা করুন

রচনা পদ্ধতি চেষ্টা করুন
জেটপ্যাক কম্পোজ হল Android এর জন্য প্রস্তাবিত UI টুলকিট। কম্পোজে কীভাবে স্পর্শ এবং ইনপুট ব্যবহার করবেন তা শিখুন।

মাল্টি-টাচ জেসচার হল যখন একাধিক পয়েন্টার (আঙ্গুল) একই সময়ে স্ক্রীনে ট্যাপ করে। এই নথিটি বর্ণনা করে যে কীভাবে একাধিক পয়েন্টার জড়িত অঙ্গভঙ্গি সনাক্ত করতে হয়।

একাধিক পয়েন্টার ট্র্যাক করুন

যখন একাধিক পয়েন্টার একই সময়ে স্ক্রীনে ট্যাপ করে, তখন সিস্টেম নিম্নলিখিত স্পর্শ ইভেন্টগুলি তৈরি করে:

  • ACTION_DOWN : যখন প্রথম পয়েন্টার স্ক্রীনে ট্যাপ করে তখন পাঠানো হয়। এই অঙ্গভঙ্গি শুরু হয়. এই পয়েন্টারের জন্য পয়েন্টার ডেটা সর্বদা MotionEvent সূচক 0 এ থাকে।
  • ACTION_POINTER_DOWN : প্রথমটির পরে অতিরিক্ত পয়েন্টার স্ক্রীনে প্রবেশ করলে পাঠানো হয়। getActionIndex() ব্যবহার করে আপনি পয়েন্টারের সূচী পেতে পারেন যা সবেমাত্র নিচে নেমে গেছে।
  • ACTION_MOVE : যেকোন সংখ্যক পয়েন্টার যুক্ত ভঙ্গিতে পরিবর্তন ঘটলে পাঠানো হয়।
  • ACTION_POINTER_UP : একটি অ-প্রাথমিক পয়েন্টার উপরে গেলে পাঠানো হয়। getActionIndex() ব্যবহার করে আপনি পয়েন্টারের সূচী পেতে পারেন যা সবেমাত্র উপরে উঠেছিল।
  • ACTION_UP : যখন শেষ পয়েন্টারটি স্ক্রীন ছেড়ে চলে যায় তখন পাঠানো হয়।
  • ACTION_CANCEL : নির্দেশ করে যে সমস্ত পয়েন্টার সহ সম্পূর্ণ অঙ্গভঙ্গি বাতিল করা হয়েছে৷

শুরু এবং শেষ অঙ্গভঙ্গি

একটি অঙ্গভঙ্গি হল একটি ACTION_DOWN ইভেন্ট থেকে শুরু হওয়া এবং একটি ACTION_UP বা ACTION_CANCEL ইভেন্টের মাধ্যমে শেষ হওয়া ইভেন্টগুলির একটি সিরিজ৷ একটি সময়ে একটি সক্রিয় অঙ্গভঙ্গি আছে. ডাউন, মুভ, উপরে এবং ক্যান্সেল অ্যাকশনগুলি পুরো অঙ্গভঙ্গিতে প্রযোজ্য। উদাহরণস্বরূপ, ACTION_MOVE সহ একটি ইভেন্ট সেই মুহুর্তে সমস্ত পয়েন্টার নিচের জন্য একটি আন্দোলন নির্দেশ করতে পারে।

পয়েন্টার ট্র্যাক রাখুন

একটি MotionEvent মধ্যে পৃথক পয়েন্টার অবস্থানের ট্র্যাক রাখতে পয়েন্টারের সূচী এবং ID ব্যবহার করুন।

  • সূচক : একটি MotionEvent একটি অ্যারেতে পয়েন্টার তথ্য সঞ্চয় করে। একটি পয়েন্টারের সূচক হল এই অ্যারের মধ্যে তার অবস্থান। বেশিরভাগ MotionEvent পদ্ধতি পয়েন্টার আইডির পরিবর্তে পয়েন্টার সূচকটিকে একটি প্যারামিটার হিসাবে নেয়।
  • আইডি : প্রতিটি পয়েন্টারে একটি আইডি ম্যাপিংও রয়েছে যা সম্পূর্ণ অঙ্গভঙ্গি জুড়ে একটি পৃথক পয়েন্টার ট্র্যাক করার অনুমতি দেওয়ার জন্য স্পর্শ ইভেন্ট জুড়ে অবিরাম থাকে।

স্বতন্ত্র পয়েন্টারগুলি একটি অনির্ধারিত ক্রমে একটি গতি ইভেন্টের মধ্যে উপস্থিত হয়। এইভাবে, একটি পয়েন্টারের সূচী একটি ইভেন্ট থেকে অন্য ইভেন্টে পরিবর্তিত হতে পারে, তবে পয়েন্টারটি যতক্ষণ সক্রিয় থাকে ততক্ষণ একটি পয়েন্টারের পয়েন্টার আইডি স্থির থাকার গ্যারান্টি দেওয়া হয়। একটি অঙ্গভঙ্গিতে পরবর্তী সমস্ত গতি ইভেন্ট জুড়ে পয়েন্টার ট্র্যাক করতে একটি পয়েন্টারের আইডি পেতে getPointerId() পদ্ধতিটি ব্যবহার করুন৷ তারপর, ধারাবাহিক মোশন ইভেন্টের জন্য, সেই মোশন ইভেন্টে একটি প্রদত্ত পয়েন্টার আইডির জন্য পয়েন্টার সূচক পেতে findPointerIndex() পদ্ধতি ব্যবহার করুন। যেমন:

কোটলিন

private var mActivePointerId: Int = 0

override fun onTouchEvent(event: MotionEvent): Boolean {
    ...
    // Get the pointer ID.
    mActivePointerId = event.getPointerId(0)

    // ... Many touch events later...

    // Use the pointer ID to find the index of the active pointer
    // and fetch its position.
    val (x: Float, y: Float) = event.findPointerIndex(mActivePointerId).let { pointerIndex ->
        // Get the pointer's current position.
        event.getX(pointerIndex) to event.getY(pointerIndex)
    }
    ...
}

জাভা

private int mActivePointerId;

public boolean onTouchEvent(MotionEvent event) {
    ...
    // Get the pointer ID.
    mActivePointerId = event.getPointerId(0);

    // ... Many touch events later...

    // Use the pointer ID to find the index of the active pointer
    // and fetch its position.
    int pointerIndex = event.findPointerIndex(mActivePointerId);
    // Get the pointer's current position.
    float x = event.getX(pointerIndex);
    float y = event.getY(pointerIndex);
    ...
}

একাধিক টাচ পয়েন্টারকে সমর্থন করার জন্য, আপনি সমস্ত সক্রিয় পয়েন্টারকে তাদের পৃথক ACTION_POINTER_DOWN এবং ACTION_DOWN ইভেন্টের সময়ে তাদের ID সহ ক্যাশে করতে পারেন৷ তাদের ACTION_POINTER_UP এবং ACTION_UP ইভেন্টে আপনার ক্যাশে থেকে পয়েন্টারগুলি সরান৷ অন্যান্য অ্যাকশন ইভেন্টগুলিকে সঠিকভাবে পরিচালনা করতে আপনি এই ক্যাশ করা আইডিগুলিকে সহায়ক মনে করতে পারেন৷ উদাহরণস্বরূপ, একটি ACTION_MOVE ইভেন্ট প্রক্রিয়া করার সময়, প্রতিটি ক্যাশ করা সক্রিয় পয়েন্টার আইডির জন্য সূচক খুঁজুন, getX() এবং getY() ফাংশন ব্যবহার করে পয়েন্টারের স্থানাঙ্ক পুনরুদ্ধার করুন, তারপর কোন পয়েন্টার সরানো হয়েছে তা আবিষ্কার করতে আপনার ক্যাশে করা স্থানাঙ্কগুলির সাথে এই স্থানাঙ্কগুলি তুলনা করুন৷

শুধুমাত্র ACTION_POINTER_UP এবং ACTION_POINTER_DOWN ইভেন্টের সাথে getActionIndex() ফাংশন ব্যবহার করুন। ACTION_MOVE ইভেন্টগুলির সাথে এই ফাংশনটি ব্যবহার করবেন না, কারণ এটি সর্বদা 0 প্রদান করে।

MotionEvent অ্যাকশন পুনরুদ্ধার করুন

একটি MotionEvent এর ক্রিয়া পুনরুদ্ধার করতে getActionMasked() পদ্ধতি বা MotionEventCompat.getActionMasked() সামঞ্জস্যপূর্ণ সংস্করণ ব্যবহার করুন। আগের getAction() পদ্ধতির বিপরীতে, getActionMasked() একাধিক পয়েন্টারের সাথে কাজ করার জন্য ডিজাইন করা হয়েছে। এটি পয়েন্টার সূচক ছাড়াই কর্ম ফেরত দেয়। একটি বৈধ পয়েন্টার সূচকের সাথে ক্রিয়াগুলির জন্য, নিম্নলিখিত স্নিপেটে দেখানো হিসাবে কর্মের সাথে যুক্ত পয়েন্টারগুলির সূচী ফেরত দিতে getActionIndex() ব্যবহার করুন:

কোটলিন

val (xPos: Int, yPos: Int) = MotionEventCompat.getActionMasked(event).let { action ->
    Log.d(DEBUG_TAG, "The action is ${actionToString(action)}")
    // Get the index of the pointer associated with the action.
    MotionEventCompat.getActionIndex(event).let { index ->
        // The coordinates of the current screen contact, relative to
        // the responding View or Activity.
        MotionEventCompat.getX(event, index).toInt() to MotionEventCompat.getY(event, index).toInt()
    }
}

if (event.pointerCount > 1) {
    Log.d(DEBUG_TAG, "Multitouch event")

} else {
    // Single touch event.
    Log.d(DEBUG_TAG, "Single touch event")
}

...

// Given an action int, returns a string description.
fun actionToString(action: Int): String {
    return when (action) {
        MotionEvent.ACTION_DOWN -> "Down"
        MotionEvent.ACTION_MOVE -> "Move"
        MotionEvent.ACTION_POINTER_DOWN -> "Pointer Down"
        MotionEvent.ACTION_UP -> "Up"
        MotionEvent.ACTION_POINTER_UP -> "Pointer Up"
        MotionEvent.ACTION_OUTSIDE -> "Outside"
        MotionEvent.ACTION_CANCEL -> "Cancel"
        else -> ""
    }
}

জাভা

int action = MotionEventCompat.getActionMasked(event);
// Get the index of the pointer associated with the action.
int index = MotionEventCompat.getActionIndex(event);
int xPos = -1;
int yPos = -1;

Log.d(DEBUG_TAG,"The action is " + actionToString(action));

if (event.getPointerCount() > 1) {
    Log.d(DEBUG_TAG,"Multitouch event");
    // The coordinates of the current screen contact, relative to
    // the responding View or Activity.
    xPos = (int)MotionEventCompat.getX(event, index);
    yPos = (int)MotionEventCompat.getY(event, index);

} else {
    // Single touch event.
    Log.d(DEBUG_TAG,"Single touch event");
    xPos = (int)MotionEventCompat.getX(event, index);
    yPos = (int)MotionEventCompat.getY(event, index);
}
...

// Given an action int, returns a string description
public static String actionToString(int action) {
    switch (action) {

        case MotionEvent.ACTION_DOWN: return "Down";
	case MotionEvent.ACTION_MOVE: return "Move";
	case MotionEvent.ACTION_POINTER_DOWN: return "Pointer Down";
	case MotionEvent.ACTION_UP: return "Up";
	case MotionEvent.ACTION_POINTER_UP: return "Pointer Up";
	case MotionEvent.ACTION_OUTSIDE: return "Outside";
	case MotionEvent.ACTION_CANCEL: return "Cancel";
    }
    return "";
}
চিত্র 1. মাল্টি-টাচ অঙ্কন নিদর্শন।

অতিরিক্ত সম্পদ

ইনপুট ইভেন্ট সম্পর্কিত আরও তথ্যের জন্য, নিম্নলিখিত উল্লেখগুলি দেখুন: