Translate animation on views with position dependencies
Do I have to translate both views plus stretch the main content view or somehow anchor the main content view to the bottom of the screen?
Well, if you don't stretch the main content View
then anchoring it to the bottom will cause a gap to appear at the top as soon as the header View
moves up. So I think you'll need a set of animations (scale and translate) for it.
Or you use the Transition framework, in this case a ChangeBounds
transition will do the job for both View
s
View sceneRoot = <someViewGroupContainingBothViews>;
TransitionManager.beginDelayedTransition(sceneRoot, new ChangeBounds());
rlInfoBar.setY(<newY_CoordinateOfHeaderView>);
How to move view permanently in Android
Use and modify the LayoutParams instead.
Android translate animation move to absolute position
Judging from official Documentation it is not possible from XML.
However, you can do this in your Java code. Example:
view.animate().translationX(0f).translationY(0f).setInterpolator(new AccelerateDecelerateInterpolator()).start();
TranslationX
and TranslationY
animates to an absolute position. There is also TranslationXBy
an TranslationYBy
that animate relatively.
Animate/translate view from position of other view
Use ConstraintLayout for your layout, put your view constraints to starting position (here I will animate @+id/view
after clicking @+id/fab
. Animated view has to be VISIBLE
or INVISIBLE
- GONE
will mess up animation.
<androidx.constraintlayout.widget.ConstraintLayout
/*constraint stuff*/>
<View
android:id="@+id/view"
android:layout_width="120dp"
android:layout_height="120dp"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="120dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintEnd_toEndOf="@+id/symbolList" />
</androidx.constraintlayout.widget.ConstraintLayout>
There are few options:
- Use ObjectAnimator
In your xml file put View that will be animated on fab position:
view = findViewById(R.id.view)
fab = findViewById(R.id.fab)
fab.setOnClickListener {
view.visibility = View.VISIBLE
val propertyX = PropertyValuesHolder.ofFloat(View.X, 0f)
val propertyY = PropertyValuesHolder.ofFloat(View.Y, 0f)
ObjectAnimator.ofPropertyValuesHolder(view, propertyX, propertyY).apply {
duration = 2000L
start()
}
}
Or use ViewPropertyAnimator (same XML as above)
fab.setOnClickListener {
view.animate()
.x(0f)
.y(0f)
.setDuration(2000L)
.start()
}Or use TransitionManager, MotionLayout, scene api or animate ConstraintSet manually.
private fun startAnimation() {
val animationEndConstraints = ConstraintSet().apply {
clone(container)
clear(button.id, ConstraintSet.START)
clear(button.id, ConstraintSet.TOP)
// instead of parent you can use fab.id
connect(button.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0)
connect(button.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
}
TransitionManager.beginDelayedTransition(container)
animationEndConstraints.applyTo(container)
}
This approach will allow to specify start state as xml layout and end state as xml layout, but you will have less control.
With other view position:
fab.setOnClickListener {
view.animate()
.x(fab.left.toFloat())
.y(fab.top.toFloat())
.setDuration(2000L)
.start()
}
How to animate a View with Translate Animation in Android
In order to move a View anywhere on the screen, I would recommend placing it in a full screen layout. By doing so, you won't have to worry about clippings or relative coordinates.
You can try this sample code:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:id="@+id/rootLayout">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MOVE" android:layout_centerHorizontal="true"/>
<ImageView
android:id="@+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" android:layout_marginLeft="10dip"/>
<ImageView
android:id="@+id/img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" android:layout_centerVertical="true" android:layout_alignParentRight="true"/>
<ImageView
android:id="@+id/img3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" android:layout_marginLeft="60dip" android:layout_alignParentBottom="true" android:layout_marginBottom="100dip"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:clipChildren="false" android:clipToPadding="false">
<ImageView
android:id="@+id/img4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" android:layout_marginLeft="60dip" android:layout_marginTop="150dip"/>
</LinearLayout>
</RelativeLayout>
Your activity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button) findViewById( R.id.btn1 )).setOnClickListener( new OnClickListener()
{
@Override
public void onClick(View v)
{
ImageView img = (ImageView) findViewById( R.id.img1 );
moveViewToScreenCenter( img );
img = (ImageView) findViewById( R.id.img2 );
moveViewToScreenCenter( img );
img = (ImageView) findViewById( R.id.img3 );
moveViewToScreenCenter( img );
img = (ImageView) findViewById( R.id.img4 );
moveViewToScreenCenter( img );
}
});
}
private void moveViewToScreenCenter( View view )
{
RelativeLayout root = (RelativeLayout) findViewById( R.id.rootLayout );
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics( dm );
int statusBarOffset = dm.heightPixels - root.getMeasuredHeight();
int originalPos[] = new int[2];
view.getLocationOnScreen( originalPos );
int xDest = dm.widthPixels/2;
xDest -= (view.getMeasuredWidth()/2);
int yDest = dm.heightPixels/2 - (view.getMeasuredHeight()/2) - statusBarOffset;
TranslateAnimation anim = new TranslateAnimation( 0, xDest - originalPos[0] , 0, yDest - originalPos[1] );
anim.setDuration(1000);
anim.setFillAfter( true );
view.startAnimation(anim);
}
The method moveViewToScreenCenter
gets the View's absolute coordinates and calculates how much distance has to move from its current position to reach the center of the screen. The statusBarOffset
variable measures the status bar height.
I hope you can keep going with this example. Remember that after the animation your view's position is still the initial one. If you tap the MOVE button again and again the same movement will repeat. If you want to change your view's position do it after the animation is finished.
Related Topics
How to Move Main Content with Drawer Layout Left Side
Should Accessing Sharedpreferences Be Done Off the UI Thread
Manage Google Maps API Key with Gradle in Android Studio
Create a Chatview Layout in Android
Android Data Binding with a Custom View
Android Lollipop, Add Popup Menu from Title in Toolbar
Manually Adding Aar with Dependency Pom/Iml File
Where Is the All Android Broadcast Intent List
Android Opengl .Obj File Loader
Oniabpurchasefinished Never Called
How to Set Custom Typeface to Items in Navigationview
Am I Getting the Steps Right for Verifying a User's Android In-App Subscription
Cannot Find Zip-Align When Publishing App
Cannot Call Getsupportfragmentmanager() from Activity
Android Screen Sizes in Pixels for Ldpi, Mdpi, Hpdi