স্প্রিং ফিজিক্স ব্যবহার করে মুভমেন্ট অ্যানিমেট করা

'কম্পোজ' ফিচার ব্যবহার করে দেখুন
Jetpack Compose হল Android-এর জন্য সাজেস্ট করা UI টুলকিট। Compose-এ কীভাবে অ্যানিমেশন ব্যবহার করতে হয় তা জানুন।

ফিজিক্স-ভিত্তিক মোশন বলের দ্বারা পরিচালিত হয়। স্প্রিং ফোর্স হল এমন একটি ফোর্স যা ইন্টার‍্যাক্টিভিটি ও মোশনকে গাইড করে। স্প্রিং ফোর্সের নিম্নলিখিত প্রপার্টি আছে: ড্যাম্পিং ও স্টিফনেস। স্প্রিং-ভিত্তিক অ্যানিমেশনে, প্রতিটি ফ্রেমে প্রয়োগ করা স্প্রিং ফোর্সের উপর ভিত্তি করে ভ্যালু ও ভেলোসিটি গণনা করা হয়।

আপনি যদি চান যে আপনার অ্যাপের অ্যানিমেশন শুধুমাত্র একটি দিকে ধীরে ধীরে হোক, তাহলে এর পরিবর্তে ঘর্ষণ-ভিত্তিক ফ্লিং অ্যানিমেশন ব্যবহার করার কথা বিবেচনা করুন।

স্প্রিং অ্যানিমেশনের লাইফসাইকেল

স্প্রিং-ভিত্তিক অ্যানিমেশনে, SpringForce ক্লাস আপনাকে স্প্রিংয়ের স্টিফনেস, এর ড্যাম্পিং রেশিও এবং এর ফাইনাল পজিশন কাস্টমাইজ করতে দেয়। অ্যানিমেশন শুরু হওয়ার সাথে সাথেই, স্প্রিং ফোর্স প্রতিটি ফ্রেমে অ্যানিমেশন ভ্যালু ও ভেলোসিটি আপডেট করে। স্প্রিং ফোর্স সাম্যাবস্থায় না পৌঁছানো পর্যন্ত অ্যানিমেশন চলতে থাকে।

যেমন, আপনি যদি স্ক্রিনের চারপাশে কোনও অ্যাপ আইকন টেনে আনেন এবং পরে আইকন থেকে আঙুল তুলে সেটি ছেড়ে দেন, তাহলে আইকনটি একটি অদৃশ্য কিন্তু পরিচিত শক্তির মাধ্যমে তার আসল জায়গায় ফিরে আসে।

ছবি ১-এ একই ধরনের স্প্রিং এফেক্ট দেখানো হয়েছে। বৃত্তের মাঝখানে থাকা প্লাস চিহ্ন (+) টাচ জেসচারের মাধ্যমে প্রয়োগ করা বলকে নির্দেশ করে।

বসন্তের রিলিজ
ছবি ১. স্প্রিং রিলিজ এফেক্ট

স্প্রিং অ্যানিমেশন তৈরি করা

আপনার অ্যাপ্লিকেশনের জন্য স্প্রিং অ্যানিমেশন তৈরি করার সাধারণ ধাপগুলি নিম্নলিখিত:

নিম্নলিখিত বিভাগে স্প্রিং অ্যানিমেশন তৈরি করার সাধারণ ধাপগুলি বিস্তারিতভাবে আলোচনা করা হয়েছে।

সাপোর্ট লাইব্রেরি যোগ করুন

ফিজিক্স-ভিত্তিক সাপোর্ট লাইব্রেরি ব্যবহার করতে, আপনাকে নিজের প্রোজেক্টে সাপোর্ট লাইব্রেরি যোগ করতে হবে যেমন:

  1. আপনার অ্যাপ মডিউলের জন্য build.gradle ফাইল খুলুন।
  2. dependencies বিভাগে সাপোর্ট লাইব্রেরি যোগ করুন।

    গ্ৰুভি

            dependencies {
                def dynamicanimation_version = '1.0.0'
                implementation "androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version"
            }
            

    Kotlin

            dependencies {
                val dynamicanimation_version = "1.0.0"
                implementation("androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version")
            }
            

    এই লাইব্রেরির বর্তমান ভার্সন দেখতে, ভার্সন পৃষ্ঠায় Dynamicanimation সংক্রান্ত তথ্য দেখুন।

স্প্রিং অ্যানিমেশন তৈরি করা

SpringAnimation ক্লাস আপনাকে কোনও অবজেক্টের জন্য স্প্রিং অ্যানিমেশন তৈরি করতে দেয়। স্প্রিং অ্যানিমেশন তৈরি করতে, আপনাকে এগুলি করতে হবে: SpringAnimation ক্লাসের একটি ইনস্ট্যান্স তৈরি করতে হবে এবং একটি অবজেক্ট, অবজেক্টের এমন একটি প্রপার্টি দিতে হবে যা আপনি অ্যানিমেট করতে চান এবং একটি ঐচ্ছিক ফাইনাল স্প্রিং পজিশন দিতে হবে যেখানে আপনি অ্যানিমেশনটি শেষ করতে চান।

মনে রাখবেন: স্প্রিং অ্যানিমেশন তৈরি করার সময়, স্প্রিংয়ের ফাইনাল পজিশন ঐচ্ছিক। তবে, অ্যানিমেশন শুরু করার আগে এটিকে অবশ্যই সংজ্ঞায়িত করতে হবে।

Kotlin

val springAnim = findViewById<View>(R.id.imageView).let { img ->
    // Setting up a spring animation to animate the view’s translationY property with the final
    // spring position at 0.
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0f)
}

জাভা

final View img = findViewById(R.id.imageView);
// Setting up a spring animation to animate the view’s translationY property with the final
// spring position at 0.
final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);

স্প্রিং-ভিত্তিক অ্যানিমেশন, ভিউ অবজেক্টে থাকা প্রকৃত প্রপার্টি পরিবর্তন করে স্ক্রিনে ভিউ অ্যানিমেট করতে পারে। সিস্টেমে নিম্নলিখিত ভিউ উপলভ্য:

  • ALPHA: ভিউতে আলফা ট্রান্সপারেন্সি দেখায়। ডিফল্ট হিসেবে ভ্যালু ১ (অস্বচ্ছ) থাকে, যার মধ্যে ০ ভ্যালু সম্পূর্ণ স্বচ্ছতা (দৃশ্যমান নয়) বোঝায়।
  • TRANSLATION_X, TRANSLATION_Y এবং TRANSLATION_Z: এই প্রপার্টিগুলি কন্ট্রোল করে যে ভিউটি কোথায় অবস্থিত, এটি তার বামদিকের কোঅর্ডিনেট, উপরের কোঅর্ডিনেট এবং উচ্চতা থেকে ডেল্টা হিসেবে দেখানো হয়, যা এর লেআউট কন্টেনার দ্বারা সেট করা হয়।
    • TRANSLATION_X বাঁদিকের কোঅর্ডিনেট বর্ণনা করে।
    • TRANSLATION_Y সবচেয়ে উপরের কোঅর্ডিনেট বর্ণনা করে।
    • TRANSLATION_Z এর উচ্চতার সাপেক্ষে ভিউয়ের গভীরতা বর্ণনা করে।
  • ROTATION, ROTATION_X এবং ROTATION_Y: এই প্রপার্টিগুলি 2D (rotation প্রপার্টি) এবং পিভট পয়েন্টের চারপাশে 3D-তে রোটেশন কন্ট্রোল করে।
  • SCROLL_X এবং SCROLL_Y: এই প্রপার্টিগুলি সোর্সের বাঁদিক ও উপরের দিকের প্রান্তের স্ক্রল অফসেট পিক্সেলে দেখায়। এছাড়াও, পৃষ্ঠাটি কতটা স্ক্রল করা হয়েছে সেই অনুযায়ী এটি পজিশন নির্দেশ করে।
  • SCALE_X এবং SCALE_Y: এইসব প্রপার্টি, কোনও ভিউয়ের পিভট পয়েন্টের চারপাশে সেটির 2D স্কেলিং নিয়ন্ত্রণ করে।
  • X, Y এবং Z: এগুলি হল ভিউয়ের কন্টেনারে সেটির চূড়ান্ত লোকেশন বর্ণনা করার জন্য মৌলিক ইউটিলিটি প্রপার্টি।
    • X হল বাঁদিকের ভ্যালু এবং TRANSLATION_X-এর যোগফল।
    • Y হল সর্বোচ্চ ভ্যালু ও TRANSLATION_Y-এর যোগফল।
    • Z হল উচ্চতা সংক্রান্ত ভ্যালু ও TRANSLATION_Z-এর যোগফল।

লিসনার রেজিস্টার করা

DynamicAnimation ক্লাসে দুটি শ্রোতা থাকে: OnAnimationUpdateListener ও OnAnimationEndListener. অ্যানিমেশনের ভ্যালুতে কোনও পরিবর্তন হলে এবং অ্যানিমেশন শেষ হলে, এই লিসনাররা অ্যানিমেশনের আপডেট শোনেন।

OnAnimationUpdateListener

চেন অ্যানিমেশন তৈরি করার জন্য একাধিক ভিউ অ্যানিমেট করতে চাইলে, বর্তমান ভিউয়ের প্রপার্টিতে কোনও পরিবর্তন হলে, প্রতিবার কলব্যাক পাওয়ার জন্য আপনি OnAnimationUpdateListener সেট-আপ করতে পারেন। বর্তমান ভিউয়ের প্রপার্টিতে হওয়া পরিবর্তনের ভিত্তিতে কলব্যাক অন্য ভিউকে তার স্প্রিং পজিশন আপডেট করার বিষয়ে বিজ্ঞপ্তি পাঠায়। লিসনার রেজিস্টার করতে, নিচের ধাপগুলি অনুসরণ করুন:

  1. addUpdateListener() মেথড কল করুন এবং অ্যানিমেশনের সাথে লিসনার অ্যাটাচ করুন।

    মনে রাখবেন: অ্যানিমেশন শুরু হওয়ার আগে আপনাকে আপডেট লিসনার রেজিস্টার করতে হবে। তবে, অ্যানিমেশন ভ্যালুতে পরিবর্তনের জন্য প্রতি ফ্রেম আপডেট প্রয়োজন হলেই আপডেট লিসনারকে রেজিস্টার করা উচিত। আপডেট লিসনার, অ্যানিমেশনকে সম্ভাব্যভাবে আলাদা থ্রেডে চলতে বাধা দেয়।

  2. বর্তমান অবজেক্টে হওয়া পরিবর্তন সম্পর্কে কলারকে বিজ্ঞপ্তি পাঠাতে onAnimationUpdate() মেথড ওভাররাইড করুন। নিচে দেওয়া নমুনা কোড থেকে OnAnimationUpdateListener-এর সামগ্রিক ব্যবহার সম্পর্কে ধারণা পাওয়া যায়।

Kotlin

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
val (anim1X, anim1Y) = findViewById<View>(R.id.view1).let { view1 ->
    SpringAnimation(view1, DynamicAnimation.TRANSLATION_X) to
            SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y)
}
val (anim2X, anim2Y) = findViewById<View>(R.id.view2).let { view2 ->
    SpringAnimation(view2, DynamicAnimation.TRANSLATION_X) to
            SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y)
}

// Registering the update listener
anim1X.addUpdateListener { _, value, _ ->
    // Overriding the method to notify view2 about the change in the view1’s property.
    anim2X.animateToFinalPosition(value)
}

anim1Y.addUpdateListener { _, value, _ -> anim2Y.animateToFinalPosition(value) }

জাভা

// Creating two views to demonstrate the registration of the update listener.
final View view1 = findViewById(R.id.view1);
final View view2 = findViewById(R.id.view2);

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
final SpringAnimation anim1X = new SpringAnimation(view1,
        DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim1Y = new SpringAnimation(view1,
    DynamicAnimation.TRANSLATION_Y);
final SpringAnimation anim2X = new SpringAnimation(view2,
        DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim2Y = new SpringAnimation(view2,
        DynamicAnimation.TRANSLATION_Y);

// Registering the update listener
anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

// Overriding the method to notify view2 about the change in the view1’s property.
    @Override
    public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                  float velocity) {
        anim2X.animateToFinalPosition(value);
    }
});

anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

  @Override
    public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                  float velocity) {
        anim2Y.animateToFinalPosition(value);
    }
});

OnAnimationEndListener

OnAnimationEndListener অ্যানিমেশন শেষ হওয়ার বিজ্ঞপ্তি দেয়। অ্যানিমেশন ইক্যুইলিব্রিয়ামে পৌঁছালে বা বাতিল করা হলে, কলব্যাক পাওয়ার জন্য আপনি লিসনার সেট-আপ করতে পারবেন। লিসনারকে রেজিস্টার করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. addEndListener() মেথড কল করুন এবং অ্যানিমেশনের সাথে লিসনার অ্যাটাচ করুন।
  2. কোনও অ্যানিমেশন সাম্যাবস্থায় পৌঁছালে বা বাতিল করা হলে বিজ্ঞপ্তি পেতে onAnimationEnd() মেথড ওভাররাইড করুন।

লিসনারদের সরিয়ে দেওয়া

অ্যানিমেশন আপডেট কলব্যাক ও অ্যানিমেশন শেষ হওয়ার কলব্যাক পাওয়া বন্ধ করতে, যথাক্রমে removeUpdateListener() ও removeEndListener() মেথড কল করুন।

অ্যানিমেশনের শুরুর ভ্যালু সেট করা

অ্যানিমেশনের শুরুর ভ্যালু সেট করতে, setStartValue() মেথড কল করুন এবং অ্যানিমেশনের শুরুর ভ্যালু পাস করুন। আপনি শুরুর ভ্যালু সেট না করলে, অ্যানিমেশন অবজেক্টের প্রপার্টির বর্তমান ভ্যালুকে শুরুর ভ্যালু হিসেবে ব্যবহার করে।

অ্যানিমেশন ভ্যালু রেঞ্জ সেট করা

আপনি যখন কোনও নির্দিষ্ট রেঞ্জে প্রপার্টির ভ্যালু সীমাবদ্ধ করতে চান, তখন আপনি সর্বনিম্ন ও সর্বোচ্চ অ্যানিমেশন ভ্যালু সেট করতে পারেন। এছাড়াও, এটি সেইসব প্রপার্টির ক্ষেত্রে রেঞ্জ কন্ট্রোল করতে সাহায্য করে যেগুলির ইন্ট্রিনসিক রেঞ্জ আছে, যেমন আলফা (০ থেকে ১)।

  • ন্যূনতম ভ্যালু সেট করতে, setMinValue() মেথড কল করুন এবং প্রপার্টির ন্যূনতম ভ্যালু পাস করুন।
  • সর্বাধিক ভ্যালু সেট করতে, setMaxValue() মেথড কল করুন এবং প্রপার্টির সর্বাধিক ভ্যালু পাস করুন।

দুটি পদ্ধতিতেই সেই অ্যানিমেশনটি রিটার্ন করা হয় যার ভ্যালু সেট করা হচ্ছে।

মনে রাখবেন: আপনি যদি শুরুর ভ্যালু সেট করে থাকেন এবং অ্যানিমেশন ভ্যালু রেঞ্জ নির্ধারণ করে থাকেন, তাহলে দেখে নিন যে শুরুর ভ্যালু সর্বনিম্ন ও সর্বাধিক ভ্যালু রেঞ্জের মধ্যে আছে কিনা।

প্রাথমিক বেগ সেট করা

অ্যানিমেশনের শুরুতে অ্যানিমেশন প্রপার্টি যে স্পিডে পরিবর্তিত হয় তা স্টার্ট ভেলোসিটি নির্ধারণ করে। ডিফল্ট স্টার্ট ভেলোসিটি শূন্য পিক্সেল প্রতি সেকেন্ড হিসেবে সেট করা থাকে। আপনি টাচ জেসচারের ভেলোসিটি দিয়ে অথবা স্টার্ট ভেলোসিটি হিসেবে একটি নির্দিষ্ট ভ্যালু ব্যবহার করে ভেলোসিটি সেট করতে পারবেন। আপনি যদি একটি নির্দিষ্ট ভ্যালু প্রদান করার বিকল্প বেছে নেন, তাহলে আমরা সাজেস্ট করি যে ভ্যালুকে প্রথমে dp প্রতি সেকেন্ডে সংজ্ঞায়িত করুন এবং তারপরে এটিকে পিক্সেল প্রতি সেকেন্ডে কনভার্ট করুন। সেকেন্ড পিছু dp-তে ভ্যালু নির্ধারণ করা ঘনত্ব ও ফর্ম ফ্যাক্টর থেকে ভেলোসিটিকে স্বাধীন হতে দেয়। ভ্যালুকে পিক্সেল পার সেকেন্ডে কনভার্ট করা সম্পর্কে আরও তথ্য পেতে, ডিপি পার সেকেন্ডকে পিক্সেল পার সেকেন্ডে কনভার্ট করা বিভাগ দেখুন।

ভেলোসিটি সেট করতে, setStartVelocity() মেথড কল করুন এবং পিক্সেল পার সেকেন্ডে ভেলোসিটি পাস করুন। যে স্প্রিং ফোর্স অবজেক্টে ভেলোসিটি সেট করা হয়, এই পদ্ধতি সেটি রিটার্ন করে।

মনে রাখবেন: টাচ জেসচারের ভেলোসিটি রিট্রিভ ও কম্পিউট করতে GestureDetector.OnGestureListener বা VelocityTracker ক্লাস পদ্ধতি ব্যবহার করুন।

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        …
        // Compute velocity in the unit pixel/second
        vt.computeCurrentVelocity(1000)
        val velocity = vt.yVelocity
        setStartVelocity(velocity)
    }
}

জাভা

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
// Compute velocity in the unit pixel/second
vt.computeCurrentVelocity(1000);
float velocity = vt.getYVelocity();
anim.setStartVelocity(velocity);

ডট পার সেকেন্ডকে পিক্সেল পার সেকেন্ডে কনভার্ট করা

স্প্রিংয়ের ভেলোসিটি অবশ্যই পিক্সেল প্রতি সেকেন্ডে হতে হবে। আপনি যদি ভেলোসিটির শুরু হিসেবে একটি নির্দিষ্ট ভ্যালু প্রদান করার বিকল্প বেছে নেন, তাহলে dp প্রতি সেকেন্ডে ভ্যালু প্রদান করুন এবং তারপরে এটিকে পিক্সেল প্রতি সেকেন্ডে কনভার্ট করুন। কনভার্সনের জন্য, TypedValue ক্লাস থেকে applyDimension() পদ্ধতি ব্যবহার করুন। নিচের স্যাম্পেল কোড দেখুন:

Kotlin

val pixelPerSecond: Float =
    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, resources.displayMetrics)

জাভা

float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

বসন্তের প্রপার্টি সেট করা

SpringForce ক্লাসটি ড্যাম্পিং অনুপাত ও স্টিফনেসের মতো প্রতিটি স্প্রিং প্রপার্টির জন্য গেটার ও সেটার মেথডকে সংজ্ঞায়িত করে। স্প্রিং প্রপার্টি সেট করতে, হয় স্প্রিং ফোর্স অবজেক্ট রিট্রিভ করতে হবে অথবা এমন কাস্টম স্প্রিং ফোর্স তৈরি করতে হবে যার প্রপার্টি আপনি সেট করতে পারবেন। কাস্টম স্প্রিং ফোর্স তৈরি করা সম্পর্কে আরও জানতে, কাস্টম স্প্রিং ফোর্স তৈরি করা বিভাগ দেখুন।

পরামর্শ: সেটার পদ্ধতি ব্যবহার করার সময়, আপনি একটি পদ্ধতি চেইন তৈরি করতে পারবেন কারণ সব সেটার পদ্ধতিই স্প্রিং ফোর্স অবজেক্ট রিটার্ন করে।

ড্যাম্পিং রেশিও

ড্যাম্পিং রেশিও স্প্রিংয়ের দোলনের ধীরে ধীরে কমে যাওয়াকে বর্ণনা করে। ড্যাম্পিং রেশিও ব্যবহার করে, আপনি নির্ধারণ করতে পারবেন যে কীভাবে একটি বাউন্স থেকে পরের বাউন্সে অসিলেশন দ্রুত কমে যায়। স্প্রিং ড্যাম্প করার চারটি আলাদা আলাদা উপায় আছে: ১. স্প্রিংয়ের সাথে একটি ড্যাম্পার যোগ করুন।

  • ড্যাম্পিং রেশিও একের বেশি হলে ওভারড্যাম্পিং হয়। এটি অবজেক্টটিকে ধীরে ধীরে আগের অবস্থায় ফিরিয়ে আনে।
  • ড্যাম্পিং রেশিও এক হলে ক্রিটিক্যাল ড্যাম্পিং হয়। এটি অবজেক্টকে সবচেয়ে কম সময়ের মধ্যে রেস্ট পজিশনে ফিরিয়ে আনে।
  • ড্যাম্পিং রেশিও একের কম হলে আন্ডারড্যাম্পিং হয়। এটি অবজেক্টকে রেস্ট পজিশন অতিক্রম করে একাধিকবার ওভারশুট করতে দেয় এবং তারপরে ধীরে ধীরে রেস্ট পজিশনে পৌঁছায়।
  • ড্যাম্পিং রেশিও শূন্যের সমান হলে আনড্যাম্পড হয়। এটি অবজেক্টকে চিরকাল ধরে দোলানোর অনুমতি দেয়।

স্প্রিংয়ে ড্যাম্পিং রেশিও যোগ করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. ড্যাম্পিং রেশিও যোগ করার জন্য স্প্রিং পেতে getSpring() মেথড কল করুন।
  2. setDampingRatio() মেথড কল করুন এবং স্প্রিংয়ে যে ড্যাম্পিং রেশিও যোগ করতে চান সেটি পাস করুন। যে স্প্রিং ফোর্স অবজেক্টে ড্যাম্পিং রেশিও সেট করা আছে, মেথড সেটি রিটার্ন করে।

    মনে রাখবেন: ড্যাম্পিং রেশিওকে অবশ্যই একটি নেগেটিভ নয় এমন সংখ্যা হতে হবে। আপনি ড্যাম্পিং রেশিও শূন্যে সেট করলে, স্প্রিংটি কখনও রেস্ট পজিশনে পৌঁছাবে না। অন্যভাবে বলতে গেলে, এটি চিরকাল ধরে দোলনাতে থাকে।

সিস্টেমে নিম্নলিখিত ড্যাম্পিং রেশিও কনস্ট্যান্ট উপলভ্য:

ছবি ২: বেশি বাউন্স

ছবি ৩: মাঝারি বাউন্স

ছবি ৪: কম বাউন্স

ছবি ৫: কোনও বাউন্স নেই

ডিফল্ট ড্যাম্পিং রেশিও DAMPING_RATIO_MEDIUM_BOUNCY হিসেবে সেট করা থাকে।

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        …
        // Setting the damping ratio to create a low bouncing effect.
        spring.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
        …
    }
}

জাভা

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
// Setting the damping ratio to create a low bouncing effect.
anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);
…

আড়ষ্টতা

স্টিফনেস স্প্রিং ধ্রুবক নির্ধারণ করে, যা স্প্রিংয়ের ক্ষমতা পরিমাপ করে। স্প্রিংটি যখন রেস্ট পজিশনে থাকে না, তখন স্প্রিংটি যে অবজেক্টের সাথে অ্যাটাচ করা থাকে সেটির উপর আরও বেশি বল প্রয়োগ করে। স্প্রিংয়ে দৃঢ়তা যোগ করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. দৃঢ়তা যোগ করার জন্য স্প্রিং পেতে getSpring() মেথড কল করুন।
  2. setStiffness() মেথড কল করুন এবং স্প্রিংয়ে যে স্টিফনেস ভ্যালু যোগ করতে চান সেটি পাস করুন। পদ্ধতিটি স্প্রিং ফোর্স অবজেক্ট রিটার্ন করে যার উপর স্টিফনেস সেট করা হয়।

    মনে রাখবেন: স্টিফনেস অবশ্যই একটি ধনাত্মক সংখ্যা হতে হবে।

সিস্টেমে নিম্নলিখিত স্টিফনেস ধ্রুবক উপলভ্য:

ছবি ৬: হাই স্টিফনেস

ছবি ৭: মাঝারি স্টিফনেস

ছবি ৮: কম স্টিফনেস

ছবি ৯: খুব কম স্টিফনেস

ডিফল্ট স্টিফনেস STIFFNESS_MEDIUM হিসেবে সেট করা থাকে।

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        …
        // Setting the spring with a low stiffness.
        spring.stiffness = SpringForce.STIFFNESS_LOW
        …
    }
}

জাভা

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
// Setting the spring with a low stiffness.
anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);
…

কাস্টম স্প্রিং ফোর্স তৈরি করা

আপনি ডিফল্ট স্প্রিং ফোর্স ব্যবহার করার বিকল্প হিসেবে কাস্টম স্প্রিং ফোর্স তৈরি করতে পারেন। কাস্টম স্প্রিং ফোর্স আপনাকে একাধিক স্প্রিং অ্যানিমেশন জুড়ে একই স্প্রিং ফোর্স ইনস্ট্যান্স শেয়ার করতে দেয়। স্প্রিং ফোর্স তৈরি করার পরে, আপনি ড্যাম্পিং রেশিও ও স্টিফনেসের মতো প্রপার্টি সেট করতে পারবেন।

  1. SpringForce অবজেক্ট তৈরি করুন।

    SpringForce force = new SpringForce();

  2. সম্পর্কিত পদ্ধতি কল করে প্রপার্টি অ্যাসাইন করুন। এছাড়াও, আপনি একটি মেথড চেইন তৈরি করতে পারেন।

    force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

  3. অ্যানিমেশনে স্প্রিং সেট করতে setSpring() মেথড কল করুন।

    setSpring(force);

অ্যানিমেশন শুরু করুন

আপনি দুটি উপায়ে স্প্রিং অ্যানিমেশন শুরু করতে পারেন: start() কল করে অথবা animateToFinalPosition() মেথড কল করে। দুটি পদ্ধতিকেই মূল থ্রেডে কল করতে হবে।

animateToFinalPosition() পদ্ধতিটি দুটি কাজ করে:

  • স্প্রিংয়ের চূড়ান্ত পজিশন সেট করে।
  • অ্যানিমেশন শুরু না হয়ে থাকলে, এটি শুরু করে।

যেহেতু এই পদ্ধতি স্প্রিংয়ের চূড়ান্ত পজিশন আপডেট করে এবং প্রয়োজন হলে অ্যানিমেশন শুরু করে, তাই অ্যানিমেশনের কোর্স পরিবর্তন করতে আপনি যেকোনও সময় এই পদ্ধতি কল করতে পারেন। যেমন, চেইন করা স্প্রিং অ্যানিমেশনে, একটি ভিউয়ের অ্যানিমেশন অন্য ভিউয়ের উপর নির্ভর করে। এই ধরনের অ্যানিমেশনের জন্য, এটি animateToFinalPosition() পদ্ধতি ব্যবহার করা আরও সুবিধাজনক। চেনড স্প্রিং অ্যানিমেশনে এই পদ্ধতি ব্যবহার করলে, আপনি যে অ্যানিমেশনটি আপডেট করতে চান সেটি বর্তমানে চলছে কিনা তা নিয়ে আপনাকে চিন্তা করতে হবে না।

ছবি ১০-এ একটি চেইনড স্প্রিং অ্যানিমেশন দেখানো হয়েছে, যেখানে একটি ভিউয়ের অ্যানিমেশন অন্য ভিউয়ের উপর নির্ভর করে।

চেন দিয়ে বাঁধা স্প্রিংয়ের ডেমো
ছবি ১০. চেন স্প্রিং ডেমো

animateToFinalPosition() পদ্ধতি ব্যবহার করতে, animateToFinalPosition() পদ্ধতি কল করুন এবং স্প্রিংয়ের বাকি পজিশন পাস করুন। এছাড়াও, আপনি setFinalPosition() মেথড কল করে স্প্রিংয়ের রেস্ট পজিশন সেট করতে পারবেন।

start() মেথডটি প্রপার্টির ভ্যালুকে শুরুর ভ্যালুতে সঙ্গে সঙ্গে সেট করে না। ড্র পাস হওয়ার আগে প্রতিটি অ্যানিমেশন পালসে প্রপার্টির ভ্যালু পরিবর্তিত হয়। ফলে, পরবর্তী ফ্রেমে পরিবর্তনগুলি দেখা যায়, যেন মানগুলি সঙ্গে সঙ্গে সেট করা হয়েছে।

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        …
        // Starting the animation
        start()
        …
    }
}

জাভা

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
// Starting the animation
anim.start();
…

অ্যানিমেশন বাতিল করা

আপনি অ্যানিমেশন বাতিল করতে পারেন অথবা শেষ পর্যন্ত এড়িয়ে যেতে পারেন। আদর্শ পরিস্থিতি হল যখন কোনও ব্যবহারকারীর ইন্টার‍্যাকশনের কারণে অ্যানিমেশন অবিলম্বে বন্ধ করতে হয়। এটি সাধারণত তখনই হয় যখন কোনও ব্যবহারকারী হঠাৎ করে অ্যাপ থেকে বেরিয়ে যান বা ভিউ অদৃশ্য হয়ে যায়।

অ্যানিমেশন বন্ধ করার জন্য আপনি দুটি পদ্ধতি ব্যবহার করতে পারেন। cancel() মেথড অ্যানিমেশনটি যেখানে আছে সেই ভ্যালুতে সেটি বন্ধ করে দেয়। skipToEnd() মেথড অ্যানিমেশনটি ফাইনাল ভ্যালুতে নিয়ে গিয়ে বন্ধ করে দেয়।

অ্যানিমেশন বন্ধ করার আগে, স্প্রিংয়ের অবস্থা চেক করে নেওয়া গুরুত্বপূর্ণ। স্টেট ড্যাম্প না করা হলে, অ্যানিমেশন কখনই রেস্ট পজিশনে পৌঁছাতে পারবে না। স্প্রিংয়ের অবস্থা চেক করতে, canSkipToEnd() মেথড কল করুন। যদি স্প্রিং ড্যাম্প করা থাকে, তাহলে মেথড true রিটার্ন করে, অন্যথায় false রিটার্ন করে।

স্প্রিংয়ের অবস্থা জানার পরে, আপনি skipToEnd() পদ্ধতি বা cancel() পদ্ধতি ব্যবহার করে অ্যানিমেশন বন্ধ করতে পারবেন। The cancel() মেথড অবশ্যই শুধুমাত্র মূল থ্রেডে কল করতে হবে।

মনে রাখবেন: সাধারণত, skipToEnd() পদ্ধতিতে ভিজ্যুয়াল জাম্প হয়।