সফ্টওয়্যার কীবোর্ড নিয়ন্ত্রণ এবং অ্যানিমেট করুন

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

WindowInsetsCompat ব্যবহার করে, আপনার অ্যাপটি সিস্টেম বারের সাথে যেভাবে ইন্টারঅ্যাক্ট করে, ঠিক সেভাবেই অন-স্ক্রিন কীবোর্ড (যাকে IME ও বলা হয়) অনুসন্ধান এবং নিয়ন্ত্রণ করতে পারে। সফ্টওয়্যার কীবোর্ড খোলা বা বন্ধ করার সময় আপনার অ্যাপটি WindowInsetsAnimationCompat ব্যবহার করে নিরবচ্ছিন্ন ট্রানজিশন তৈরি করতে পারে।

চিত্র ১. সফ্টওয়্যার কীবোর্ড ওপেন-ক্লোজড ট্রানজিশনের দুটি উদাহরণ।

পূর্বশর্ত

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

কীবোর্ড সফ্টওয়্যার দৃশ্যমানতা পরীক্ষা করুন

সফ্টওয়্যার কীবোর্ডের দৃশ্যমানতা পরীক্ষা করতে WindowInsets ব্যবহার করুন।

কোটলিন

val insets = ViewCompat.getRootWindowInsets(view) ?: return
val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom

জাভা

WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view);
boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;

বিকল্পভাবে, আপনি সফ্টওয়্যার কীবোর্ডের দৃশ্যমানতার পরিবর্তনগুলি পর্যবেক্ষণ করতে ViewCompat.setOnApplyWindowInsetsListener ব্যবহার করতে পারেন।

কোটলিন

ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets ->
  val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
  val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
  insets
}

জাভা

ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> {
  boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
  int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
  return insets;
});

সফ্টওয়্যার কীবোর্ডের সাথে অ্যানিমেশন সিঙ্ক্রোনাইজ করুন

একজন ব্যবহারকারী টেক্সট ইনপুট ফিল্ডে ট্যাপ করলে কীবোর্ডটি স্ক্রিনের নিচ থেকে স্লাইড হয়ে যায়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

চিত্র ২। সিঙ্ক্রোনাইজড কীবোর্ড অ্যানিমেশন।
  • চিত্র ২-এ "আনসিঙ্ক্রোনাইজড" লেবেলযুক্ত উদাহরণটি অ্যান্ড্রয়েড ১০ (এপিআই লেভেল ২৯) এর ডিফল্ট আচরণ দেখায়, যেখানে অ্যাপের টেক্সট ফিল্ড এবং বিষয়বস্তু কীবোর্ডের অ্যানিমেশনের সাথে সিঙ্ক্রোনাইজ করার পরিবর্তে জায়গায় স্ন্যাপ করে - এমন আচরণ যা দৃশ্যত বিরক্তিকর হতে পারে।

  • অ্যান্ড্রয়েড ১১ (এপিআই লেভেল ৩০) এবং তার উচ্চতর সংস্করণে, আপনি WindowInsetsAnimationCompat ব্যবহার করে অ্যাপের ট্রানজিশন সিঙ্ক্রোনাইজ করতে পারেন, যাতে কীবোর্ডটি স্ক্রিনের নিচ থেকে উপরে এবং নীচে স্লাইড করে। এটি আরও মসৃণ দেখাচ্ছে, যেমনটি চিত্র ২-এ "সিঙ্ক্রোনাইজড" লেবেলযুক্ত উদাহরণে দেখানো হয়েছে।

কীবোর্ড অ্যানিমেশনের সাথে সিঙ্ক্রোনাইজ করার জন্য ভিউ সহ WindowInsetsAnimationCompat.Callback কনফিগার করুন।

কোটলিন

ViewCompat.setWindowInsetsAnimationCallback(
  view,
  object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) {
    // Override methods.
  }
)

জাভা

ViewCompat.setWindowInsetsAnimationCallback(
    view,
    new WindowInsetsAnimationCompat.Callback(
        WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP
    ) {
      // Override methods.
    });

WindowInsetsAnimationCompat.Callback এ ওভাররাইড করার জন্য বেশ কয়েকটি পদ্ধতি রয়েছে, যেমন onPrepare() , onStart() , onProgress() , এবং onEnd() । যেকোনো লেআউট পরিবর্তনের আগে onPrepare() কল করে শুরু করুন।

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

রুট ভিউয়ের শুরুর অবস্থা নীচের স্থানাঙ্ক দেখানো একটি ছবি।
চিত্র ৩. শুরুর অবস্থা রেকর্ড করতে onPrepare() ব্যবহার করা হচ্ছে।

নিম্নলিখিত স্নিপেটটি onPrepare এ একটি নমুনা কল দেখায়:

কোটলিন

var startBottom = 0f

override fun onPrepare(
  animation: WindowInsetsAnimationCompat
) {
  startBottom = view.bottom.toFloat()
}

জাভা

float startBottom;

@Override
public void onPrepare(
    @NonNull WindowInsetsAnimationCompat animation
) {
  startBottom = view.getBottom();
}

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

ভিউয়ের শেষ অবস্থা নীচের স্থানাঙ্ক দেখানো একটি ছবি
চিত্র ৪. শেষ অবস্থা রেকর্ড করতে onStart() ব্যবহার করা হচ্ছে।

নিম্নলিখিত স্নিপেটটি onStart এ একটি নমুনা কল দেখায়:

কোটলিন

var endBottom = 0f

override fun onStart(
  animation: WindowInsetsAnimationCompat,
  bounds: WindowInsetsAnimationCompat.BoundsCompat
): WindowInsetsAnimationCompat.BoundsCompat {
  // Record the position of the view after the IME transition.
  endBottom = view.bottom.toFloat()

  return bounds
}

জাভা

float endBottom;

@NonNull
@Override
public WindowInsetsAnimationCompat.BoundsCompat onStart(
    @NonNull WindowInsetsAnimationCompat animation,
    @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds
) {
  endBottom = view.getBottom();
  return bounds;
}

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

এই মুহুর্তে সমস্ত লেআউট পরিবর্তন সম্পূর্ণ হয়েছে। উদাহরণস্বরূপ, যদি আপনি ভিউ স্থানান্তর করার জন্য View.translationY ব্যবহার করেন, তাহলে এই পদ্ধতির প্রতিটি কলের জন্য মান ধীরে ধীরে হ্রাস পায় এবং অবশেষে মূল লেআউট অবস্থানে 0 এ পৌঁছায়।

চিত্র ৫. অ্যানিমেশনগুলি সিঙ্ক্রোনাইজ করার জন্য onProgress() ব্যবহার করা।

নিম্নলিখিত স্নিপেটটি onProgress এ একটি নমুনা কল দেখায়:

কোটলিন

override fun onProgress(
  insets: WindowInsetsCompat,
  runningAnimations: MutableList<WindowInsetsAnimationCompat>
): WindowInsetsCompat {
  // Find an IME animation.
  val imeAnimation = runningAnimations.find {
    it.typeMask and WindowInsetsCompat.Type.ime() != 0
  } ?: return insets

  // Offset the view based on the interpolated fraction of the IME animation.
  view.translationY =
    (startBottom - endBottom) * (1 - imeAnimation.interpolatedFraction)

  return insets
}

জাভা

@NonNull
@Override
public WindowInsetsCompat onProgress(
    @NonNull WindowInsetsCompat insets,
    @NonNull List<WindowInsetsAnimationCompat> runningAnimations
) {
  // Find an IME animation.
  WindowInsetsAnimationCompat imeAnimation = null;
  for (WindowInsetsAnimationCompat animation : runningAnimations) {
    if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) {
      imeAnimation = animation;
      break;
    }
  }
  if (imeAnimation != null) {
    // Offset the view based on the interpolated fraction of the IME animation.
    view.setTranslationY((startBottom - endBottom)

        *   (1 - imeAnimation.getInterpolatedFraction()));
  }
  return insets;
}

ঐচ্ছিকভাবে, আপনি onEnd ওভাররাইড করতে পারেন। অ্যানিমেশন শেষ হওয়ার পরে এই পদ্ধতিটি বলা হয়। যেকোনো অস্থায়ী পরিবর্তন পরিষ্কার করার জন্য এটি একটি ভাল সময়।

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