Animation is not smooth
I made an application where on a button click I copied the line layout. The code for the linear layout slide works fine, but the problem is it lags behind when sliding. Also the height I set for the shear layout is not suitable for all screen sizes (specifically for Nexus 5). Please help me
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_upload_add"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/add" />
<LinearLayout
android:id="@+id/ll_upload_options"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/choosefile_bg"
android:gravity="center"
android:orientation="vertical">
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
android:id="@+id/tv_upload_gallery"
style="@style/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:padding="5dp"
android:text="GALLERY"
android:textSize="20sp"
android:visibility="visible" />
<TextView
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/line" />
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
android:id="@+id/tv_upload_camera"
style="@style/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:padding="5dp"
android:text="CAMERA"
android:textSize="20sp"
android:visibility="visible" />
<TextView
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/line" />
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
android:id="@+id/tv_upload_file"
style="@style/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:padding="5dp"
android:text="FILE"
android:textSize="20sp"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/all_left_mar"
android:layout_marginRight="@dimen/all_right_mar"
android:layout_weight="2"
android:gravity="center"
android:orientation="vertical">
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.EditTextFont
style="@style/edit_text"
android:drawableBottom="@drawable/line_black"
android:hint="File Title"
android:textColor="#000"
android:textColorHint="#000" />
<AutoCompleteTextView
style="@style/edit_text"
android:layout_marginTop="10dp"
android:completionThreshold="1"
android:drawableBottom="@drawable/line_black"
android:hint="Type"
android:textColor="#000"
android:textColorHint="#000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<Switch
android:id="@+id/switch1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="false"
android:textOff="No"
android:textOn="Yes" />
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.TextViewGeneral
style="@style/text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="@string/Protect"
android:textColor="#000" />
</LinearLayout>
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.EditTextFont
style="@style/edit_text"
android:layout_marginTop="10dp"
android:drawableBottom="@drawable/line_black"
android:hint="Password"
android:inputType="numberPassword"
android:textColor="#000"
android:textColorHint="#000" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="@dimen/all_left_mar"
android:layout_marginRight="@dimen/all_right_mar"
android:layout_weight="1">
<pocketdocs.indiehustlers.com.pocketdocsv2.Utils.ButtonFont
style="@style/button"
android:text="UPLOAD" />
</LinearLayout>
</LinearLayout>
code
if (llUploadOptions.getMeasuredHeight() != 0) {
// tvGallery.setVisibility(View.GONE);
// tvCamera.setVisibility(View.GONE);
// tvFile.setVisibility(View.GONE);
ValueAnimator anim = ValueAnimator.ofInt(llUploadOptions.getMeasuredHeight(),200);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = llUploadOptions.getLayoutParams();
layoutParams.height = val;
llUploadOptions.setLayoutParams(layoutParams);
}
});
anim.setDuration(700);
anim.start();
} else {
ValueAnimator anim = ValueAnimator.ofInt(llUploadOptions.getMeasuredHeight(),250);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = llUploadOptions.getLayoutParams();
layoutParams.height = val;
llUploadOptions.setLayoutParams(layoutParams);
}
});
anim.setDuration(700);
anim.start();
}
source to share
The problem is when you are trying to animate the height of your layout. This means that with each step of the animation, you call setLayoutParams (), which causes your entire layout (including children) to be relayed by going through the full view hierarchy, and this results in lagged animation. Prototyping things is an expensive operation!
There are some "workarounds" (I'm not sure what you want to do):
- Since Android 4.0 you can just use animation layout changes in your xml if you just want to show / hide the element with animation in your layout
- For more complex things, you might consider using the Transitions framework presented in Kitkat (Api 19) https://www.youtube.com/watch?v=S3H7nJ4QaD8 . Backports: https://github.com/guerwan/TransitionsBackport or https://github.com/andkulikov/transitions-everywhere
- "Faking" animations by manually animating representations with translation, alpha, etc. and setting LayoutParameters only once after the animation finishes.
- I don't remember what the api is called, but you can subclass from ViewGroup and use it as the root layout. You must intercept the layout changes when animating the height to get a smooth animation (this is how animateLayoutChanges = true works). However, this is an advanced topic and I would recommend going one of the other ways.
source to share
you are using Animators
(not Animations
) which can be slow especially with moving widgets around. try TranslateAnimation
TranslateAnimation animation = new TranslateAnimation(0.0f, 200.0f,
0.0f, 0.0f);
// these are delta's, check doc for this constructor
// TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(700);
llUploadOptions.startAnimation(animation);
if you want to leave your animated view at target coordinates use
animation.setFillAfter(true);
but it may not be clickable or there may be other problems. for these you can use
animation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation anim)
{
};
public void onAnimationRepeat(Animation anim)
{
};
public void onAnimationEnd(Animation anim)
{
//set fixed position in here, using LayoutParams or setTop/setRight etc. methods of View (API 11)
};
});
change:
so instead of ValueAnimator you can do something like this
int desiredHeightInPx = getResources().getDimensionPixelSize(R.dimen.expandedHeight);
//note those are pixels, not dp. you might set this as =200 or =250 like you have
ScaleAnimation animation = new ScaleAnimation(0, 0, 0, desiredHeightInPx/llUploadOptions.getMeasuredHeight(), Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
animation.setDuration(1000); //ms
llUploadOptions.startAnimation(animation);
following steps as above fillAfter
or set AnimationListener
and internally onAnimationEnd
set final LayoutParams.
remember that it ScaleAnimation
scales, it may be more appropriate to use RelativeLayout
Linear instead (which retells its children)
source to share