I have the following code, after creating ~400 ImageView instance (by calling updateUI(NewImage) ~400 times) the newly created ImageView animation would be laggy, the more time elapsed the more laggy they become. I think after anImageView animation is done, i must destroy them to avoid being laggy. any idea?
public void updateUI(final Bitmap bitmap)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
final ImageView tmp = new ImageView(getApplicationContext());
tmp.setImageBitmap(bitmap);
tmp.setY(AT_THE_BOTTON_OF_ACTIVITY);
rv.addView(tmp); add the ImageView to the Relalayout
tmp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//disappear the imageView
ImageView t=imgs.get(id);
ObjectAnimator opacity = ObjectAnimator.ofFloat(tmp(The ImageView), "alpha", 0.0f);
opacity.setDuration(200);
opacity.start();
}
});
ObjectAnimator anim2 = ObjectAnimator.ofFloat(tmp, "y", 0);
anim2.setDuration(5000);
anim2.setInterpolator(new LinearInterpolator());
anim2.start();
}
});
}
Related
I'm quite new to Android Studio, and I would like to animate multiple images at the same time, over multiple coordinates.
Let's say I would like to move image A from 0/0 to 100/100, and then to 200/200; at the same time (eg. by the click of a button), image B shall be moved from 0/100 to 100/100, and then to 200/100. All with simple translations.
(As a plus, I would like to be able to set the duration of the movements independently.)
When the animations have finished, there should be an event (somthing like OnAnimationFinish?) to trigger other things, like enabling the start button again.
What would be the most effective way to do this? I know there is an AnimationSet in Android to store multiple animations, but I don't know if this is helpful here.
Thanks in advance!
You can use ObjectAnimator with AnimatorSet to play multiple animations simultaneously with proper listeners.
For example():
val imageXAnimator = ObjectAnimator.ofFloat(imageView, "translationX", translateX)
val imageYAnimator = ObjectAnimator.ofFloat(imageView, "translationY", translateY)
val imageAlphaAnimator = ObjectAnimator.ofFloat(imageView, "alpha", if (reverse) 0F else 1F)
val animationSet = AnimatorSet()
animationSet.playTogether(
imageXAnimator,
imageYAnimator,
imageAlphaAnimator)
animationSet.interpolator = DecelerateInterpolator()
animationSet.duration = 1000
animationSet.addListener(
onStart = {
//When animation is started
},
onEnd = {
//When animation finishes
}
)
animationSet.start()
Or a simple extension in kotlin which can be called on a specific View:
inline fun View.animateTranslationY(translationY: Float, duration: Long = 1000, startDelay: Long = 0) {
val translationYAnimator = ObjectAnimator.ofFloat(this, "translationY", translationY)
translationYAnimator.duration = duration
translationYAnimator.startDelay = startDelay
translationYAnimator.interpolator = LinearInterpolator()
translationYAnimator.addAnimatorListener(
onStart = { },
onEnd = { }
)
translationYAnimator.start()
}
You can use the "View.animate()" method that allow you to access to its sub-methods and events to manage all these stuff. You just have to call "animate()" on a View (TextView, ImageView, EditBox, etc..) and then call its sub-methods to decide what kind of animation to perform: motion, rotation, changing transparency, etc... For each animation you can set a listener that will be called at Start and/or at the End of animation.
Consider these two methods for both views
private void animateFirstView(final ImageView first, long durationFirst, final long durationSecond) {
first.setTranslationX(0);
first.setTranslationY(0);
first.animate().translationX(100).translationY(100).setDuration(durationFirst).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
first.animate().translationY(200).translationX(200).setDuration(durationSecond).setListener(null).setInterpolator(new LinearInterpolator()).start();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}).setInterpolator(new LinearInterpolator()).start();
}
private void animateSecondView(final ImageView second, long durationFirst, final long durationSecond) {
second.setTranslationX(0);
second.setTranslationY(100);
second.animate().translationX(100).translationY(100).setDuration(durationFirst).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
second.animate().translationY(200).translationX(100).setDuration(durationSecond).setListener(null).setInterpolator(new LinearInterpolator()).start();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}).setInterpolator(new LinearInterpolator()).start();
}
You can do this:
private void playAnimation(final View view, final int endRangeY) {
view.animate().translationY(endRangeY) //endRangeY where you want to end the animation
.alpha(0.0f)
.setDuration(3000)
.setListener(new AnimatorListenerAdapter() {
#Override public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
}
i want to increase the rotation speed.How can I increase the rotation speed of the ImageView in this code ??anyone please help me.I need help with this code. Thanks in advance.
public class MainActivity extends Activity {
ImageView img_one;
Button btn_one;
Random r;
int angle;
boolean restart=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img_one = (ImageView) findViewById(R.id.imageView_ring);
r=new Random();
btn_one = (Button) findViewById(R.id.btn_1);
btn_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (restart){
angle=angle & 360;
angle=r.nextInt()+360;
RotateAnimation rotate=new RotateAnimation(angle,360,RotateAnimation.RELATIVE_TO_SELF,0.5f,
RotateAnimation.RELATIVE_TO_SELF,0.5f);
rotate.setFillAfter(true);
rotate.setDuration(50);
rotate.setInterpolator(new AccelerateDecelerateInterpolator());
img_one.startAnimation(rotate);
restart=false;
}else {
angle=r.nextInt()+360;
RotateAnimation rotate=new RotateAnimation(0,angle,RotateAnimation.RELATIVE_TO_SELF,0.5f,
RotateAnimation.RELATIVE_TO_SELF,0.5f);
rotate.setFillAfter(true);
rotate.setDuration(50);
rotate.setInterpolator(new AccelerateDecelerateInterpolator());
img_one.startAnimation(rotate);
restart=true;
}
}
});
}
}
If you want to rotate faster, you need to lower the duration of the animation. Currently you have it set to last for 50 milliseconds:
rotate.setDuration(50);
but you can set the duration to whatever you need to achieve your desired effect.
I have developed an app in which I have a textview whose text keeps scrolling automatically. I also have an imageview whose image keeps changing automatically after every four seconds. To accomplish this I have created a new runnable having 4 seconds time. Suppose there are 5 images which gets displayed. The problem is every time a new image is loaded in imageview the text of textview gets reset and it starts scrolling from beginning and this happens only for the first iteration of all the images. After all images are displayed once then from the next iteration onwards the textview starts behaving properly and the text doesn't resets. I don't know what is the problem. Here is the code
//In onCreate
headlinesText = (TextView) findViewById(R.id.text_news);
headlinesText.setSelected(true);
//This is a separate method
public void settingAds() {
myRef.child("Advertisements").addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
imageUrl.clear();
for (com.google.firebase.database.DataSnapshot eachAdUrl : dataSnapshot.child("Adurls").getChildren()) {
imageUrl.add(String.valueOf(eachAdUrl.getValue()));
}
headlineFromFirebase = String.valueOf(dataSnapshot.child("News").getValue());
adTimer = (long) dataSnapshot.child("Time").getValue();
headlinesText.setText(headlineFromFirebase);
/*headlinesText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, NewsList.class));
}
});*/
//Randomly shuffling the array list
Collections.shuffle(imageUrl);
for(int i=0;i<imageUrl.size();i++) {
Picasso.with(MainActivity.this)
.load(imageUrl.get(i))
.fetch();
}
//runnable code was here
if(handler != null) {
handler.removeCallbacks(runnable);
}
handler = new Handler();
runnable = new Runnable() {
int imageCounter=0;
public void run() {
Picasso.with(MainActivity.this)
.load(imageUrl.get(imageCounter))
.fit()
.centerCrop()
.into(mAdsView);
imageCounter++;
if (imageCounter > imageUrl.size()-1) {
imageCounter = 0;
}
handler.postDelayed(this,adTimer);
}
};
handler.postDelayed(runnable, 250);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I have been trying to animate a spannablestringbuilder. However, I get this message from the Devices Logcat: "PropertyValuesHolder﹕ Method setAlpha() with type float not found on target class class".
Any ideas of how to animate a pure string at all?
Code of what I have been doing:
private static void fadeEnhancedText(Context context,TextView labText, TextView labEnchangedText,
int defaultColor) {
//animation add objectanimation
SpannableStringBuilder mSpannableStringBuilder=
new SpannableStringBuilder(labEnchangedText
.getText().toString());
mSpannableStringBuilder.setSpan(mForegroundColorSpan, mMatcher.start(),
mMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
labText.setText(labEnchangedText.getText().toString());
labText.setVisibility(View.GONE);
//TODO spannable problem fader doesn't work fully
labEnchangedText.setText(mSpannableStringBuilder, TextView.BufferType.SPANNABLE);
mAnimationSet.play(fadeIn(labEnchangedText,mSpannableStringBuilder)).
after(fadeOut(labEnchangedText,
labText,
defaultColor,mSpannableStringBuilder));
mAnimationSet.start();
}
private static ObjectAnimator fadeIn(TextView textView, SpannableStringBuilder spannableStringBuilder)
{
ObjectAnimator animation = ObjectAnimator.ofFloat(spannableStringBuilder.getSpans(mMatcher.start(),
mMatcher.end(),textView.getClass()), "alpha",0f,1f);
animation.setDuration(300);
return animation;
}
private static ObjectAnimator fadeOut(final TextView textView, final TextView currentView, final int defaultColor,
final SpannableStringBuilder spannableStringBuilder)
{
//textView.setTextColor(Color.rgb(177, 24, 46));
ObjectAnimator animation = ObjectAnimator.ofFloat(spannableStringBuilder.getSpans(mMatcher.start(),
mMatcher.end(),textView.getClass()), "alpha",1f,0f);
animation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
textView.setTextColor(defaultColor);
currentView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
animation.setRepeatCount(4);
animation.setDuration(300);
return animation;
}
TextView, the type returned for the spans in the call to getSpans (you specify the type as TextView), does not have a setAlpha method (nor a getAlpha method). Also, I'm not sure how ObjectAnimator likes arrays, but I haven't tried it.
Have a look at Android Transparent TextView? for TextView transparency.
It might also be possible to use HTML to style the text: How to display HTML in TextView? or see the string resources guide: http://developer.android.com/guide/topics/resources/string-resource.html#StylingWithHTML
So, here's my problem? I have it where it will slide out and then it will stay in that position and then you should be able to click on it again and it will slide back to the original location.
But instead I have to click on where it FIRST was at. Even when it's slided out. I want to make it after the animation I can click it any where, that it slided out.
Here's my code
public void sideBar()
{
ImageView sidebar = (ImageView)findViewById(R.id.sidebar);
if(out == 0)
{
mSlideInRight = AnimationUtils.loadAnimation(this, R.anim.slide_in_right);
mSlideInRight.setFillAfter(true);
sidebar.startAnimation(mSlideInRight);
out= 1;
}
else if(out == 1)
{
mSlideInLeft = AnimationUtils.loadAnimation(this, R.anim.slide_in_left);
sidebar.startAnimation(mSlideInLeft);
out=0;
}
}
and this is the code for when you click on it
public void onClick(View v) {
ImageView sidebar = (ImageView)findViewById(R.id.sidebar);
ImageView popup = (ImageView)findViewById(R.id.popup);
ImageView popup2 = (ImageView)findViewById(R.id.popup2);
switch(v.getId())
{
case R.id.sidebar:
sideBar();
break;
}
}
Animations only affect how your sidebar ImageView is drawn, not its actual position. After your animation completes, you should update the sidebar's layout parameters to your desired position. You can do this in an AnimationListener if you want the position to be updated as the animation runs or after it is complete, or right after your call to startAnimation if you want the position change to happen as the animation starts.
mSlideInRight.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation anim) {};
#Override
public void onAnimationRepeat(Animation anim) {};
#Override
public void onAnimationEnd(Animation anim) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(...);
// Set properties of layoutParams here
sidebar.setLayoutParams(layoutParams);
};
});
Replace RelativeLayout with whatever layout your ImageView is a child of.