android: how to visible portion of a view with animation? - android

I have a invisible View behind of another View. I want to make this view visible with a translate animation and show only a part of the right side view.
like this:
I don't want to use 9 patch image and resize that.
this animation named "peek in"" in MS-PowerPoint.

You could try something like this
1) create a drawable resource rectangle_curved.xml as shown below
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="#FFFFFF"/>
<corners
android:bottomRightRadius="350dp"
android:bottomLeftRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="350dp"/>
<stroke android:color="#50000000" android:width="2dp"/>
</shape>
2) Set this as the background of the view which is expanding and collapsing. Here I have used a Framelayout which is expanding and collapsing
<FrameLayout
android:id="#+id/shape"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:background="#drawable/rectangle_curved"/>
3) Create a class to handle the expand/collapse animation as follows
public class ResizeAnimation extends Animation {
private int mWidth;
private int mInitialWidth;
private View mView;
public ResizeAnimation(View view, int width) {
mView = view;
mWidth = width;
mInitialWidth = view.getWidth();
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newWidth = mInitialWidth + (int) ((mWidth - mInitialWidth) * interpolatedTime);
mView.getLayoutParams().width = newWidth;
mView.requestLayout();
}
#Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
4) Finally, use it like this. Create a function to handle animation as follows
private void animate(View shapeView, boolean isExpand) {
int width = isExpand ? 500 : 0; // 500 is the max width in pixels , you ca change it
ResizeAnimation anim = new ResizeAnimation(shapeView, width);
anim.setDuration(500);
shape.startAnimation(anim);
}
and call this function as follows
for expand animation : animate(myBackgroundView, true)
for collapse animation : animate(myBackgroundView, false)
EDIT:
in this line of step 4: int width = isExpand ? 500 : 0; use 1 instead of 0.
0 not work properly. I don't know why.
private void animate(View view, boolean isExpand) {
int width = isExpand ? 200 : 1; // 200 is the max width in pixels.
//use a factor for same width on all screen size.
DisplayMetrics metrics = getResources().getDisplayMetrics();
int factor =(int) metrics.density;
ResizeAnimation anim = new ResizeAnimation(view, width * factor);
anim.setDuration(500);
view.startAnimation(anim);
}

Related

more button between two recycler view

I have two recycler views in one screen and in between of them, there is one more button like this.
I want to update the height of recycler view of the upper one to MATCH PARENT with animation, So I had tried this.
binding.moreLl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ValueAnimator anim = ValueAnimator.ofInt();
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = binding.fragmentWalletRv.getLayoutParams();
layoutParams.height = val;
binding.fragmentWalletRv.setLayoutParams(layoutParams);
}
});
anim.setDuration(500);
anim.start();
}
});
But unfortunately i cant get the expected result. So please guide me how i can do that thing.
Thanks in advance.
If you just want to have an animation when layout changes, no need to use a custom animation.
Try adding default layout change animation by enabling
android:animateLayoutChanges="true"
to the parent layout in xml.
On your more button click, only change the LayoutParams of the Recyclerview.
To change the speed of animation
LinearLayout layout = mContentView.findViewById(R.id.parent_layout);
LayoutTransition lt = layout.getLayoutTransition();
lt.setDuration(2000);
public class SlideAnimation extends Animation {
int mFromHeight;
int mToHeight;
View mView;
public SlideAnimation(View view, int fromHeight, int toHeight) {
this.mView = view;
this.mFromHeight = fromHeight;
this.mToHeight = toHeight;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
int newHeight;
if (mView.getHeight() != mToHeight) {
newHeight = (int) (mFromHeight + ((mToHeight - mFromHeight) * interpolatedTime));
mView.getLayoutParams().height = newHeight;
mView.requestLayout();
}
}
#Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
Use above animation like below
rv1 = findViewById(R.id.rv1);
Animation animation = new SlideAnimation(rv1, rv1.getHeight(), 500);
animation.setInterpolator(new AccelerateInterpolator());
animation.setDuration(500);
rv1.setAnimation(animation);
rv1.startAnimation(animation);

Circular reveal transition for new activity

As per https://developer.android.com/training/material/animations.html
The ViewAnimationUtils.createCircularReveal() method enables you to
animate a clipping circle to reveal or hide a view.
To reveal a previously invisible view using this effect:
// previously invisible view
View myView = findViewById(R.id.my_view);
// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;
// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();
This is meant to reveal a view. How can I use this to circularly reveal an entire activity, without any shared elements?
Specifically, I'd like my searchActivity to circularly reveal from the search action button in the toolbar.
After looking for a solution for half a day without a result, I came up with an own implementation. I'm using a transparent activity with a matching root layout.
The root layout is a view which can then be revealed with createCircularReveal().
My code looks like this:
Theme Definition in styles.xml
<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
Activity Definition in AndroidManifest.xml
<activity
android:name=".ui.CircularRevealActivity"
android:theme="#style/Theme.Transparent"
android:launchMode="singleTask"
/>
then I declared a layout for my activity (I've chosen DrawerLayout, so that I can have a NavDrawer. Every layout should work here.)
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/honey_melon"
>
<!-- Insert your actual layout here -->
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
Important is the FrameLayout with the id root_layout. This view will be revealed in the activity.
Finally I implemented CircularRevealActivity and overwrote onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.do_not_move, R.anim.do_not_move);
setContentView(R.layout.activity_reveal_circular);
if (savedInstanceState == null) {
rootLayout.setVisibility(View.INVISIBLE);
ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
circularRevealActivity();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
}
}
}
It was important to put circularRevealActivity() into a OnGlobalLayoutListener, because the view needs to be drawn for the animation.
circularRevealActivity() looks like Ishaan's proposal:
private void circularRevealActivity() {
int cx = rootLayout.getWidth() / 2;
int cy = rootLayout.getHeight() / 2;
float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight());
// create the animator for this view (the start radius is zero)
Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, 0, finalRadius);
circularReveal.setDuration(1000);
// make the view visible and start the animation
rootLayout.setVisibility(View.VISIBLE);
circularReveal.start();
}
Edit 1
The definition for R.anim.do_not_move was added. However, it should work without that line too, if your design does not specify default transitions for activities. Let me know
R.anim.do_not_move:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="0"
android:duration="#android:integer/config_mediumAnimTime"
/>
</set>
If you want to reverse the circular reveal on leaving activity, use the following modification to onBackPressed().
#Override
public void onBackPressed() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int cx = rootLayout.getWidth();
int cy = 0;
float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight());
Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, finalRadius, 0);
circularReveal.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationEnd(Animator animator) {
rootLayout.setVisibility(View.INVISIBLE);
finish();
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
circularReveal.setDuration(400);
circularReveal.start();
}else{
super.onBackPressed();
}
}
I think you can use ActivityOptionsCompat.makeClipRevealAnimation .
[https://developer.android.com/reference/android/support/v4/app/ActivityOptionsCompat.html#makeClipRevealAnimation(android.view.View, int, int, int, int)](https://developer.android.com/reference/android/support/v4/app/ActivityOptionsCompat.html#makeClipRevealAnimation(android.view.View, int, int, int, int))
To reverse the CircularReveal animation swap the startRadius and endRadius arguments. Also you will need to setup an AnimatorListenerand in the onAnimationEnd() callback method is where you can call finishAfterTransition(). This is for when you press the up navigation or click on the back button.
ou have to draw the circle view, and after that you should create an animation to it.
Creating the circle view:
public class Circle extends View {
private static final int START_ANGLE_POINT = 90;
private final Paint paint;
private final RectF rect;
private float angle;
public Circle(Context context, AttributeSet attrs) {
super(context, attrs);
final int strokeWidth = 40;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(strokeWidth);
//Circle color
paint.setColor(Color.RED);
//size 200x200 example
rect = new RectF(strokeWidth, strokeWidth, 200 + strokeWidth, 200 + strokeWidth);
//Initial Angle (optional, it can be zero)
angle = 120;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint);
}
public float getAngle() {
return angle;
}
public void setAngle(float angle) {
this.angle = angle;
}
}
Creating the animation class to set the new angle:
public class CircleAngleAnimation extends Animation {
private Circle circle;
private float oldAngle;
private float newAngle;
public CircleAngleAnimation(Circle circle, int newAngle) {
this.oldAngle = circle.getAngle();
this.newAngle = newAngle;
this.circle = circle;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
float angle = oldAngle + ((newAngle - oldAngle) * interpolatedTime);
circle.setAngle(angle);
circle.requestLayout();
}
}
Put circle into your layout:
<com.package.Circle
android:id="#+id/circle"
android:layout_width="300dp"
android:layout_height="300dp" />
And finally starting the animation:
Circle circle = (Circle) findViewById(R.id.circle);
CircleAngleAnimation animation = new CircleAngleAnimation(circle, 240);
animation.setDuration(1000);
circle.startAnimation(animation);

Dynamic Animation - Android

I currently have a button that when clicked an animation begins that shows a LinearLayout above the button. The LinearLayout is directly above it. In the xml file the LinearLayouts visibility is set to GONE. So when the button is clicked the visibility is set to VISIBLE. Then the animation begins. The animation is a slidedown animation. Everything works perfectly. But When the button is clicked the button jumps to the bottom of where the LinearLayout ends. Even though the LinearLayout is still going through the animation. How can I make the button move with the LinearLayout animation? I want everything to be a smooth transition. But the button jumps and it doesn't look very smooth.
LInearLayout Animation
<?xml version="1.0" encoding="utf-8"?>
<!-- slide down -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="0.0"
android:interpolator="#android:anim/linear_interpolator"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
I just ran into a very similar situation today.
I used a custom animation that re sizes the view.
The required height is measured and saved. Initially the height is set to 0 and it grows as the animation goes on. Finally it reaches the measured height and then it is set to wrap content as it was originally.
public static void expand(final View v) {
v.measure(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LayoutParams.WRAP_CONTENT
: (int)(targetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
v should be the LinearLayout you would like to animate.
You can choose a fixed time duration if you preffer.
source: https://stackoverflow.com/a/13381228/1646326
Use custom animation, it's very easy you can change whatever you want in applytransformation,
interpolatedTime - this is current position like in % from start to end animation (and has float value from 0 to 1, so here using this interpolatedTime you can iterate anything you can imagine) ;)
static class HeightAnimation extends Animation{
private View view;
private int mViewHeightFrom;
private int mViewHeightTo;
public HeightAnimation(View view, int heightFrom, int heightTo){
this.view = view;
this.mViewHeightFrom = heightFrom;
this.mViewHeightTo = heightTo;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int)((mViewHeightTo - mViewHeightFrom)*interpolatedTime+0.5));
view.setLayoutParams(params);
}
#Override
public boolean willChangeBounds() {
return true;
}
#Override
public boolean isFillEnabled() {
return true;
}
}
and the usage:
public static void applyAnimationHeightTransformation(Context context, View view, int viewHeightFrom, int viewHeightTo, int duration, int animationOffsetMilisec){
HeightAnimation anim = new HeightAnimation(view, viewHeightFrom, viewHeightTo);
anim.setStartOffset(animationOffsetMilisec);
anim.setDuration(duration);
//anim.setInterpolator(new OvershootInterpolator()); // here interpolators can be used
if(view != null) {
view.setAnimation(anim);
view.startAnimation(anim);
}
}
for height to make easier using - use values in dp via transform to pixels:
public static int dpToPx(int dp) {
return (int)(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, YourApplication.getMainContext().getResources().getDisplayMetrics()));
}

In android how to make a image grow from one point using animation?

In android how to make a image grow from one point using animation?
I mean to say is...i have a button ..and i want is when i click on that button my image must grow(ascending order) to grow bigger and bigger from that point ...and when again i click on that button again it must collapse gowing smaller and smaller to end at that point
Can any anybody help me in doing this using android animation?
i'm new to android
This can be achieved using View Animation utility. This scales the image from 100% to 140% for 1 sec
Place the following file in res/anim/scale.xml
<?xml version="1.0" encoding="utf-8"?>
<set android:shareInterpolator="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="1000" />
</set>
Java code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final View view = findViewById(R.id.imageView1);
final Animation anim = AnimationUtils.loadAnimation(this, R.anim.scale);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
view.startAnimation(anim);
}
});
}
I would suggest you look at this SO post:
Android: Expand/collapse animation
public class DropDownAnim extends Animation {
int targetHeight;
View view;
boolean down;
public DropDownAnim(View view, int targetHeight, boolean down) {
this.view = view;
this.targetHeight = targetHeight;
this.down = down;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newHeight;
if (down) {
newHeight = (int) (targetHeight * interpolatedTime);
} else {
newHeight = (int) (targetHeight * (1 - interpolatedTime));
}
view.getLayoutParams().height = newHeight;
view.requestLayout();
}
#Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
You would have to use that as an example as you want to apply it to your button.
Starting with Android 3.0, the preferred way of animating views is to
use the android.animation package APIs.These Animator-based classes change actual properties of the View object, ....
Or you can use a ViewPropertyAnimator for simple things - an image button that grows over a period of 1000ms to 1.4 x its size:
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imageButton.animate().
scaleX(1.4f).
scaleY(1.4f).
setDuration(1000).start();
}
});

Android 2.3: Animating a View?

How can you change the coordinates of a view while its animating? For instance, if I'm doing a translation of a View on the screen from left to right, I want the View to push everything to the right of it as its moving?
public Animation expandHiddenPanel(final View v, final boolean expand) {
panelExpanded = expand;
v.measure(MeasureSpec.makeMeasureSpec(200, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
final int initialWidth = v.getMeasuredWidth();
Log.i("test", "initialWidth = " + initialWidth);
v.getLayoutParams().width = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newWidth;
if (expand) {
newWidth = (int)(initialWidth * interpolatedTime);
Log.i("test", "new Width = " + newWidth);
}
else {
newWidth = (int)(initialWidth * (1 - interpolatedTime));
Log.i("test", "new Width = " + newWidth);
}
v.getLayoutParams().width = newWidth;
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setInterpolator(new AccelerateInterpolator());
a.setDuration(2500);
a.setFillAfter(true);
v.startAnimation(a);
return a;
}
I fixed this by overlaying the main layout over my panel, placing the button in the upper left hand corner of my main layout, and changing the code i posted above to pad the left margin of my main layout to reveal the panel.
To get the sliding drawer effect, I changed the panel's visibility and applied a translate animation that ran for the same duration and used the same interpolator.

Categories

Resources