I am creating Countdown app. i finished all codes and its all working pretty fine but i am new to android animation. I need to apply below animation to my app. i tried use slide in/out but it is not working good i also tried few other animation but nothing is same as compared below animation.
once play button pressed a timer starts then once again pressed a pause button comes and a textView under pause icon which we have current countdown time. if again pressed the count start again. I am only looking for animation all other codes i have already done.
i have a ImageButton which shows icon each timer user press play/pause and TextView which shows countdown timer and another TextView which shows current timer when user press pause button.Is there anyway i can implement this animation to app?
So Any help would be appropriated as i am new to android animations. Thanks!
Here is xml:
<FrameLayout
android:layout_width="228dp"
android:layout_height="228dp"
android:layout_marginTop="7dp"
android:layout_marginLeft="7dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:id="#+id/circlea"
android:visibility="visible"
android:background="#drawable/circle">
<ImageButton
android:layout_width="142dp"
android:layout_height="142dp"
android:layout_marginTop="43dp"
android:layout_marginBottom="43dp"
android:layout_marginLeft="43dp"
android:id="#+id/play"
android:background="#000"
android:layout_marginRight="43dp"
android:src="#mipmap/icon"
android:visibility="visible" />
<TextView
android:layout_width="134dp"
android:layout_height="73dp"
android:text=""
android:textColor="#FFFFFF"
android:textSize="55sp"
android:layout_marginTop="78dp"
android:layout_marginStart="48dp"
android:id="#+id/countText"
android:fontFamily="sans-serif-light"
android:background="#000"
android:visibility="invisible" />
<TextView
android:layout_marginTop="180dp"
android:layout_marginLeft="90dp"
android:text=""
android:id="#+id/pusetext"
android:textSize="24sp"
android:textColor="#1EFFFFFF"
android:layout_width="61dp"
android:layout_height="32dp" />
</FrameLayout>
java:
//some code
super.onCreate(savedInstanceState);
play=(ImageButton)findViewById(R.id.play);
pausetext=(TextView) findViewById(R.id.pusetext);
CountText=(TextView)findViewById(R.id.countText);
play.OnClickListener startListener = new View.OnClickListener() {//first public void onClick( View v ){
play.setVisibility(View.INVISIBLE);
CountText.setVisibility(View.VISIBLE);
ObjectAnimator slideDownAnimTextView = ObjectAnimator.ofFloat(CountText, "translationY", -(CountText.getTop() + CountText.getHeight()), 0);
slideDownAnimTextView.start();
}
CountText.setOnClickListener
public void onClick( View v ){//pause click
play.setVisibility(View.VISIBLE);
ObjectAnimator slideDownAnimPlayButton = ObjectAnimator.ofFloat(play, "translationY", -(play.getTop() + play.getHeight()), 0);
ObjectAnimator scaleDownAnimTextViewX = ObjectAnimator.ofFloat(CountText, "scaleX", 1f, 0.5f);
ObjectAnimator scaleDownAnimTextViewY = ObjectAnimator.ofFloat(CountText, "scaleY", 1f, 0.5f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(1000);
animatorSet.playTogether(slideDownAnimPlayButton,scaleDownAnimTextViewX,scaleDownAnimTextViewY);
animatorSet.start();
}
play.setOnClickListener
public void onClick(View view) {resume click
play.setVisibility(View.INVISIBLE);
CountText.setVisibility(View.VISIBLE);
}
CountText.setOnClickListener(new View.OnClickListener() //pause click agine
#Override
public void onClick(View view) {
//some code
You can use the HTextView library to achieve the first part of the animations(showing the text).
Then, use ObjectAnimators to slide and scale the text down, and to slide the play button down (Use AnimatorSet to play them all together).
Here's a sample code (you should, of course, change the values according to your needs) -
ObjectAnimator slideDownAnimPlayButton = ObjectAnimator.ofFloat(play, "translationY", -(CountText.getTop()), 0);
ObjectAnimator slideDownAnimTextView = ObjectAnimator.ofFloat(CountText, "translationY",0, (CountText.getTop() ));
ObjectAnimator scaleDownAnimTextViewX = ObjectAnimator.ofFloat(CountText, "scaleX", 1f, 0.5f);
ObjectAnimator scaleDownAnimTextViewY = ObjectAnimator.ofFloat(CountText, "scaleY", 1f, 0.5f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(1000);
animatorSet.playTogether(slideDownAnimPlayButton,slideDownAnimTextView,scaleDownAnimTextViewX,scaleDownAnimTextViewY);
animatorSet.start();
Edit: Seeing your new code now, the problem with the first text animation is that you call it from onCreate(), so the View hasn't been drawn yet, meaning he does not have valid Height or Top parameters.
You can solve it by giving your animation a small delay, or using a ViewTreeObserver. See the following examples -
Starting your animation with a delay -
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
ObjectAnimator slideDownAnimTextView = ObjectAnimator.ofFloat(CountText, "translationY", -(CountText.getTop() + CountText.getHeight()), 0);
slideDownAnimTextView.start();
}
}, 300);
Or, perhaps the better way, use a ViewTreeObserver -
CountText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
CountText.getViewTreeObserver().removeOnGlobalLayoutListener(this);
ObjectAnimator slideDownAnimTextView = ObjectAnimator.ofFloat(CountText, "translationY", -(CountText.getTop() + CountText.getHeight()), 0);
slideDownAnimTextView.start();
}
});
Related
I created simple app with some animations in android. In my layout I have an ImageView with a sourceImage and a button on it. When I click the button, I want it move and resize in same time.
I used ObjectAnimator and ValueAnimator for create animations and play them together with animatorSet. My problem is that my button not move smoothly.
I checked several animation library like Transitions Everywhere and APIDemos. In these libraries when I set ImageBackground the view can't move smoothly
and all of them have my problem.
Can anyone help me to solve this problem?
my layout code:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageview"
android:fitsSystemWindows="true"
android:src="#drawable/image"
android:scaleType="fitXY" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frame">
<Button
android:layout_width="100dp"
android:layout_height="45dp"
android:id="#+id/btn_start"
android:layout_gravity="center_horizontal|bottom"
android:gravity="center_vertical|center_horizontal"
android:textAllCaps="false"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Start" />
// ....................
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
my animations code:
btn_start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ButtonAnimation();
}
});
private void ButtonAnimation() {
Animator moveButtonAnimY = ObjectAnimator.ofFloat(btn_start, "translationY", 0, 200)
.setDuration(500);
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(width_btn_start, width_btn_start * 2.0f);
valueAnimator.setDuration(500);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
btn_start.getLayoutParams().width = value.intValue();
btn_start.requestLayout();
}
});
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(moveButtonAnimY, valueAnimator);
animatorSet.start();
}
According to Wikipedia:
Animation is the process of making the illusion of motion and change by means of the rapid display of a sequence of static images that minimally differ from each other.
Therefore, animation is a pretty heavy task for the device to process, and the smoothness as you referred, depends upon the device configuration.
So, First check if the device have enough power to carry out that animation smoothly.
Secondly, Your code initializes animation every time the button is clicked, Instead you should initialize animation once, and use the instances of them every time you need to start the animation.
A better version of your code would be :
btn_start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ButtonAnimation();
}
});
Animator moveButtonAnimY = ObjectAnimator.ofFloat(btn_start,"translationY", 0, 200).setDuration(500);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(width_btn_start, width_btn_start * 2.0f);
valueAnimator.setDuration(500);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
btn_start.getLayoutParams().width = value.intValue();
btn_start.requestLayout();
}
});
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(moveButtonAnimY, valueAnimator);
private void ButtonAnimation() {
animatorSet.start();
}
I have Floating action menu and I use this library to make it 'com.github.clans:fab:1.6.1' Now I need change my icon when I click on it. I have some icon, and when I click on menu I need to transform it to another icon(icon plus). Is it possible?
This is my xml:
<com.github.clans.fab.FloatingActionMenu
android:id="#+id/menu3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
fab:menu_icon="#drawable/ic_float_cards"
android:layout_margin="16dp"
fab:menu_animationDelayPerItem="0"
fab:menu_colorNormal="#color/event_background"
fab:menu_colorPressed="#color/fab_colorPressed"
fab:menu_colorRipple="#color/fab_colorRipple"
fab:menu_labels_maxLines="2"
fab:menu_labels_ellipsize="end">
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_dial_fill"
fab:fab_label="Пополнить"
style="#style/MenuButtonsSmall.Green" />
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_dial_pay"
fab:fab_label="Оплатить"
style="#style/MenuButtonsSmall.Yellow" />
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_dial_outcome"
fab:fab_label="Перевести"
style="#style/MenuButtonsSmall.Red" />
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_dial_income"
fab:fab_label="Запрос перевода"
style="#style/MenuButtonsSmall.DarkPink" />
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_dial_send"
fab:fab_label="Сообщение"
style="#style/MenuButtonsSmall.Purple" />
</com.github.clans.fab.FloatingActionMenu>
At first icon is ic_float_cards, but when I click it should be isic_float_cross
If you have some ideas tell me please)
This does the job and will also revert to the original icon.
final FloatingActionMenu fab = (FloatingActionMenu) findViewById(R.id.menu3);
fab.setOnMenuToggleListener(new FloatingActionMenu.OnMenuToggleListener() {
#Override
public void onMenuToggle(boolean opened) {
int drawableId;
if (opened) {
drawableId = R.drawable.ic_float_cross;
} else {
drawableId = R.drawable.ic_float_cards;
}
Drawable drawable = getResources().getDrawable(drawableId);
fab.getMenuIconView().setImageDrawable(drawable);
}
});
There is a better solution which includes cross-fade animation between icon drawables. It can be found in the sample Clans' application here.
This is the code which does the job:
final FloatingActionMenu fabMenu = ...;
AnimatorSet set = new AnimatorSet();
View menuIconView = fabMenu.getMenuIconView();
ObjectAnimator scaleOutX = ObjectAnimator.ofFloat(menuIconView, "scaleX", 1.0f, 0.2f);
ObjectAnimator scaleOutY = ObjectAnimator.ofFloat(menuIconView, "scaleY", 1.0f, 0.2f);
ObjectAnimator scaleInX = ObjectAnimator.ofFloat(menuIconView, "scaleX", 0.2f, 1.0f);
ObjectAnimator scaleInY = ObjectAnimator.ofFloat(menuIconView, "scaleY", 0.2f, 1.0f);
scaleOutX.setDuration(50);
scaleOutY.setDuration(50);
scaleInX.setDuration(150);
scaleInY.setDuration(150);
scaleInX.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationStart(Animator animation) {
fabMenu.getMenuIconView().setImageResource(fabMenu.isOpened()
? R.drawable.ic_float_cross : R.drawable.ic_float_cards);
}
});
set.play(scaleOutX).with(scaleOutY);
set.play(scaleInX).with(scaleInY).after(scaleOutX);
set.setInterpolator(new OvershootInterpolator(2));
fabMenu.setIconToggleAnimatorSet(set);
I need to do some like ripple effect of Listview item background changing. I try to use ObjectAnimator like this:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(activity,
R.animator.animator_bkg);
set.setTarget(childLinear);
set.setInterpolator(new AccelerateInterpolator());
set.start();
R.animator.animator_bkg:
<objectAnimator
android:propertyName="backgroundColor"
android:duration="3000"
android:valueFrom="#color/white"
android:valueTo="#color/redTrans"
android:repeatCount="-1"
android:repeatMode="reverse"/>
It fluently changes a background (complete filling), but I need gradual filling of ListView item like ripple effect after touch the button.
I think, maybe I can use Canvas with overriding onDraw, but it's to hard for application and it can be some lags.
You can do it with a custom view and implement the circular transition in onDraw(), but it's complicated.
You can work around the complexity by using ViewAnimationUtils.createCircularReveal() on sub view. But the draw back is that it's only for API 21+.
In few words, your root layout of the cell has to be a FrameLayout or a RelativeLayout.
When the transition starts, you dynamically add 2 views under your cell with the start and the end color, then transition with the circular reveal between the 2. At the end of the transition, you just remove the 2 sub views to keep the view hierarchy a bit cleaner.
Here is the result :
In code :
Cell layout:
<FrameLayout
android:id="#+id/cell_root"
android:layout_width="match_parent"
android:layout_height="72dp">
<LinearLayout
android:id="#+id/cell_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"
android:background="#FF00FF">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is content"
android:textSize="14sp" />
</LinearLayout>
</FrameLayout>
Code that trigger the background transition :
private void changeBackgroundColor() {
final FrameLayout startingColorFrame = new FrameLayout(mCellRoot.getContext());
final FrameLayout endingColorFrame = new FrameLayout(mCellRoot.getContext());
startingColorFrame.setBackground(mCellContent.getBackground());
endingColorFrame.setBackground(mPendingColor);
mCellContent.setBackground(null);
endingColorFrame.setVisibility(View.GONE);
mCellRoot.addView(endingColorFrame, 0, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mCellRoot.addView(startingColorFrame, 0, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
int finalRadius = (int) Math.sqrt(mCellRoot.getWidth()*mCellRoot.getWidth() + mCellRoot.getHeight()*mCellRoot.getHeight());
final int sourceX = mCellRoot.getWidth() / 3;
final int sourceY = mCellRoot.getHeight() / 2;
// this is API 21 minimum. Add proper checks
final Animator circularReveal = ViewAnimationUtils.createCircularReveal(endingColorFrame, sourceX, sourceY, 0, finalRadius);
endingColorFrame.setVisibility(View.VISIBLE);
circularReveal.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(final Animator animation) {
super.onAnimationEnd(animation);
mStartButton.setEnabled(true);
mCellContent.setBackground(mPendingColor);
mPendingColor = startingColorFrame.getBackground();
mCellRoot.removeView(startingColorFrame);
mCellRoot.removeView(endingColorFrame);
}
});
// customize the animation here
circularReveal.setDuration(800);
circularReveal.setInterpolator(new AccelerateInterpolator());
circularReveal.start();
}
hi im wanting to know how to scale animate a logo and move its position?
i have an if statement that runs some checks and then when its done i want it to scale down an image view (logo) and move it up.
heres my layout
<?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:background="#drawable/bg_default" >
<ImageView
android:id="#+id/su_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="34dp"
android:src="#drawable/su_logo"
android:contentDescription="#string/cd_su_logo"/>
<ImageView
android:id="#+id/su_shirts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:src="#drawable/su_shirts"
android:contentDescription="#string/cd_su_shirts" />
</RelativeLayout>
heres my java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_initialsetup);
preChecks();
}
public void preChecks(){
//check for internet connection
//check version
String curVersion = getResources().getString(R.string.app_versionCode);
int curVer = Integer.parseInt(curVersion);
String LiveVersion = "100";
int liveVer = Integer.parseInt(LiveVersion);
if(curVer < liveVer) Log.v("setup", "There is a new version");
else {
//scale animation
}
}
You can do that by applying ScaleAnimation and TranslateAnimation together in AnimationSet
// Scaling
Animation scale = new ScaleAnimation(fromXscale, toXscale, fromYscale, toYscale, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
// 1 second duration
scale.setDuration(1000);
// Moving up
Animation slideUp = new TranslateAnimation(fromX, toX, fromY, toY);
// 1 second duration
slideUp.setDuration(1000);
// Animation set to join both scaling and moving
AnimationSet animSet = new AnimationSet(true);
animSet.setFillEnabled(true);
animSet.addAnimation(scale);
animSet.addAnimation(slideUp);
// Launching animation set
logo.startAnimation(animSet);
I have a relative layout with some button on it and I have created a rotation animation to rotate it
but when I rotate it the action of button does not work correctly, the action of button still save the old position of button before rotation
could any one please help me fixing this
<ImageButton
android:id="#+id/last20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="75dp"
android:background="#null"
android:src="#drawable/last20_selector"
android:onClick="last20OnClick"/>
super.onCreate(savedInstanceState);
setContentView(R.layout.wheel);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.wheelLayout);
RotateAnimation rotateAnim = new RotateAnimation(0, 45,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotateAnim.setDuration(1000);
rotateAnim.setRepeatCount(0);
rotateAnim.setFillAfter(true);
layout.startAnimation(rotateAnim);
}
public void last20OnClick(View view) {
System.out.println("last20OnClick");
}
Try to set attributes:
android:fillAfter="false"
android:fillBefore="false"
or in java:
rotateAnim.setFillAfter(false);
rotateAnim.setFillBefore(false);
as suggested in this question. It helped me.
Aslo, to preserve your animation rotate from -45 to 0 degrees.
Where in your code do you set the OnClickListener?
Try putting the listener in you onCreate method:
findViewById(R.id.last20).setOnClickListener(new OnClickListener() {
public abstract void onClick (View v) {
last20OnClick(v);
}
});
Hope it helps you!