প্রপার্টি অ্যানিমেশন ওভারভিউ

Compose-এর মাধ্যমে চেষ্টা করুন
Jetpack Compose হল Android-এর জন্য সাজেস্ট করা UI টুলকিট। Compose-এ কীভাবে অ্যানিমেশন ব্যবহার করতে হয় তা জানুন।

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

প্রপার্টি অ্যানিমেশন সিস্টেম আপনাকে অ্যানিমেশনের নিম্নলিখিত বৈশিষ্ট্যগুলি সংজ্ঞায়িত করতে দেয়:

  • সময়সীমা: আপনি অ্যানিমেশনের সময়সীমা নির্দিষ্ট করতে পারবেন। ডিফল্ট দৈর্ঘ্য হল ৩০০ মিলি সেকেন্ড।
  • টাইম ইন্টারপোলেশন: অ্যানিমেশনের বর্তমান অতিবাহিত সময়ের ফাংশন হিসেবে প্রপার্টির মান কীভাবে গণনা করা হয় তা আপনি নির্দিষ্ট করতে পারেন।
  • কতবার রিপিট হবে এবং আচরণ: কোনও অ্যানিমেশন তার সময়সীমার শেষে পৌঁছালে সেটি রিপিট হবে কিনা এবং কতবার রিপিট হবে তা আপনি নির্দিষ্ট করতে পারবেন। এছাড়াও, আপনি অ্যানিমেশনটি রিভার্সে প্লেব্যাক করতে চান কিনা তা নির্দিষ্ট করতে পারেন। এটি রিভার্স হিসেবে সেট করলে, যতবার রিপিট করার কথা ততবার না হওয়া পর্যন্ত অ্যানিমেশনটি প্রথমে সামনের দিকে এবং তারপরে পিছনের দিকে বারবার চলতে থাকে।
  • এনিমেটর সেট: আপনি এনিমেশনগুলিকে লজিক্যাল সেটে গ্রুপ করতে পারেন যা একসাথে বা ক্রমানুসারে বা নির্দিষ্ট বিলম্বের পরে চলে।
  • ফ্রেম রিফ্রেশ করার বিলম্ব: আপনার অ্যানিমেশনের ফ্রেম কত ঘন ঘন রিফ্রেশ করতে হবে তা আপনি নির্দিষ্ট করতে পারেন। ডিফল্ট হিসেবে প্রতি ১০ মিলিসেকেন্ডে রিফ্রেশ করার জন্য সেট করা থাকে, তবে আপনার অ্যাপ্লিকেশন কত দ্রুত ফ্রেম রিফ্রেশ করতে পারে তা শেষ পর্যন্ত নির্ভর করে সিস্টেমটি সামগ্রিকভাবে কতটা ব্যস্ত এবং সিস্টেমটি কত দ্রুত অন্তর্নিহিত টাইমারকে পরিষেবা দিতে পারে তার উপর।

প্রপার্টি অ্যানিমেশনের সম্পূর্ণ উদাহরণ দেখতে, GitHub-এ CustomTransition স্যাম্পেলে ChangeColor ক্লাস দেখুন।

প্রপার্টি অ্যানিমেশন কীভাবে কাজ করে

প্রথমে, একটি সহজ উদাহরণের মাধ্যমে অ্যানিমেশন কীভাবে কাজ করে তা দেখে নেওয়া যাক। ছবি ১-এ একটি কাল্পনিক অবজেক্ট দেখানো হয়েছে যা x প্রপার্টির মাধ্যমে অ্যানিমেট করা হয়েছে, এটি স্ক্রিনে অবজেক্টের অনুভূমিক লোকেশন দেখায়। অ্যানিমেশনের সময়সীমা ৪০ মিলি সেকেন্ড এবং ভ্রমণের দূরত্ব ৪০ পিক্সেল হিসেবে সেট করা হয়েছে। প্রতি ১০ মিলি সেকেন্ডে, যা ডিফল্ট ফ্রেম রিফ্রেশ রেট, অবজেক্টটি অনুভূমিকভাবে ১০ পিক্সেল সরে যায়। ৪০ মিলিসেকেন্ডের শেষে, অ্যানিমেশন থেমে যায় এবং অবজেক্টটি অনুভূমিক অবস্থান ৪০-এ শেষ হয়। এটি লিনিয়ার ইন্টারপোলেশন সহ অ্যানিমেশনের একটি উদাহরণ, যার অর্থ হল অবজেক্টটি একটি নির্দিষ্ট স্পিডে চলে।

ছবি ১. লিনিয়ার অ্যানিমেশনের উদাহরণ

এছাড়াও, আপনি নন-লিনিয়ার ইন্টারপোলেশন সহ অ্যানিমেশন নির্দিষ্ট করতে পারবেন। চিত্র ২-এ একটি কাল্পনিক অবজেক্ট দেখানো হয়েছে যা অ্যানিমেশনের শুরুতে গতি বাড়ায় এবং অ্যানিমেশনের শেষে গতি কমায়। অবজেক্টটি এখনও ৪০ মিলি সেকেন্ডে ৪০ পিক্সেল সরে যায়, তবে নন-লিনিয়ারভাবে। শুরুতে, এই অ্যানিমেশনটি অর্ধেক পথ পর্যন্ত গতি বাড়ায় এবং তারপরে অর্ধেক পথ থেকে অ্যানিমেশনের শেষ পর্যন্ত গতি কমায়। ছবি ২-এ যেমন দেখানো হয়েছে, অ্যানিমেশনের শুরু ও শেষে অতিক্রান্ত দূরত্ব মাঝের দূরত্বের চেয়ে কম।

ছবি ২. নন-লিনিয়ার অ্যানিমেশনের উদাহরণ

প্রপার্টি অ্যানিমেশন সিস্টেমের গুরুত্বপূর্ণ উপাদানগুলি কীভাবে উপরে দেখানো অ্যানিমেশনের মতো অ্যানিমেশন গণনা করবে তা বিস্তারিতভাবে দেখে নেওয়া যাক। ছবি ৩-এ দেখানো হয়েছে কীভাবে প্রধান ক্লাসগুলি একে অপরের সাথে কাজ করে।

ছবি ৩. অ্যানিমেশন কীভাবে গণনা করা হয়

ValueAnimator অবজেক্ট আপনার অ্যানিমেশনের টাইমিং ট্র্যাক করে, যেমন অ্যানিমেশন কতক্ষণ ধরে চলছে এবং এটি যে প্রপার্টি অ্যানিমেট করছে তার বর্তমান ভ্যালু।

ValueAnimator-এ TimeInterpolator এনক্যাপসুলেট করা থাকে, যা অ্যানিমেশন ইন্টারপোলেশন নির্ধারণ করে এবং TypeEvaluator, যা অ্যানিমেট করা প্রপার্টির ভ্যালু কীভাবে গণনা করা হবে তা নির্ধারণ করে। যেমন, ছবি ২-এ, ব্যবহৃত TimeInterpolator হবে AccelerateDecelerateInterpolator এবং TypeEvaluator হবে IntEvaluator।

অ্যানিমেশন শুরু করতে, একটি ValueAnimator তৈরি করুন এবং আপনি যে প্রপার্টি অ্যানিমেট করতে চান তার শুরু ও শেষের ভ্যালু দিন, এর সাথে অ্যানিমেশনের সময়সীমাও দিন। start()-কে কল করলে অ্যানিমেশন শুরু হয়। পুরো অ্যানিমেশন চলাকালীন, অ্যানিমেশনের সময়সীমা এবং কতটা সময় অতিবাহিত হয়েছে তার উপর ভিত্তি করে ValueAnimator, ০ এবং ১-এর মধ্যে অতিবাহিত ভগ্নাংশ গণনা করে। অতিক্রান্ত ভগ্নাংশ অ্যানিমেশন সম্পূর্ণ হওয়ার সময় শতাংশে দেখায়, ০ মানে ০% এবং ১ মানে ১০০%। যেমন, চিত্র ১-এ, t = ১০ মিলি সেকেন্ডে অতিবাহিত ভগ্নাংশ .২৫ হবে কারণ মোট সময়সীমা t = ৪০ মিলি সেকেন্ড।

ValueAnimator অতিবাহিত ভগ্নাংশ গণনা করা শেষ করলে, এটি বর্তমানে সেট করা TimeInterpolator-কে কল করে, যাতে একটি ইন্টারপোলেটেড ভগ্নাংশ গণনা করা যায়। ইন্টারপোলেট করা ভগ্নাংশ, অতিবাহিত ভগ্নাংশকে একটি নতুন ভগ্নাংশে ম্যাপ করে যা সেট করা সময় ইন্টারপোলেশনকে বিবেচনা করে। যেমন, চিত্র ২-এ, অ্যানিমেশন ধীরে ধীরে ত্বরান্বিত হওয়ার কারণে, ইন্টারপোলেট করা ভগ্নাংশ, প্রায় .১৫, t = ১০ ms-এ অতিবাহিত ভগ্নাংশ, .২৫-এর চেয়ে কম। চিত্র ১-এ, ইন্টারপোলেট করা ভগ্নাংশ সর্বদা অতিবাহিত ভগ্নাংশের মতোই হয়।

ইন্টারপোলেট করা ভগ্নাংশ গণনা করা হলে, ValueAnimator উপযুক্ত TypeEvaluator-কে কল করে, ইন্টারপোলেট করা ভগ্নাংশ, শুরুর মান এবং অ্যানিমেশনের শেষ মানের উপর ভিত্তি করে আপনি যে প্রপার্টি অ্যানিমেট করছেন তার মান গণনা করার জন্য। যেমন, ২ নম্বর ছবিতে, t = ১০ মিলি সেকেন্ডে ইন্টারপোলেট করা ভগ্নাংশ ছিল .১৫, তাই সেই সময়ে প্রপার্টির ভ্যালু হবে .১৫ × (৪০ - ০) বা ৬।

প্রপার্টি অ্যানিমেশন কীভাবে ভিউ অ্যানিমেশন থেকে আলাদা

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

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

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

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

API ওভারভিউ

আপনি android.animation-এ বেশিরভাগ প্রপার্টি অ্যানিমেশন সিস্টেমের API খুঁজে পাবেন। ভিউ অ্যানিমেশন সিস্টেম আগে থেকেই android.view.animation-এ অনেক ইন্টারপোলেটর সংজ্ঞায়িত করে, তাই আপনি প্রপার্টি অ্যানিমেশন সিস্টেমেও সেইসব ইন্টারপোলেটর ব্যবহার করতে পারবেন। নিম্নলিখিত সারণীতে প্রপার্টি অ্যানিমেশন সিস্টেমের প্রধান কম্পোনেন্টগুলি বর্ণনা করা হয়েছে।

Animator ক্লাস অ্যানিমেশন তৈরি করার জন্য প্রাথমিক স্ট্রাকচার প্রদান করে। আপনি সাধারণত এই ক্লাস সরাসরি ব্যবহার করেন না কারণ এটি শুধুমাত্র ন্যূনতম ফাংশনালিটি প্রদান করে যা অ্যানিমেটিং ভ্যালুকে সম্পূর্ণভাবে সাপোর্ট করার জন্য অবশ্যই বাড়াতে হবে। নিম্নলিখিত সাবক্লাস Animator-কে এক্সটেন্ড করে:

টেবিল ১. অ্যানিমেটর

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

মূল্যায়নকারীরা প্রপার্টি অ্যানিমেশন সিস্টেমকে বলে দেয় যে কীভাবে প্রদত্ত প্রপার্টির জন্য মান গণনা করতে হবে। তারা Animator ক্লাস থেকে পাওয়া টাইমিং ডেটা, অ্যানিমেশনের শুরু ও শেষের ভ্যালু নেয় এবং এই ডেটার ভিত্তিতে প্রপার্টির অ্যানিমেটেড ভ্যালু গণনা করে। প্রপার্টি অ্যানিমেশন সিস্টেম নিম্নলিখিত মূল্যায়নকারী প্রদান করে:

টেবিল ২. মূল্যায়নকারী

ক্লাস/ইন্টারফেস বর্ণনা
IntEvaluator int প্রপার্টির জন্য ভ্যালু গণনা করার ডিফল্ট মূল্যায়নকারী।
FloatEvaluator float প্রপার্টির জন্য ভ্যালু গণনা করার ডিফল্ট মূল্যায়নকারী।
ArgbEvaluator হেক্সাডেসিমেল মান হিসেবে দেখানো রঙের প্রপার্টির মান গণনা করার জন্য ডিফল্ট মূল্যায়নকারী।
TypeEvaluator একটি ইন্টারফেস যা আপনাকে নিজের মূল্যায়নকারী তৈরি করতে দেয়। আপনি যদি এমন কোনও অবজেক্ট প্রপার্টি অ্যানিমেট করেন যা int, float বা রঙ নয়, তাহলে অবজেক্ট প্রপার্টির অ্যানিমেটেড ভ্যালু কীভাবে গণনা করা হবে তা নির্দিষ্ট করতে আপনাকে অবশ্যই TypeEvaluator ইন্টারফেস প্রয়োগ করতে হবে। আপনি যদি ডিফল্ট অ্যাকশনের থেকে আলাদাভাবে সেই ধরনের প্রসেস করতে চান, তাহলে আপনি int, float এবং রঙের মানের জন্য একটি কাস্টম TypeEvaluator নির্দিষ্ট করতে পারেন। কীভাবে কাস্টম ইভ্যালুয়েটর লিখতে হয় সেই সম্পর্কে আরও জানতে TypeEvaluator ব্যবহার করা সংক্রান্ত বিভাগটি দেখুন।

টাইম ইন্টারপোলেটর নির্ধারণ করে যে অ্যানিমেশনের নির্দিষ্ট মান কীভাবে সময়ের ফাংশন হিসেবে গণনা করা হয়। যেমন, আপনি পুরো অ্যানিমেশন জুড়ে লিনিয়ারভাবে অ্যানিমেশন হওয়ার জন্য নির্দিষ্ট করতে পারেন, যার অর্থ হল অ্যানিমেশনটি পুরো সময় জুড়ে সমানভাবে চলে, অথবা আপনি নন-লিনিয়ার সময় ব্যবহার করার জন্য অ্যানিমেশন নির্দিষ্ট করতে পারেন, যেমন, অ্যানিমেশনের শুরুতে গতি বাড়ানো এবং শেষে গতি কমানো। সারণী ৩-এ android.view.animation-এ থাকা ইন্টারপোলেটর সম্পর্কে বর্ণনা করা হয়েছে। প্রদান করা ইন্টারপোলেটরের মধ্যে কোনওটিই আপনার প্রয়োজন পূরণ না করলে, TimeInterpolator ইন্টারফেস প্রয়োগ করে আপনার নিজস্ব ইন্টারপোলেটর তৈরি করুন। কীভাবে কাস্টম ইন্টারপোলেটর লিখতে হয় সেই সম্পর্কে আরও জানতে ইন্টারপোলেটর ব্যবহার করা দেখুন।

সারণী ৩. ইন্টারপোলেটর

ক্লাস/ইন্টারফেস বর্ণনা
AccelerateDecelerateInterpolator এমন একটি ইন্টারপোলেটর যার পরিবর্তনের হার ধীরে ধীরে শুরু এবং শেষ হয় তবে মাঝখানে ত্বরান্বিত হয়।
AccelerateInterpolator একটি ইন্টারপোলেটর যার পরিবর্তনের হার ধীরে ধীরে শুরু হয় এবং তারপরে ত্বরান্বিত হয়।
AnticipateInterpolator একটি ইন্টারপোলেটর যার পরিবর্তন পিছনের দিকে শুরু হয় তারপর সামনের দিকে এগিয়ে যায়।
AnticipateOvershootInterpolator এমন একটি ইন্টারপোলেটর যার পরিবর্তন পিছন দিকে শুরু হয়, সামনের দিকে যায় এবং টার্গেট ভ্যালু ছাড়িয়ে যায়, তারপর অবশেষে চূড়ান্ত ভ্যালুতে ফিরে আসে।
BounceInterpolator একটি ইন্টারপোলেটর যার পরিবর্তন শেষে বাউন্স করে।
CycleInterpolator একটি ইন্টারপোলেটর যার অ্যানিমেশন নির্দিষ্ট সংখ্যক চক্রের জন্য পুনরাবৃত্তি হয়।
DecelerateInterpolator একটি ইন্টারপোলেটর যার পরিবর্তনের হার দ্রুত শুরু হয় এবং তারপরে ধীর হয়ে যায়।
LinearInterpolator একটি ইন্টারপোলেটর যার পরিবর্তনের হার ধ্রুবক।
OvershootInterpolator এমন একটি ইন্টারপোলেটর যার পরিবর্তন সামনের দিকে এগিয়ে যায় এবং শেষ ভ্যালুকে ছাড়িয়ে যায়, তারপর ফিরে আসে।
TimeInterpolator একটি ইন্টারফেস যা আপনাকে নিজের ইন্টারপোলেটর প্রয়োগ করতে দেয়।

ValueAnimator ব্যবহার করে অ্যানিমেট করুন

ValueAnimator ক্লাস আপনাকে অ্যানিমেশনের সময়সীমার জন্য কিছু ধরনের ভ্যালু অ্যানিমেট করতে দেয়। এর জন্য আপনাকে int, float বা কালার ভ্যালুর একটি সেট নির্দিষ্ট করতে হয় যার মাধ্যমে অ্যানিমেট করা হবে। আপনি এর ফ্যাক্টরি মেথডের মধ্যে একটিতে কল করে ValueAnimator পান: ofInt(), ofFloat() অথবা ofObject()। যেমন:

Kotlin

ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 1000
    start()
}

জাভা

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();

এই কোডে, start() পদ্ধতি রান করলে, ValueAnimator ১০০০ মিলি সেকেন্ডের জন্য ০ থেকে ১০০-এর মধ্যে অ্যানিমেশনের মান গণনা করা শুরু করে।

এছাড়াও, আপনি নিম্নলিখিত ধাপগুলি অনুসরণ করে অ্যানিমেট করার জন্য একটি কাস্টম ধরন নির্দিষ্ট করতে পারেন:

Kotlin

ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply {
    duration = 1000
    start()
}

জাভা

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

এই কোডে, start() পদ্ধতি রান করলে, ValueAnimator, startPropertyValue ও endPropertyValue-এর মধ্যে, MyTypeEvaluator-এর মাধ্যমে সরবরাহ করা লজিক ব্যবহার করে ১০০০ মিলি সেকেন্ডের জন্য অ্যানিমেশনের মান গণনা করা শুরু করে।

আপনি ValueAnimator অবজেক্টে AnimatorUpdateListener যোগ করে অ্যানিমেশনের ভ্যালু ব্যবহার করতে পারবেন, যেমনটি নিম্নলিখিত কোডে দেখানো হয়েছে:

Kotlin

ValueAnimator.ofObject(...).apply {
    ...
    addUpdateListener { updatedAnimation ->
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        textView.translationX = updatedAnimation.animatedValue as Float
    }
    ...
}

জাভা

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

onAnimationUpdate() পদ্ধতিতে আপনি আপডেট করা অ্যানিমেশন ভ্যালু অ্যাক্সেস করতে পারবেন এবং আপনার কোনও একটি ভিউয়ের প্রপার্টিতে এটি ব্যবহার করতে পারবেন। লিসনার সম্পর্কে আরও তথ্যের জন্য, অ্যানিমেশন লিসনার সম্পর্কিত বিভাগটি দেখুন।

ObjectAnimator ব্যবহার করে অ্যানিমেট করুন

ObjectAnimator হল ValueAnimator-এর (আগের বিভাগে আলোচনা করা হয়েছে) একটি সাবক্লাস এবং এটি টাইমিং ইঞ্জিন ও ValueAnimator-এর ভ্যালু কম্পিউটেশনকে একত্রিত করে, যাতে টার্গেট অবজেক্টের নামযুক্ত প্রপার্টি অ্যানিমেট করা যায়। এর ফলে যেকোনও অবজেক্ট অ্যানিমেট করা অনেক সহজ হয়ে যায়, কারণ আপনাকে আর ValueAnimator.AnimatorUpdateListener প্রয়োগ করতে হয় না, কারণ অ্যানিমেটেড প্রপার্টি অটোমেটিক আপডেট হয়।

ObjectAnimator ইনস্ট্যান্টিয়েট করা ValueAnimator-এর মতোই, তবে আপনি অবজেক্ট এবং সেই অবজেক্টের প্রপার্টির নামও (স্ট্রিং হিসেবে) নির্দিষ্ট করেন, যার মধ্যে অ্যানিমেট করার ভ্যালু থাকে:

Kotlin

ObjectAnimator.ofFloat(textView, "translationX", 100f).apply {
    duration = 1000
    start()
}

জাভা

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
animation.setDuration(1000);
animation.start();

ObjectAnimator-এর প্রপার্টি সঠিকভাবে আপডেট করতে, আপনাকে নিম্নলিখিত ধাপগুলি অনুসরণ করতে হবে:

  • আপনি যে অবজেক্ট প্রপার্টি অ্যানিমেট করছেন সেটিতে অবশ্যই একটি সেটার ফাংশন (ক্যামেল কেসে) থাকতে হবে, যা set<PropertyName>() ফর্ম্যাটে হবে। কারণ অ্যানিমেশনের সময় ObjectAnimator অটোমেটিক প্রপার্টি আপডেট করে, তাই এই সেটার পদ্ধতির মাধ্যমে প্রপার্টি অ্যাক্সেস করতে পারতেই হবে। যেমন, প্রপার্টির নাম foo হলে, আপনার কাছে setFoo() পদ্ধতি থাকতে হবে। এই সেটার পদ্ধতি না থাকলে, আপনার কাছে তিনটি বিকল্প আছে:
    • আপনার কাছে অধিকার থাকলে, ক্লাসে সেটার পদ্ধতি যোগ করুন।
    • এমন একটি র‍্যাপার ক্লাস ব্যবহার করুন যা পরিবর্তন করার অধিকার আপনার আছে এবং সেই র‍্যাপারকে সঠিক সেটার পদ্ধতির মাধ্যমে ভ্যালু গ্রহণ করতে দিন এবং আসল অবজেক্টে সেটি ফরওয়ার্ড করুন।
    • পরিবর্তে ValueAnimator ব্যবহার করুন।
  • আপনি যদি ObjectAnimator ফ্যাক্টরি পদ্ধতির মধ্যে একটিতে values... প্যারামিটারের জন্য শুধুমাত্র একটি ভ্যালু নির্দিষ্ট করেন, তাহলে এটি অ্যানিমেশনের শেষ ভ্যালু হিসেবে ধরে নেওয়া হয়। তাই, আপনি যে অবজেক্ট প্রপার্টি অ্যানিমেট করছেন, সেটিতে অবশ্যই একটি গেটার ফাংশন থাকতে হবে যা অ্যানিমেশনের শুরুর ভ্যালু পেতে ব্যবহার করা হয়। গেটার ফাংশনটি অবশ্যই get<PropertyName>()-এর ফর্ম্যাটে হতে হবে। যেমন, প্রপার্টির নাম foo হলে, আপনার getFoo() পদ্ধতি থাকতে হবে।
  • আপনি যে প্রপার্টি অ্যানিমেট করছেন সেটির গেটার (প্রয়োজন হলে) এবং সেটার পদ্ধতি অবশ্যই ObjectAnimator-এ আপনার উল্লেখ করা শুরু এবং শেষের ভ্যালুর মতো একই ধরনের হতে হবে। যেমন, আপনি যদি নিম্নলিখিত ObjectAnimator তৈরি করেন, তাহলে আপনার কাছে অবশ্যই targetObject.setPropName(float) এবং targetObject.getPropName() থাকতে হবে:
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • আপনি কোন প্রপার্টি বা অবজেক্ট অ্যানিমেট করছেন তার উপর নির্ভর করে, আপনাকে একটি ভিউতে invalidate() পদ্ধতি কল করতে হতে পারে যাতে স্ক্রিনটি আপডেট করা অ্যানিমেটেড ভ্যালু সহ নিজেকে আবার আঁকতে বাধ্য হয়। আপনি এটি onAnimationUpdate() কলব্যাকে করেন। যেমন, কোনও Drawable অবজেক্টের কালার প্রপার্টি অ্যানিমেট করলে, স্ক্রিনে তখনই আপডেট হয় যখন সেই অবজেক্ট নিজেকে আবার আঁকে। View-এর সব প্রপার্টি সেটার, যেমন setAlpha() এবং setTranslationX() View-কে সঠিকভাবে ইনভ্যালিডেট করে, তাই নতুন ভ্যালু সহ এইসব মেথড কল করার সময় আপনাকে View ইনভ্যালিডেট করতে হবে না। লিসনার সম্পর্কে আরও তথ্যের জন্য, অ্যানিমেশন লিসনার সম্পর্কিত বিভাগটি দেখুন।

AnimatorSet ব্যবহার করে একাধিক অ্যানিমেশন কোরিওগ্রাফ করুন

অনেক ক্ষেত্রে, আপনি এমন একটি অ্যানিমেশন চালাতে চান যা অন্য একটি অ্যানিমেশন কখন শুরু বা শেষ হয় তার উপর নির্ভর করে। Android সিস্টেম আপনাকে একসাথে অ্যানিমেশনগুলিকে একটি AnimatorSet-এ বান্ডিল করতে দেয়, যাতে আপনি অ্যানিমেশনগুলি একসাথে, ক্রমানুসারে বা নির্দিষ্ট বিলম্বের পরে শুরু করবেন কিনা তা নির্দিষ্ট করতে পারেন। এছাড়াও, আপনি একটির মধ্যে আরেকটি AnimatorSet অবজেক্ট নেস্ট করতে পারবেন।

নিম্নলিখিত কোড স্নিপেট নিম্নলিখিত Animator অবজেক্ট নিম্নলিখিত উপায়ে চালায়:

  1. bounceAnim বার চালানো হয়েছে।
  2. squashAnim1, squashAnim2, stretchAnim1 এবং stretchAnim2 একই সময়ে চালায়।
  3. bounceBackAnim বার চালানো হয়েছে।
  4. fadeAnim বার চালানো হয়েছে।

Kotlin

val bouncer = AnimatorSet().apply {
    play(bounceAnim).before(squashAnim1)
    play(squashAnim1).with(squashAnim2)
    play(squashAnim1).with(stretchAnim1)
    play(squashAnim1).with(stretchAnim2)
    play(bounceBackAnim).after(stretchAnim2)
}
val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
}
AnimatorSet().apply {
    play(bouncer).before(fadeAnim)
    start()
}

জাভা

AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

অ্যানিমেশন লিসনার

নিচে উল্লেখ করা লিসনারের সাহায্যে আপনি অ্যানিমেশনের সময়কাল চলাকালীন গুরুত্বপূর্ণ ইভেন্ট শুনতে পারবেন।

  • Animator.AnimatorListener
    • onAnimationStart() - অ্যানিমেশন শুরু হলে কল করা হয়।
    • onAnimationEnd() - অ্যানিমেশন শেষ হলে কল করা হয়।
    • onAnimationRepeat() - অ্যানিমেশন রিপিট হলে কল করা হয়।
    • onAnimationCancel() - অ্যানিমেশন বাতিল করা হলে কল করা হয়। বাতিল করা অ্যানিমেশনও onAnimationEnd() কল করে, সেগুলি কীভাবে শেষ করা হয়েছে তা নির্বিশেষে।
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() - অ্যানিমেশনের প্রতিটি ফ্রেমে কল করা হয়। অ্যানিমেশন চলাকালীন ValueAnimator-এর মাধ্যমে জেনারেট করা গণনা করা ভ্যালু ব্যবহার করতে এই ইভেন্ট শুনুন। ভ্যালু ব্যবহার করতে, getAnimatedValue() পদ্ধতির মাধ্যমে বর্তমান অ্যানিমেটেড ভ্যালু পেতে ইভেন্টে পাস করা ValueAnimator অবজেক্ট কোয়েরি করুন। আপনি ValueAnimator ব্যবহার করলে, এই লিসেনার প্রয়োগ করা বাধ্যতামূলক।

      আপনি কোন প্রপার্টি বা অবজেক্ট অ্যানিমেট করছেন তার উপর নির্ভর করে, আপনাকে হয়ত invalidate()-এ কল করতে হবে যাতে স্ক্রিনের সেই অংশটি নতুন অ্যানিমেটেড ভ্যালু সহ নিজেকে আবার আঁকতে বাধ্য হয়। যেমন, Drawable অবজেক্টের কালার প্রপার্টি অ্যানিমেট করলে, স্ক্রিনে তখনই আপডেট হয় যখন সেই অবজেক্ট নিজেকে আবার আঁকে। View-এর সব প্রপার্টি সেটার, যেমন setAlpha() এবং setTranslationX() View-কে সঠিকভাবে ইনভ্যালিডেট করে, তাই নতুন ভ্যালু দিয়ে এইসব পদ্ধতি কল করার সময় আপনাকে View ইনভ্যালিডেট করতে হবে না।

আপনি যদি Animator.AnimatorListener ইন্টারফেসের সব পদ্ধতি প্রয়োগ করতে না চান, তাহলে Animator.AnimatorListener ইন্টারফেস প্রয়োগ করার পরিবর্তে AnimatorListenerAdapter ক্লাস এক্সটেন্ড করতে পারেন। AnimatorListenerAdapter ক্লাসটি মেথডের খালি ইমপ্লিমেন্টেশন প্রদান করে যা আপনি ওভাররাইড করার জন্য বেছে নিতে পারেন।

যেমন, নিম্নলিখিত কোড স্নিপেট শুধু onAnimationEnd() কলব্যাকের জন্য AnimatorListenerAdapter তৈরি করে:

Kotlin

ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            balls.remove((animation as ObjectAnimator).target)
        }
    })
}

জাভা

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

ViewGroup অবজেক্টে লেআউট পরিবর্তন অ্যানিমেট করুন

প্রপার্টি অ্যানিমেশন সিস্টেম ViewGroup অবজেক্টে পরিবর্তন অ্যানিমেট করার ক্ষমতা প্রদান করে পাশাপাশি View অবজেক্টগুলি নিজেরাই অ্যানিমেট করার একটি সহজ উপায় প্রদান করে।

আপনি LayoutTransition ক্লাস ব্যবহার করে ViewGroup-এর মধ্যে লেআউট পরিবর্তন অ্যানিমেট করতে পারবেন। ViewGroup-এর মধ্যে থাকা ভিউ, ViewGroup-এ যোগ করা বা সেখান থেকে সরিয়ে দেওয়ার সময় অথবা VISIBLE, INVISIBLE বা GONE সহ কোনও ভিউয়ের setVisibility() পদ্ধতি কল করার সময়, আবির্ভাব ও অন্তর্ধান অ্যানিমেশনের মাধ্যমে দেখানো যেতে পারে। আপনি ভিউ যোগ বা সরানোর সময় ViewGroup-এ বাকি ভিউগুলিও তাদের নতুন পজিশনে অ্যানিমেট করতে পারে। আপনি setAnimator() কল করে এবং নিম্নলিখিত LayoutTransition কনস্ট্যান্টের মধ্যে একটি সহ Animator অবজেক্ট পাস করে LayoutTransition অবজেক্টে নিম্নলিখিত অ্যানিমেশন সংজ্ঞায়িত করতে পারেন:

  • APPEARING - কন্টেনারে দেখানো আইটেমে যে অ্যানিমেশন চলে তা নির্দেশ করার জন্য একটি ফ্ল্যাগ।
  • CHANGE_APPEARING - কন্টেনারে নতুন আইটেম আসার কারণে যেসব আইটেম পরিবর্তন হচ্ছে, সেগুলির উপর চলা অ্যানিমেশন নির্দেশ করার ফ্ল্যাগ।
  • DISAPPEARING - কন্টেনার থেকে অদৃশ্য হয়ে যাওয়া আইটেমে যে অ্যানিমেশন রান করে তা নির্দেশ করার ফ্ল্যাগ।
  • CHANGE_DISAPPEARING - একটি ফ্ল্যাগ যা অ্যানিমেশন নির্দেশ করে যা আইটেমগুলিতে চলে কন্টেইনার থেকে একটি আইটেম অদৃশ্য হওয়ার কারণে পরিবর্তন হচ্ছে।

আপনার লেআউট ট্রানজিশনের লুক কাস্টমাইজ করতে, এই চার ধরনের ইভেন্টের জন্য আপনি নিজের কাস্টম অ্যানিমেশন নির্ধারণ করতে পারেন অথবা ডিফল্ট অ্যানিমেশন ব্যবহার করার জন্য অ্যানিমেশন সিস্টেমকে বলতে পারেন।

ViewGroup-এর জন্য android:animateLayoutchanges অ্যাট্রিবিউট true-এ সেট করতে নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

এই অ্যাট্রিবিউট true হিসেবে সেট করলে, ViewGroup থেকে যোগ করা বা সরানো View এবং ViewGroup-এ থাকা বাকি View-তে অটোমেটিক অ্যানিমেশন যোগ করা হয়।

StateListAnimator ব্যবহার করে ভিউ স্টেট পরিবর্তন অ্যানিমেট করুন

StateListAnimator ক্লাস আপনাকে অ্যানিমেটর সংজ্ঞায়িত করতে দেয় যা ভিউয়ের স্ট্যাটাস পরিবর্তন হলে রান করে। এই অবজেক্টটি একটি Animator অবজেক্টের জন্য একটি র‍্যাপার হিসাবে কাজ করে, যখনই নির্দিষ্ট ভিউ স্টেট (যেমন "প্রেস করা" বা "ফোকাস করা") পরিবর্তিত হয় তখনই সেই অ্যানিমেশনকে কল করে।

StateListAnimator-কে XML রিসোর্সে রুট <selector> এলিমেন্ট ও চাইল্ড <item> এলিমেন্টের মাধ্যমে সংজ্ঞায়িত করা যেতে পারে, যেখানে প্রতিটি এলিমেন্ট StateListAnimator ক্লাস দ্বারা সংজ্ঞায়িত আলাদা ভিউ স্টেট নির্দিষ্ট করে। প্রতিটি <item>-এ প্রপার্টি অ্যানিমেশন সেট-এর সংজ্ঞা থাকে।

যেমন, নিম্নলিখিত ফাইলটি একটি স্টেট লিস্ট অ্যানিমেটর তৈরি করে যা ভিউ প্রেস করা হলে তার x ও y স্কেল পরিবর্তন করে:

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the pressed state; increase x and y size to 150% -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
        </set>
    </item>
    <!-- the default, non-pressed state; set x and y size to 100% -->
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
        </set>
    </item>
</selector>

কোনও ভিউতে স্টেট লিস্ট অ্যানিমেটর অ্যাটাচ করতে, নিম্নলিখিত উপায়ে android:stateListAnimator অ্যাট্রিবিউট যোগ করুন:

<Button android:stateListAnimator="@xml/animate_scale"
        ... />

এখন এই বোতামের স্ট্যাটাস পরিবর্তন হলে animate_scale.xml-এ নির্দিষ্ট করা অ্যানিমেশন ব্যবহার করা হয়।

অথবা এর পরিবর্তে আপনার কোডের কোনও ভিউতে স্টেট লিস্ট অ্যানিমেটর অ্যাসাইন করতে, AnimatorInflater.loadStateListAnimator() পদ্ধতি ব্যবহার করুন এবং View.setStateListAnimator() পদ্ধতির মাধ্যমে আপনার ভিউতে অ্যানিমেটর অ্যাসাইন করুন।

অথবা, ভিউয়ের প্রপার্টি অ্যানিমেট করার পরিবর্তে, আপনি AnimatedStateListDrawable ব্যবহার করে, স্টেট পরিবর্তনের মধ্যে ড্রয়েবল অ্যানিমেশন চালাতে পারেন। Android 5.0-এর কিছু সিস্টেম উইজেট ডিফল্ট হিসেবে এইসব অ্যানিমেশন ব্যবহার করে। নিম্নলিখিত উদাহরণ থেকে কীভাবে XML রিসোর্স হিসেবে AnimatedStateListDrawable সংজ্ঞায়িত করতে হয় তা জানুন:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

TypeEvaluator ব্যবহার করুন

আপনি যদি এমন কোনও টাইপ অ্যানিমেট করতে চান যা Android সিস্টেমের কাছে অজানা, তাহলে আপনি TypeEvaluator ইন্টারফেস প্রয়োগ করে নিজের ইভ্যালুয়েটর তৈরি করতে পারেন। Android সিস্টেম যেসব ধরন শনাক্ত করতে পারে সেগুলি হল int, float বা কোনও রঙ, যা IntEvaluator, FloatEvaluator ও ArgbEvaluator ধরনের ইভ্যালুয়েটর দ্বারা সমর্থিত।

TypeEvaluator ইন্টারফেসে প্রয়োগ করার জন্য শুধুমাত্র একটি পদ্ধতি আছে, evaluate() পদ্ধতি। এটি অ্যানিমেশনের বর্তমান পয়েন্টে আপনার অ্যানিমেটেড প্রপার্টির জন্য উপযুক্ত ভ্যালু ফিরিয়ে দিতে, আপনি যে অ্যানিমেটর ব্যবহার করছেন তাকে অনুমতি দেয়। FloatEvaluator ক্লাস এটি কীভাবে করতে হয় তা দেখায়:

Kotlin

private class FloatEvaluator : TypeEvaluator<Any> {

    override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any {
        return (startValue as Number).toFloat().let { startFloat ->
            startFloat + fraction * ((endValue as Number).toFloat() - startFloat)
        }
    }

}

জাভা

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

মনে রাখবেন: ValueAnimator (বা ObjectAnimator) রান করলে, এটি অ্যানিমেশনের বর্তমান অতিবাহিত ভগ্নাংশ (০ থেকে ১-এর মধ্যে কোনও মান) গণনা করে এবং তারপরে আপনি যে ইন্টারপোলেটর ব্যবহার করছেন তার উপর নির্ভর করে সেটির একটি ইন্টারপোলেট করা ভার্সন গণনা করে। ইন্টারপোলেট করা ভগ্নাংশ হল আপনার TypeEvaluator, fraction প্যারামিটারের মাধ্যমে যা পায়, তাই অ্যানিমেটেড ভ্যালু গণনা করার সময় আপনাকে ইন্টারপোলেটর বিবেচনা করতে হবে না।

ইন্টারপোলেটর ব্যবহার করুন

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

অ্যানিমেশন সিস্টেমে ইন্টারপোলেটররা অ্যানিমেটরদের কাছ থেকে একটি ভগ্নাংশ পায় যা অ্যানিমেশনের অতিবাহিত সময়কে উপস্থাপন করে। ইন্টারপোলেটর এই ভগ্নাংশকে পরিবর্তন করে যাতে এটি যে ধরনের অ্যানিমেশন প্রদান করতে চায় তার সাথে মিলে যায়। Android সিস্টেম android.view.animation package-এ সাধারণ ইন্টারপোলেটরের একটি সেট প্রদান করে। এগুলির মধ্যে কোনওটিই আপনার প্রয়োজন পূরণ না করলে, আপনি TimeInterpolator ইন্টারফেস প্রয়োগ করে নিজের ইন্টারফেস তৈরি করতে পারেন।

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

AccelerateDecelerateInterpolator

Kotlin

override fun getInterpolation(input: Float): Float =
        (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f

জাভা

@Override
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

LinearInterpolator

Kotlin

override fun getInterpolation(input: Float): Float = input

জাভা

@Override
public float getInterpolation(float input) {
    return input;
}

নিম্নলিখিত সারণীটি আনুমানিক মানগুলি উপস্থাপন করে যা এইগুলি দ্বারা গণনা করা হয় ১০০০ মিলি সেকেন্ড স্থায়ী অ্যানিমেশনের জন্য ইন্টারপোলেটর:

মিলিসেকেন্ড অতিবাহিত হয়েছে অতিক্রান্ত ভগ্নাংশ/ইন্টারপোলেট করা ভগ্নাংশ (লিনিয়ার) ইন্টারপোলেট করা ভগ্নাংশ (গতি বাড়ানো/কমানো)
0 0 0
200 .২ .১
400 .৪ .৩৪৫
600 .৬ .৬৫৪
৮০০ .৮ .৯
১০০০ 1 1

টেবিলে যেমন দেখানো হয়েছে, LinearInterpolator একই গতিতে ভ্যালু পরিবর্তন করে, প্রতি ২০০ মিলি সেকেন্ডে .২ করে। AccelerateDecelerateInterpolator ২০০ মিলি সেকেন্ড ও ৬০০ মিলি সেকেন্ডের মধ্যে LinearInterpolator-এর চেয়ে দ্রুত এবং ৬০০ মিলি সেকেন্ড ও ১০০০ মিলি সেকেন্ডের মধ্যে আরও ধীরে ভ্যালু পরিবর্তন করে।

কীফ্রেম নির্দিষ্ট করা

Keyframe অবজেক্টে সময়/মান পেয়ার থাকে যা আপনাকে অ্যানিমেশনের নির্দিষ্ট সময়ে নির্দিষ্ট স্টেট নির্ধারণ করতে দেয়। প্রতিটি কীফ্রেমের নিজস্ব ইন্টারপোলেটরও থাকতে পারে যা আগের কীফ্রেমের সময় এবং এই কীফ্রেমের সময়ের মধ্যে অ্যানিমেশনের আচরণ নিয়ন্ত্রণ করে।

Keyframe অবজেক্ট ইনস্ট্যান্টিয়েট করতে, আপনাকে অবশ্যই উপযুক্ত ধরনের Keyframe পেতে ফ্যাক্টরি পদ্ধতি, ofInt(), ofFloat() অথবা ofObject()-এর মধ্যে যেকোনও একটি ব্যবহার করতে হবে। তারপর আপনি PropertyValuesHolder অবজেক্ট পেতে ofKeyframe() ফ্যাক্টরি মেথড কল করেন। অবজেক্টটি পাওয়ার পরে, আপনি PropertyValuesHolder অবজেক্ট এবং অ্যানিমেট করার অবজেক্ট পাস করে অ্যানিমেটর পেতে পারেন। নিম্নলিখিত কোড স্নিপেট থেকে বোঝা যাবে যে এটি কীভাবে করতে হবে:

Kotlin

val kf0 = Keyframe.ofFloat(0f, 0f)
val kf1 = Keyframe.ofFloat(.5f, 360f)
val kf2 = Keyframe.ofFloat(1f, 0f)
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2)
ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply {
    duration = 5000
}

জাভা

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

অ্যানিমেট ভিউ

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

প্রপার্টি অ্যানিমেশন সিস্টেম ভিউ অবজেক্টের আসল প্রপার্টি পরিবর্তন করে স্ক্রিনে ভিউ অ্যানিমেট করতে পারে। এছাড়াও, Views-এর প্রপার্টি পরিবর্তন করা হলে, স্ক্রিন রিফ্রেশ করার জন্য এটি অটোমেটিক invalidate() মেথড কল করে। View ক্লাসে নতুন প্রপার্টি যা প্রপার্টি অ্যানিমেশনকে সহজ করে তোলে:

  • translationX এবং translationY: এই প্রপার্টিগুলি নিয়ন্ত্রণ করে যে ভিউ কোথায় অবস্থিত, এটি বাঁদিক ও উপরের কোঅর্ডিনেট থেকে ডেল্টা হিসেবে দেখানো হয় যা লেআউট কন্টেনার দ্বারা সেট করা হয়।
  • rotation, rotationX এবং rotationY: এই প্রপার্টিগুলি পিভট পয়েন্টের চারপাশে 2D (rotation প্রপার্টি) এবং 3D-তে রোটেশন নিয়ন্ত্রণ করে।
  • scaleX এবং scaleY: এই প্রপার্টিগুলি পিভট পয়েন্টের চারপাশে View-এর 2D স্কেলিং নিয়ন্ত্রণ করে।
  • pivotX এবং pivotY: এই প্রপার্টিগুলি পিভট পয়েন্টের লোকেশন কন্ট্রোল করে, যার চারপাশে রোটেশন এবং স্কেলিং ট্রান্সফর্ম ঘটে। ডিফল্ট হিসেবে, পিভট পয়েন্ট অবজেক্টের কেন্দ্রে থাকে।
  • x এবং y: এগুলি হল কন্টেনারে ভিউয়ের চূড়ান্ত লোকেশন বর্ণনা করার জন্য সহজ ইউটিলিটি প্রপার্টি, যা left এবং top ভ্যালু এবং translationX এবং translationY ভ্যালুর যোগফল হিসেবে দেখানো হয়।
  • alpha: ভিউতে আলফা ট্রান্সপারেন্সি দেখায়। ডিফল্ট হিসেবে এই ভ্যালু হল ১ (অস্বচ্ছ), সম্পূর্ণ স্বচ্ছতা (দেখা যায় না) বোঝাতে ০ ভ্যালু ব্যবহার করা হয়।

কোনও View অবজেক্টের প্রপার্টি অ্যানিমেট করতে, যেমন এটির রঙ বা রোটেশন ভ্যালু, আপনাকে শুধু একটি প্রপার্টি অ্যানিমেটর তৈরি করতে হবে এবং আপনি যে View প্রপার্টি অ্যানিমেট করতে চান সেটি নির্দিষ্ট করতে হবে। যেমন:

Kotlin

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)

জাভা

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

অ্যানিমেটর তৈরি করার ব্যাপারে আরও তথ্যের জন্য, ValueAnimator এবং ObjectAnimator-এর সাহায্যে অ্যানিমেট করা সংক্রান্ত বিভাগগুলি দেখুন।

ViewPropertyAnimator ব্যবহার করে অ্যানিমেট করুন

ViewPropertyAnimator, একটি অন্তর্নিহিত Animator অবজেক্ট ব্যবহার করে, সমান্তরালভাবে View-এর একাধিক প্রপার্টি অ্যানিমেট করার একটি সহজ উপায় প্রদান করে। এটি অনেকটা ObjectAnimator-এর মতো কাজ করে, কারণ এটি ভিউয়ের প্রপার্টির আসল ভ্যালু পরিবর্তন করে, তবে একসাথে অনেক প্রপার্টি অ্যানিমেট করার সময় এটি আরও দক্ষভাবে কাজ করে। এছাড়াও, ViewPropertyAnimator ব্যবহার করার কোড অনেক সংক্ষিপ্ত এবং সহজে পড়া যায়। নিম্নলিখিত কোড স্নিপেট থেকে একাধিক ObjectAnimator অবজেক্ট, একটি ObjectAnimator এবং ViewPropertyAnimator ব্যবহার করার মধ্যে পার্থক্য বোঝা যায়, যখন একইসাথে কোনও ভিউয়ের x এবং y প্রপার্টি অ্যানিমেট করা হয়।

একাধিক ObjectAnimator অবজেক্ট

Kotlin

val animX = ObjectAnimator.ofFloat(myView, "x", 50f)
val animY = ObjectAnimator.ofFloat(myView, "y", 100f)
AnimatorSet().apply {
    playTogether(animX, animY)
    start()
}

জাভা

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

One ObjectAnimator

Kotlin

val pvhX = PropertyValuesHolder.ofFloat("x", 50f)
val pvhY = PropertyValuesHolder.ofFloat("y", 100f)
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()

জাভা

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

ViewPropertyAnimator

Kotlin

myView.animate().x(50f).y(100f)

জাভা

myView.animate().x(50f).y(100f);

ViewPropertyAnimator সম্পর্কে আরও বিস্তারিত তথ্যের জন্য, সংশ্লিষ্ট Android Developers ব্লগ পোস্ট দেখুন।

XML-এ অ্যানিমেশন ঘোষণা করা

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

Android 3.1 থেকে শুরু করে, নতুন প্রপার্টি অ্যানিমেশন API ব্যবহার করা অ্যানিমেশন ফাইলগুলিকে লিগ্যাসি ভিউ অ্যানিমেশন ফ্রেমওয়ার্ক ব্যবহার করা ফাইল থেকে আলাদা করতে, আপনাকে প্রপার্টি অ্যানিমেশনের জন্য XML ফাইলগুলি res/animator/ ডিরেক্টরিতে সেভ করতে হবে।

নিম্নলিখিত প্রপার্টি অ্যানিমেশন ক্লাসে XML ডিক্লারেশন সাপোর্ট আছে, নিম্নলিখিত XML ট্যাগের সাথে:

আপনার XML ডিক্লারেশনে ব্যবহার করতে পারবেন এমন অ্যাট্রিবিউট খুঁজতে, অ্যানিমেশন রিসোর্স দেখুন। নিচের উদাহরণে অবজেক্ট অ্যানিমেশনের দুটি সেট পরপর চালানো হয়, প্রথম নেস্টেড সেট দুটি অবজেক্ট অ্যানিমেশন একসাথে চালায়:

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>

এই অ্যানিমেশন চালাতে, আপনাকে অবশ্যই আপনার কোডে XML রিসোর্সকে একটি AnimatorSet অবজেক্টে ইনফ্লেট করতে হবে এবং তারপরে অ্যানিমেশন সেট শুরু করার আগে সমস্ত অ্যানিমেশনের জন্য টার্গেট অবজেক্ট সেট করতে হবে। setTarget() কল করা হলে, সুবিধার জন্য AnimatorSet-এর সব চাইল্ডের জন্য একটি টার্গেট অবজেক্ট সেট করা হয়। এটি কীভাবে করতে হয় তা নিম্নলিখিত কোড থেকে জানতে পারবেন:

Kotlin

(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply {
    setTarget(myObject)
    start()
}

জাভা

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animator.property_animator);
set.setTarget(myObject);
set.start();

এছাড়াও, আপনি XML-এ ValueAnimator ঘোষণা করতে পারেন, যেমন নিচের উদাহরণে দেখানো হয়েছে:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0f"
    android:valueTo="-100f" />

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

Kotlin

(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply {
    addUpdateListener { updatedAnimation ->
        textView.translationX = updatedAnimation.animatedValue as Float
    }

    start()
}

জাভা

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,
        R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

xmlAnimator.start();

প্রপার্টি অ্যানিমেশন সংজ্ঞায়িত করার জন্য XML সিনট্যাক্স সম্পর্কে তথ্যের জন্য, অ্যানিমেশন রিসোর্স দেখুন।

UI পারফর্ম্যান্সের উপর সম্ভাব্য প্রভাব

UI আপডেট করে এমন অ্যানিমেটর, অ্যানিমেশন রান করে এমন প্রতিটি ফ্রেমের জন্য অতিরিক্ত রেন্ডারিংয়ের কাজ করে। এই কারণে, রিসোর্স ইনটেনসিভ অ্যানিমেশন ব্যবহার করলে আপনার অ্যাপের পারফর্ম্যান্সের উপর নেতিবাচক প্রভাব পড়তে পারে।

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