Reputation: 5167
Right now I am implementing a feature where I need to animate any ImageView in the app to full screen when it is clicked. And when back it hit, a reverse animation will be applied to restored the ImageView to original position. The ImageView can be anywhere in the view tree. To simplify the description, consider this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/image1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher"/>
<ImageView
android:id="@+id/image2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_marginTop="100dp"
android:src="@mipmap/ic_launcher"/>
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="100dp"
android:layout_gravity="center">
<ImageView
android:id="@+id/image3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher"/>
</FrameLayout>
</LinearLayout>
And the corresponding kotlin file:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(R.id.image2).setOnClickListener {
it.animate().scaleX(5.0f).scaleY(5.0f).setDuration(5000L).start()
}
findViewById<View>(R.id.image3).setOnClickListener {
it.animate().scaleX(5.0f).scaleY(5.0f).setDuration(5000L).start()
}
}
}
Here when we click image2 or image3 we want it to scale up. However the result is not what we want. For image2 it will be covered by image3 after scaling up. For image3 it will simply be clipped:
What's the right way to temporarily bring the ImageView to front?
Upvotes: 1
Views: 176
Reputation: 124
Try this it would help you
class BottomNavigationExample : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bottom_navigation_example)
findViewById<View>(R.id.image2).setOnClickListener {
it.animate().scaleX(5.0f).scaleY(5.0f).setDuration(5000L).start()
setElevation(it)
}
findViewById<View>(R.id.image3).setOnClickListener {
it.animate().scaleX(5.0f).scaleY(5.0f).setDuration(5000L).start()
setElevation(it)
}
}
fun setElevation(view: View) {
ViewCompat.setElevation(image1, 0f);
ViewCompat.setElevation(image2, 0f);
ViewCompat.setElevation(image3, 0f);
ViewCompat.setElevation(view, 5f);
}
}
Upvotes: 4
Reputation: 87
You can use something like this..
class MainActivity : FragmentActivity() {
private var currentAnimator: Animator? = null
private var shortAnimationDuration: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val thumbView: View = findViewById(R.id.thumb_button_1)
val thumbView2: View = findViewById(R.id.thumb_button_2)
thumbView.setOnClickListener { zoomImageFromThumb(thumb_button_1, R.drawable.image1) }
thumbView2.setOnClickListener { zoomImageFromThumb(thumb_button_2, R.drawable.girls2) }
shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime)
}
private fun zoomImageFromThumb(thumbView: View, imageResId: Int) {
currentAnimator?.cancel()
val expandedImageView: ImageView = findViewById(R.id.expanded_image)
expandedImageView.setImageResource(imageResId)
val startBoundsInt = Rect()
val finalBoundsInt = Rect()
val globalOffset = Point()
thumbView.getGlobalVisibleRect(startBoundsInt)
findViewById<View>(R.id.container)
.getGlobalVisibleRect(finalBoundsInt, globalOffset)
startBoundsInt.offset(-globalOffset.x, -globalOffset.y)
finalBoundsInt.offset(-globalOffset.x, -globalOffset.y)
val startBounds = RectF(startBoundsInt)
val finalBounds = RectF(finalBoundsInt)
val startScale: Float
if ((finalBounds.width() / finalBounds.height() > startBounds.width() / startBounds.height())) {
// Extend start bounds horizontally
startScale = startBounds.height() / finalBounds.height()
val startWidth: Float = startScale * finalBounds.width()
val deltaWidth: Float = (startWidth - startBounds.width()) / 2
startBounds.left -= deltaWidth.toInt()
startBounds.right += deltaWidth.toInt()
} else {
// Extend start bounds vertically
startScale = startBounds.width() / finalBounds.width()
val startHeight: Float = startScale * finalBounds.height()
val deltaHeight: Float = (startHeight - startBounds.height()) / 2f
startBounds.top -= deltaHeight.toInt()
startBounds.bottom += deltaHeight.toInt()
}
thumbView.alpha = 0f
expandedImageView.visibility = View.VISIBLE
expandedImageView.pivotX = 0f
expandedImageView.pivotY = 0f
currentAnimator = AnimatorSet().apply {
play(
ObjectAnimator.ofFloat(
expandedImageView,
View.X,
startBounds.left,
finalBounds.left
)
).apply {
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))
}
duration = shortAnimationDuration.toLong()
interpolator = DecelerateInterpolator()
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
currentAnimator = null
}
override fun onAnimationCancel(animation: Animator) {
currentAnimator = null
}
})
start()
}
expandedImageView.setOnClickListener {
currentAnimator?.cancel()
currentAnimator = AnimatorSet().apply {
play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left)).apply {
with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top))
with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale))
with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale))
}
duration = shortAnimationDuration.toLong()
interpolator = DecelerateInterpolator()
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
thumbView.alpha = 1f
expandedImageView.visibility = View.GONE
currentAnimator = null
}
override fun onAnimationCancel(animation: Animator) {
thumbView.alpha = 1f
expandedImageView.visibility = View.GONE
currentAnimator = null
}
})
start()
}
}
}
}
layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<ImageButton
android:id="@+id/thumb_button_1"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:background="@color/colorWhite"
android:contentDescription="@null"
android:scaleType="centerInside"
android:src="@drawable/image1" />
<ImageButton
android:id="@+id/thumb_button_2"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:background="@color/colorWhite"
android:contentDescription="@null"
android:scaleType="centerInside"
android:src="@drawable/girls2" />
</LinearLayout>
<ImageView
android:id="@+id/expanded_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:visibility="invisible" />
Upvotes: 1