I want to change my Relative layout's background every 10 seconds with fade in/fade out animation.
So I found
//Transitiondrawable
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);
But it supports only 2 Drawable and I want to add more
Is there any way to do this?
First implement MyAnim.java class as below:
public class MyAnim extends Animation {
private final RelativeLayout view;
private int targetBackGround;
public MyAnim(RelativeLayout view, int tagetBackGroundColor) {
this.view = view;
this.targetBackGround = tagetBackGroundColor;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
view.setBackgroundColor(targetBackGround);
}
public void setColor(int color) {
this.targetBackGround = color;
}
}
Then add below code to your activity and call that animateBackground() method wherever you want:
private MyAnim backgroundAnim;
private int i;
private void animateBackground(){
final RelativeLayout animLay = (RelativeLayout) findViewById(R.id.animLay);
final int colors[] = new int[]{Color.RED, Color.CYAN, Color.DKGRAY, Color.GREEN, Color.MAGENTA};
backgroundAnim = new MyAnim(animLay, colors[i]);
backgroundAnim.setDuration(1000);
animLay.startAnimation(backgroundAnim);
backgroundAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (i == colors.length - 1) {
i = 0;
} else {
i++;
}
backgroundAnim.setColor(colors[i]);
animLay.startAnimation(backgroundAnim);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
You can create your own loop, something like:
int delayBetweenAnimations = 10000;
for (int i = 0; i < yourImagesArray.length ; i++) {
int delay = i * delayBetweenAnimations;
yourImageview.postDelayed(new Runnable() {
#Override
public void run() {
//set your image and animation here
}
}, delay);
}
Another way is to use recursive animation:
#Override
public void onAnimationEnd(Animator animation) {
if(check_if_you_Still_want to_loop){
//rerun your animation
}
}
Related
I would like to start animation when view is long clicked.
The code is as follows.
public class Example_Dialog extends Dialog implements AnimationListener{
TextView view_Description1 = null;
View view_Button1 = null;
MessageCreateTask task;
public Example_Dialog( Context context , int theme ){
super( context , theme );
setContentView(R.layout.infomation_dialog);
view_Button1 = findViewById(R.id.common_dialog_button_1);
view_Description1 = (TextView)findViewById(R.id.common_dialog_description_1);
view_Description1.setHeight(0);
view_Button1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
task = new MessageCreateTask(view_Description1);
task.execute();
}
});
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
class MessageCreateTask extends AsyncTask<Void, Void, String> {
TextView textView;
String messageOutput;
int totalLineNum;
public MessageCreateTask(TextView textView) {
this.textView = textView;
messageOutput = "";
totalLineNum = 0;
}
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(Void... params) {
for( int i= 0 ; i< 10 ; i++ ){
messageOutput += "a" + "<br>";
totalLineNum++;
}
return messageOutput;
}
#Override
protected void onPostExecute(String message) {
int dialogWidth = 838;
int dialogHeight = 26*totalLineNum;
textView.setWidth( dialogWidth );
textView.setText(Html.fromHtml(message));
HeightAnimation hanime_open = new HeightAnimation(textView , 0 , dialogHeight );
hanime_open = new HeightAnimation(textView , 0 , dialogHeight );
hanime_open.setDuration(300);
textView.startAnimation(hanime_open);
}
}
}
public class HeightAnimation extends Animation {
int targetHeight;
int startHeight;
TextView textView;
public HeightAnimation(TextView textView,int startHeight, int targetHeight) {
this.textView = textView;
this.targetHeight = targetHeight;
this.startHeight = startHeight;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newHeight = (int)(startHeight + (targetHeight - startHeight)*interpolatedTime);
textView.setHeight(newHeight);
if( (startHeight != 0) && (newHeight == 0) ){
textView.setVisibility(View.GONE);
}
}
#Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, ((View)textView.getParent()).getWidth(), parentHeight);
}
}
The animation was not started with the above code, but it was started by replacing onclick with onlongclick like as below.
view_Button1.setOnLongClickListener(new View.OnLongClickListener(){
public boolean onLongClick(View v){
task = new MessageCreateTask(view_Description1);
task.execute();
return true;
}
});
I want to know the reason why animation does not start in case of onclick.
The reason why it is not working with onClickListener() is, that the view hasnĀ“t the Focus. So you Need to press the button twice or you have to use a onlongClickListener(). To make the view clickable the first time, do the following:
enable focusable in touch mode, wether in your XML layout as attribute:
android:focusableInTouchMode="true"
or programmatically after you have initialized the button:
view_button1.setFocusableInTouchMode(true);
Then you can set the Focus to the view simply:
view_button1.requestFocus();
I have two RelativeLayouts which contains one TextView each.
Basically the top layout serves as a "button". When clicked, the other layout will have its animation played (expanding downwards).
In this situation, to which layout should I add setLayoutAnimationListener() so that the top layout will not be able to be clicked in method onAnimationStart() and can be clicked in method onAnimationEnd()?
Here are the layouts I meant :
<RelativeLayout
android:id="#+id/activity_signup_step_one_dropdownTitleWrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/activity_signup_step_one_orangEmailWrapper"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp">
<TextView
android:id="#+id/activity_signup_step_one_dropdownTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/stepOneTitle"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/activity_signup_step_one_dropdownTextWrapper"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/activity_signup_step_one_dropdownTitleWrapper">
<TextView
android:id="#+id/activity_signup_step_one_dropdownText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/stepOneMessage"/>
</RelativeLayout>
The java class
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup_step_one);
...
RelativeLayout dropDownTitle = (RelativeLayout)findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper);
RelativeLayout dropDownMessage = (RelativeLayout)findViewById(R.id.activity_signup_step_one_dropdownTextWrapper);
dropDownMessage.setVisibility(View.GONE);
dropDownTitle.setOnClickListener(translateHandler);
dropDownMessage.setLayoutAnimationListener(new Animation.AnimationListener() {
//RelativeLayout touchDisabler = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper_filler);
RelativeLayout dropDownTitle = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper);
#Override
public void onAnimationStart(Animation animation) {
//touchDisabler.setClickable(true);
Log.d("onStart", "Start");
dropDownTitle.setClickable(false);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
//WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationEnd(Animation animation) {
//touchDisabler.setClickable(false);
Log.d("onEnd", "End");
dropDownTitle.setClickable(true);
//getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
//touchDisabler.setClickable(true);
}
});
int height;
View.OnClickListener translateHandler = new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout dropDownMessage = (RelativeLayout)findViewById(R.id.activity_signup_step_one_dropdownTextWrapper);
TextView testText = (TextView)findViewById(R.id.activity_signup_step_one_dropdownText);
if(dropDownMessage.getVisibility() == View.VISIBLE){
MyCustomAnimation a = new MyCustomAnimation(dropDownMessage, 350, MyCustomAnimation.COLLAPSE);
height = a.getHeight();
testText.setText(getResources().getString(R.string.stepOneMessage));
dropDownMessage.startAnimation(a);
}else{
MyCustomAnimation a = new MyCustomAnimation(dropDownMessage, 350, MyCustomAnimation.EXPAND);
a.setHeight(height);
testText.setText(getResources().getString(R.string.stepOneMessage));
dropDownMessage.startAnimation(a);
}
}
};
Here's the animation class which might be useful
public class MyCustomAnimation extends Animation {
public final static int COLLAPSE = 1;
public final static int EXPAND = 0;
private View mView;
private int mEndHeight;
private int mType;
private RelativeLayout.LayoutParams mLayoutParams;
public MyCustomAnimation(View view, int duration, int type) {
setDuration(duration);
mView = view;
mEndHeight = mView.getHeight();
mLayoutParams = ((RelativeLayout.LayoutParams) view.getLayoutParams());
mType = type;
if(mType == EXPAND) {
mLayoutParams.height = 0;
} else {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
}
view.setVisibility(View.VISIBLE);
}
public int getHeight(){
return mView.getHeight();
}
public void setHeight(int height){
mEndHeight = height;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
if(mType == EXPAND) {
mLayoutParams.height = (int)(mEndHeight * interpolatedTime);
} else {
mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime));
}
mView.requestLayout();
} else {
if(mType == EXPAND) {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
mView.requestLayout();
}else{
mView.setVisibility(View.GONE);
}
}
}
}
final RelativeLayout dropDownTitle = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper);
dropDownMessage.setLayoutAnimationListener(new Animation.AnimationListener() {
//RelativeLayout touchDisabler = (RelativeLayout) findViewById(R.id.activity_signup_step_one_dropdownTitleWrapper_filler);
#Override
public void onAnimationStart(Animation animation) {
//touchDisabler.setClickable(true);
Log.d("onStart", "Start");
dropDownTitle.setClickable(false);
dropDownMessage.setVisibility(View.GONE);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
//WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationEnd(Animation animation) {
//touchDisabler.setClickable(false);
Log.d("onEnd", "End");
dropDownTitle.setClickable(true);
//getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
//touchDisabler.setClickable(true);
}
});
Try to instantiate your RelativeLayout outside of your anonymous inner class (AnimationListener) - and of course declare it final.
I would like to apply the same alphaanimation for button A, B and C, and therefore implemented the following codes:
public void onCreate(Bundle savedInstanceState)
{
animation = new MutableAlphaAnimation();
animation.setAnimationListener(this);
btn_A.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
animation.setResetBlocked(true);
btn_A.setAnimation(animation);
animation.setResetBlocked(false);
animation.start(0.0f, 0.5f, FADE_IN_DURATION);
btn_A.invalidate();
}
});
}
public class MutableAlphaAnimation extends Animation
{
private float mFromAlpha;
private float mToAlpha;
private boolean resetBlocked;
public MutableAlphaAnimation()
{
}
public void start(float fromAlpha, float toAlpha, long duration)
{
mFromAlpha = fromAlpha;
mToAlpha = toAlpha;
setDuration(duration);
setStartTime(START_ON_FIRST_FRAME);
}
public void setResetBlocked(boolean resetBlocked)
{
this.resetBlocked = resetBlocked;
}
#Override
public void reset()
{
if (! resetBlocked) super.reset();
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
#Override
public boolean willChangeTransformationMatrix()
{
return false;
}
#Override
public boolean willChangeBounds()
{
return false;
}
}
Question:
btn_A, B and C are implemented with the same setOnClickListener. However, when they are pressed, nothing happen. Why? How can the above be modified?
Thanks!
You aren't applying your transformation to btn_home. Yes you set the it to the animation, but your animation class never touches btn_home. Your t.setAlpha... should really be btn_home.setAlpha..., so pass in the view using the constructor and then you can use it with any view in the future.
I'm currently using Nine Old Androids to animate a RelativeLayout like a slider menu, which slides down form the top. I've tried in many ways, Can someone make a suggestion?
Here is the animation code:
private OnClickListener slideClick = new OnClickListener(){
#Override
public void onClick(View v) {
slideGroups.bringToFront();
if(!mPulledDown) {
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", slideGroups.getHeight()-80);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowup);
if(Application.getAndroidAPILevel() < 11) {
// only if pre 3.0 (api level 11)
Toast.makeText(FriendsActivity.this, String.format("api level %s",
Application.getAndroidAPILevel()), Toast.LENGTH_SHORT).show();
//RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) slideGroups.getLayoutParams();
// clear animation to prevent flicker
slideGroups.clearAnimation();
// set new "real" position of wrapper
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, slideGroups.getWidth());
//lp.addRule(RelativeLayout.BELOW, R.id.branchFinderIncludeHeader);
slideGroups.setLayoutParams(lp);
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
else
{
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", 0);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowdown);
if(Application.getAndroidAPILevel() < 11) {
// only if pre 3.0 (api level 11)
Toast.makeText(FriendsActivity.this, String.format("api level %s",
Application.getAndroidAPILevel()), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
mPulledDown = !mPulledDown;
}
};
I just need something to work with sdk level 4 and newer. Currently, touching/tapping passes that event to the list underneath the slider when expanded. Please let me know if any other information is needed. slideGroups is the RelativeLayout. arrow is an imageview. groupsButton is a LinearLayout with text and an image button. groupsButton should be clickable; that's what expands and is supposed to collapse it.
Thanks in advance.
A few people have contributed by editing my question with solutions. I'd like to give them credit, but can't upvote an edit. For posterity, here is the solution that works for me.
int originalMarginLeft = 0;
int originalMarginTop = 0;
int originalMarginRight = 0;
int originalMarginBottom = 0;
int originalLeft = 0;
int originalTop = 0;
int originalRight = 0;
int originalBottom = 0;
int originalX = 0;
int originalY = 0;
int originalHeight = 0;
private OnClickListener slideClick = new OnClickListener(){
#Override
public void onClick(View v) {
slideGroups.bringToFront();
if(originalMarginLeft == 0) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) slideGroups.getLayoutParams();
originalMarginLeft = params.leftMargin;
originalMarginTop = params.topMargin;
originalMarginRight = params.rightMargin;
originalMarginBottom = params.bottomMargin;
originalLeft = slideGroups.getLeft();
originalTop = slideGroups.getTop();
originalRight = slideGroups.getRight();
originalBottom = slideGroups.getBottom();
originalHeight = params.height;
}
if(!mPulledDown) {
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", originalHeight);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowup);
if(Application.getAndroidAPILevel() < 11) {
slideGroups.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(slideGroups.getWidth(), slideGroups.getHeight());
lp.leftMargin = originalMarginLeft;
lp.rightMargin = originalMarginRight;
slideGroups.setLayoutParams(lp);
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
else
{
ObjectAnimator oa = ObjectAnimator.ofFloat(slideGroups, "translationY", -originalHeight+60);
oa.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {}
#Override
public void onAnimationRepeat(Animator arg0) {}
#Override
public void onAnimationEnd(Animator arg0) {
arrow.setImageResource(R.drawable.arrowdown);
if(Application.getAndroidAPILevel() < 11) {
slideGroups.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(slideGroups.getWidth(), slideGroups.getHeight());
lp.leftMargin = originalMarginLeft;
lp.rightMargin = originalMarginRight;
lp.topMargin = originalMarginTop;
lp.bottomMargin = originalMarginBottom;
slideGroups.setLayoutParams(lp);
}
}
#Override
public void onAnimationCancel(Animator arg0) {}
});
oa.start();
}
mPulledDown = !mPulledDown;
}
};
I want to play one animation with multiple views in android.
This is the simplified example of code.
This code works incorrectly.
Every startAnimation() call, affects all previously animated views
Please tell me, why it doesn't works and how to make it properly.
public SomeClass() {
private int currentViewID = 0;
private View[] views = { view1, view2, view3, view4, view5 }
private Animation anim = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_out);
public SomeClass() {
this.anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
if (SomeClass.this.currentViewID != SomeClass.this.views.length) SomeClass.this.hideNextView();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
this.hideNextView();
}
private void hideNextView() {
this.views[this.currentViewID++].startAnimation(this.anim);
}
}
If you don't want to deal with many Animations in your class (one for each View) you could do things locally:
private int currentViewID = 0;
private View[] views = { view1, view2, view3, view4, view5 }
public SomeClass() {
this.hideNextView();
}
private void hideNextView() {
final Animation anim = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_out);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
if (SomeClass.this.currentViewID != SomeClass.this.views.length) SomeClass.this.hideNextView();
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationStart(Animation animation) {}
});
this.views[this.currentViewID++].startAnimation(anim);
}