বাংলায় অ্যান্ড্রয়েড সহায়িকা - Bangla Android Guide

ভিউ জুম করুন

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

  1. হিডেন “জুম-ইন” (বড় করা) ImageView এ অধিক সংখ্যক ইমেজ বরাদ্দ করুন। নীচের উদাহরণ সরলতার জন্য ইউআই থ্রেডে একটি বড় আকারের ইমেজ রিসোর্স লোড করে। ইউআই থেডে ব্লকিং বন্ধ করতে একটি পৃথক থ্রেডে লোড করার মাধ্যমে আপনি এটা করতে চাইতে পারেন এবং তারপর ইউআই থ্রেডে বিটম্যাপ সেট করতে পারেন।

  2. ImageView এর জন্য বাউন্ড শুরু এবং শেষকে গণনা করুন।

  3. X, Y, (SCALE_X, এবং SCALE_Y) এ ৪ টি অবস্থানের এবং সাইজের প্রতিটা প্রপারটির অ্যানিমেশন করুন, একইভাবে শুরুর সীমা থেকে শেষের সীমার মধ্যে। এই চার ধরনের অ্যানিমেশন একটি AnimatorSet এ যুক্ত করা হয় যাতে তারা একই সাথে শুরু করতে পারে।

  4. একই ধরনের অ্যানিমেশন রান করলে জুম পেছনে চলে যায় কিন্তু বিপরীতভাবে ইউজার স্ক্রিন টাচ করে যখন ইমেজ জুম ইন করা হয়। ImageView এ একটি View.OnClickListener যুক্ত করে আপনি এটা করতে পারেন। যখন ক্লিক করা হয়, ImageView ইমেজ থাম্বনেইল সাইজে পিছিয়ে আসাকে মিনিমাইজ কওে এবং এটা তার দৃশ্যমানতাকে GONE এ সেট করে এটাকে হাইড করতে।

private void zoomImageFromThumb(final View thumbView, int imageResId) {
    // If there's an animation in progress, cancel it
    // immediately and proceed with this one.
    if (mCurrentAnimator != null) {
        mCurrentAnimator.cancel();
    }

    // Load the high-resolution "zoomed-in" image.
    final ImageView expandedImageView = (ImageView) findViewById(
            R.id.expanded_image);
    expandedImageView.setImageResource(imageResId);

    // Calculate the starting and ending bounds for the zoomed-in image.
    // This step involves lots of math. Yay, math.
    final Rect startBounds = new Rect();
    final Rect finalBounds = new Rect();
    final Point globalOffset = new Point();

    // The start bounds are the global visible rectangle of the thumbnail,
    // and the final bounds are the global visible rectangle of the container
    // view. Also set the container view's offset as the origin for the
    // bounds, since that's the origin for the positioning animation
    // properties (X, Y).
    thumbView.getGlobalVisibleRect(startBounds);
    findViewById(R.id.container)
            .getGlobalVisibleRect(finalBounds, globalOffset);
    startBounds.offset(-globalOffset.x, -globalOffset.y);
    finalBounds.offset(-globalOffset.x, -globalOffset.y);

    // Adjust the start bounds to be the same aspect ratio as the final
    // bounds using the "center crop" technique. This prevents undesirable
    // stretching during the animation. Also calculate the start scaling
    // factor (the end scaling factor is always 1.0).
    float startScale;
    if ((float) finalBounds.width() / finalBounds.height()
            > (float) startBounds.width() / startBounds.height()) {
        // Extend start bounds horizontally
        startScale = (float) startBounds.height() / finalBounds.height();
        float startWidth = startScale * finalBounds.width();
        float deltaWidth = (startWidth - startBounds.width()) / 2;
        startBounds.left -= deltaWidth;
        startBounds.right += deltaWidth;
    } else {
        // Extend start bounds vertically
        startScale = (float) startBounds.width() / finalBounds.width();
        float startHeight = startScale * finalBounds.height();
        float deltaHeight = (startHeight - startBounds.height()) / 2;
        startBounds.top -= deltaHeight;
        startBounds.bottom += deltaHeight;
    }

    // Hide the thumbnail and show the zoomed-in view. When the animation
    // begins, it will position the zoomed-in view in the place of the
    // thumbnail.
    thumbView.setAlpha(0f);
    expandedImageView.setVisibility(View.VISIBLE);

    // Set the pivot point for SCALE_X and SCALE_Y transformations
    // to the top-left corner of the zoomed-in view (the default
    // is the center of the view).
    expandedImageView.setPivotX(0f);
    expandedImageView.setPivotY(0f);

    // Construct and run the parallel animation of the four translation and
    // scale properties (X, Y, SCALE_X, and SCALE_Y).
    AnimatorSet set = new AnimatorSet();
    set
            .play(ObjectAnimator.ofFloat(expandedImageView, View.X,
                    startBounds.left, finalBounds.left))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
                    startBounds.top, finalBounds.top))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
            startScale, 1f)).with(ObjectAnimator.ofFloat(expandedImageView,
                    View.SCALE_Y, startScale, 1f));
    set.setDuration(mShortAnimationDuration);
    set.setInterpolator(new DecelerateInterpolator());
    set.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mCurrentAnimator = null;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            mCurrentAnimator = null;
        }
    });
    set.start();
    mCurrentAnimator = set;

    // Upon clicking the zoomed-in image, it should zoom back down
    // to the original bounds and show the thumbnail instead of
    // the expanded image.
    final float startScaleFinal = startScale;
    expandedImageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (mCurrentAnimator != null) {
                mCurrentAnimator.cancel();
            }

            // Animate the four positioning/sizing properties in parallel,
            // back to their original values.
            AnimatorSet set = new AnimatorSet();
            set.play(ObjectAnimator
                        .ofFloat(expandedImageView, View.X, startBounds.left))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView,
                                        View.Y,startBounds.top))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView,
                                        View.SCALE_X, startScaleFinal))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView,
                                        View.SCALE_Y, startScaleFinal));
            set.setDuration(mShortAnimationDuration);
            set.setInterpolator(new DecelerateInterpolator());
            set.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    thumbView.setAlpha(1f);
                    expandedImageView.setVisibility(View.GONE);
                    mCurrentAnimator = null;
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    thumbView.setAlpha(1f);
                    expandedImageView.setVisibility(View.GONE);
                    mCurrentAnimator = null;
                }
            });
            set.start();
            mCurrentAnimator = set;
        }
    });
}