I'm creating an android application & it has background animations for each activity.
I used AnimationDrawable setBackgroundResource(anim.xml) to run the animation xml files and works fine.
problem is, when I test on devices,some devices gives me an FATAL EXEPTION telling that
bitmap size exeeds VM budget(out of memory).
so I surfed web and found some solutions like executing animation.setCallbacks(null) before
run the animation,scaling down bitmaps(programmatically) and resizing drawables.
I tried them but few devices which has low heap still gives the same error.
so I want to know am I doing something wrong or missing something?
is their any other solution to this problem?
//animation
private void animate() {
imgView = (ImageView)findViewById(R.id.imageView1);
imgView.setVisibility(ImageView.VISIBLE);
imgView.setBackgroundResource(R.drawable.level_animation);
frameAnimation = (AnimationDrawable) imgView.getBackground();
if (frameAnimation.isRunning()) {
frameAnimation.stop();
}
else {
frameAnimation.stop();
frameAnimation.start();
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true" >
<item android:drawable="#drawable/top_anim1" android:duration="200" />
<item android:drawable="#drawable/top_anim2" android:duration="200" />
<item android:drawable="#drawable/top_anim3" android:duration="200" />
<item android:drawable="#drawable/top_anim4" android:duration="200" />
<item android:drawable="#drawable/top_anim5" android:duration="200" />
</animation-list>
Related
I have a problem with seting a custom ratingBar in Java. The problem is that setNumStars and setRating are not working. I just get one star on the screen which is fully marked although I've set the rate to 0.0f.
Here's the code:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
chapter1 = new Chapter(this);
android.widget.RelativeLayout.LayoutParams layoutParam = new RelativeLayout.LayoutParams(metrics.widthPixels , metrics.heightPixels);
myLayout.addView(chapter1, layoutParam);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
RatingBar ratingBar = new RatingBar(this);
ratingBar.setProgressDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.custom_ratingbar_menu, null));
ratingBar.setNumStars(3);
ratingBar.setRating(0.0f);
layoutParam = new RelativeLayout.LayoutParams(metrics.widthPixels / 6 , metrics.heightPixels / 32);
layoutParam.setMargins(70 + chapter1.getLeft() + wSize * j, 50 + chapter1.getTop() + hSize * i + (metrics.heightPixels / 6), 0, 0);
myLayout.addView(ratingBar, layoutParam);
}
}
And we have used the accepted answer in How to create Custom Ratings bar in Android for custom_ratingarbar_menu
Here's custom_ratingbar_menu :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+android:id/background"
android:drawable="#drawable/customm_empty_menu" />
<item android:id="#android:id/secondaryProgress"
android:drawable="#drawable/customm_empty_menu" />
<item android:id="#android:id/progress"
android:drawable="#drawable/custom_full_menu" />
</layer-list>
And it's customm_empty_menu :
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_off_menu" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_off_menu" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_off_menu" />
<item android:drawable="#drawable/stars_off_menu" />
</selector>
And this is custom_full_menu :
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_on_menu" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_on_menu" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#drawable/stars_on_menu" />
<item android:drawable="#drawable/stars_on_menu" />
</selector>
Edit
There is some problem with setting the progress drawable in code. Your drawables work when used in XML. The problem seems to revolve around setting the appropriate attributes. If I get time, I can look into this further or maybe someone else has an idea. (Check your XML, there is a typo: "customm" instead of "custom". I have corrected it below.)
(For API level 21 and above, you could do the following:
In MainActivity.java:
RatingBar ratingBar = new RatingBar(this, null, 0, R.style.myRatingBar);
In styles.xml:
<style name="myRatingBar" parent="#android:style/Widget.RatingBar">
<item name="android:progressDrawable">#drawable/custom_ratingbar_menu</item>
</style>
But this is not a general solution, so I prefer the following.)
In the meantime, you can accomplish what you want by inflating a RatingBar from XML and adding it to your layout instead of doing new RatingBar(this). In this way, you can make use of the attributes in the XML file. This fixes your issue.
Define an XML layout file that contains just a rating bar as follows:
rating_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<RatingBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/modelRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progressDrawable="#drawable/custom_ratingbar_menu" />
The drawable files are much as you defined them. I use a different icon since I did not have access to yours:
custom_ratingbar_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#android:id/background"
android:drawable="#drawable/custom_empty_menu" />
<item
android:id="#android:id/secondaryProgress"
android:drawable="#drawable/custom_empty_menu" />
<item
android:id="#android:id/progress"
android:drawable="#drawable/custom_full_menu">
</item>
</layer-list>
custom_empty_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_off" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_off" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_off" />
<item android:drawable="#android:drawable/star_off" />
</selector>
custom_full_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_on" />
<item android:state_focused="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_on" />
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="#android:drawable/star_on" />
<item android:drawable="#android:drawable/star_on" />
</selector>
Finally, the main activity's onCreate():
MainActivity#onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
RelativeLayout myLayout = new RelativeLayout(this);
super.onCreate(savedInstanceState);
setContentView(myLayout);
// Your loop would go here...
RatingBar ratingBar = (RatingBar) getLayoutInflater()
.inflate(R.layout.rating_bar, myLayout, false);
myLayout.addView(ratingBar);
ratingBar.setNumStars(5);
ratingBar.setStepSize(0.5f);
ratingBar.setRating(2.0f);
}
Old answer, but still holds.
From the documentation for RatingBar:
The number of stars set (via setNumStars(int) or in an XML layout) will be shown when the layout width is set to wrap_content (if another layout width is set, the results may be unpredictable).
You are doing the following. (The width and height are not wrap_content.)
layoutParam = new RelativeLayout.LayoutParams(metrics.widthPixels / 6 , metrics.heightPixels / 32);
myLayout.addView(ratingBar, layoutParam);
Doing the following, instead, may get you what you want, or at least, get you the number of stars you want.
layoutParam = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
myLayout.addView(ratingBar, layoutParam);
I suggest that you forego the progress drawable for the time being and get the number of stars and rating right then introduce the drawable.
If this doesn't work, can you post custom_ratingbar_menu?
I need to make an imageview with rotation feature. So I looked at the android developers site. And used their codes. But somehow I get an error.
Error:java.lang.ClassCastException: android.graphics.drawable.StateListDrawable cannot be cast to android.graphics.drawable.AnimationDrawable
I have these codes:
ImageView refresh = (ImageView)findViewById(R.id.refresh_devices_button);
refresh.setBackgroundResource(R.drawable.spin_animation); // The IDE says that it may produce null pointer exception
AnimationDrawable frameAnimation = (AnimationDrawable) refresh.getBackground();
frameAnimation.start();
In spin_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<animation-list android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/scan_1" android:duration="50" />
<item android:drawable="#drawable/scan_2" android:duration="50" />
<item android:drawable="#drawable/scan_3" android:duration="50" />
<item android:drawable="#drawable/scan_4" android:duration="50" />
<item android:drawable="#drawable/scan_5" android:duration="50" />
</animation-list>
</selector>
Please help me. From android's site I get the codes but their codes does not work. Maybe the problem is with my spin_animation.xml file.
refresh.getBackground returns StateListDrawableI think.
You can use something like this
ImageView splash = (ImageView) view.findViewById(R.id.imageView);
RotateAnimation anim = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(500);
// Start animating the image
splash.startAnimation(anim);
I have a rotation animation for my ImageView. You can try with this code:
First create your xml for rotation animation in anim directory :
rotation_animation.xml :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="400"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:toDegrees="360" />
</set>
After that in your Java class (activity or fragment) add this :
Animation rotationAnimation = AnimationUtils.loadAnimation(this, R.anim.rotation_animation);
yourImageView.startAnimation(rotationAnimation);
Now you are ready. Happy codding :)
Use below code and import below class as well.
import android.graphics.drawable.AnimationDrawable;
private AnimationDrawable mAnimation;
private ImageView mAnimLogo;
mAnimLogo = (ImageView) findViewById(R.id.loading_image);
mAnimation = (AnimationDrawable) mAnimLogo.getDrawable();
mAnimation.start();
With this line :
AnimationDrawable frameAnimation = (AnimationDrawable) refresh.getBackground();
you are trying to cast a StateListDrawable to an AnimationDrawable which throws the exception.
Nice and simple :
refresh.animate().rotation(360).setDuration(...);
rotates your view to 360 Degrees clockwise in ... ms.
Or
refresh.animate().rotationBy(360).setDuration(...);
rotates the view BY 360 degrees.
Check out ViewPropertyAnimator for different kinds of animations you can code in one line.
Rotation Animation to imageview
`RotateAnimation anim = new RotateAnimation(0f, 350f, 15f, 15f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(700);
// Start animating the image
final ImageView splash = (ImageView) findViewById(R.id.splash);
splash.startAnimation(anim);
// Later.. stop the animation
splash.setAnimation(null);`
I found that android site is okay. The problem was with my xml file.
I had this code
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<animation-list android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/scan_1" android:duration="50" />
<item android:drawable="#drawable/scan_2" android:duration="50" />
<item android:drawable="#drawable/scan_3" android:duration="50" />
<item android:drawable="#drawable/scan_4" android:duration="50" />
<item android:drawable="#drawable/scan_5" android:duration="50" />
</animation-list>
</selector>
Instead of the above code I used the following code. I had to remove the<selector> tags.
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/scan_1" android:duration="50" />
<item android:drawable="#drawable/scan_2" android:duration="50" />
<item android:drawable="#drawable/scan_3" android:duration="50" />
<item android:drawable="#drawable/scan_4" android:duration="50" />
<item android:drawable="#drawable/scan_5" android:duration="50" />
</animation-list>
I'm trying to animate some png and i would loop the animation. This is my code:
wave.setBackgroundResource(R.drawable.wave_animation);
frameAnimation = (AnimationDrawable)wave.getBackground();
frameAnimation.setCallback(wave);
frameAnimation.setVisible(true, true);
frameAnimation.start();
and here the xml with the png
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="#drawable/wave_01" android:duration="200" />
<item android:drawable="#drawable/wave_02" android:duration="200" />
<item android:drawable="#drawable/wave_03" android:duration="200" />
<item android:drawable="#drawable/wave_04" android:duration="200" />
</animation-list>
I added also the android:oneshot=false but doesn't work.
just change android:oneshot="false" to be like this
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/wave_01" android:duration="200" />
<item android:drawable="#drawable/wave_02" android:duration="200" />
<item android:drawable="#drawable/wave_03" android:duration="200" />
<item android:drawable="#drawable/wave_04" android:duration="200" />
</animation-list>
Your code above shows
android:oneshot="true"
Which will make your animation run Once and only Once.
You say you tried android:oneshot="false".
That will be essential for running through the animation-list more than once. So put it back.
Keep in mind that running animation is a 'background' task which will terminate when the primary/foreground task completes regardless of its own settings.
If you want something else you might need to take a different approach.
This is running an animation on image. Before starting the animation you need to make sure its not already running. Add a check before starting animation, if its running then stop it and then start it.
private void startAnimation(){
imageView.setImageResource(R.drawable.img_animation);
AnimationDrawable imgAnimation = (AnimationDrawable) imageView.getDrawable();
if (imgAnimation .isRunning()) {
imgAnimation .stop();
}
imgAnimation .start();
}
img_animation.xml // Check for comments in below
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true" >
<!-- 24 frame per sec | 1000ms/24 i.e. 41ms per image -->
<item
android:drawable="#drawable/ball01" android:duration="41"/>
<item
android:drawable="#drawable/ball02" android:duration="41"/>
..........so on ..........
<item
android:drawable="#drawable/ball24" android:duration="41"/>
<!-- Reset to first when animation stops-->
<item
android:drawable="#drawable/ball01"
android:duration="10"/>
</animation-list>
I'm trying to animate an image view that I'm using as a background in my activity but the app crashes when loading the activity. All the images and the .xml file are in the drawable-hdpi folder so I'm not sure why it's not finding it. Please let me know if there is a better way to set an animation as an activity background.
Heres my .xml file for the animation:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/selected" android:oneshot="false">
<item android:drawable="#drawable/bow1" android:duration="60" />
<item android:drawable="#drawable/bow2" android:duration="60" />
<item android:drawable="#drawable/bow3" android:duration="60" />
<item android:drawable="#drawable/bow4" android:duration="60" />
<item android:drawable="#drawable/bow5" android:duration="60" />
<item android:drawable="#drawable/bow6" android:duration="60" />
<item android:drawable="#drawable/bow7" android:duration="60" />
<item android:drawable="#drawable/bow8" android:duration="60" />
<item android:drawable="#drawable/bow9" android:duration="60" />
</animation-list>
Heres the code I'm using to try run it:
public class MainActivity extends Activity {
ImageView bground;
AnimationDrawable bganim;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_main);
bground = (ImageView)findViewById(R.id.background);
bground.setBackgroundResource(R.drawable.bowanimbg);
bganim = (AnimationDrawable) bground.getBackground();
bganim.start();
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.lucidity/com.example.lucidity.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable-xxhdpi/bowanimbg.xml from drawable resource ID #0x7f02000b
I would put this in a comment, but unfortunately I don't have a high enough rep. So I'll do my best to solve the problem.
You mentioned that all of the images were present in the drawable-hdpi folder. But if you notice the error, it looks like it is searching for the file in the res/drawable-xxhdpi folder. What I would suggest is copying the .xml files from the -hdpi folder into the -xxhdpi folder and seeing if it works!
Fixed it!! Since it wasn't loading the animation at all I decided to make an onWindowFocusedChanged method so that it would load the animation once the activity had loaded. I also set the background of the imageview to my bowanimbg.xml file in the .xml which I initially thought wouldn't be necessary.
public void onWindowFocusChanged(boolean hasFocus) {
bground = (ImageView)findViewById(R.id.background);
bground.setImageResource(R.drawable.bowanimbg);
bganim = (AnimationDrawable) bground.getBackground();
if (hasFocus) {
bganim.start();
}
else {
bganim.stop();
}
I am having trouble applying an animation to a View. I am trying to load the animation from inside the constructor of a CursorAdapter, so I can set it later assign it to certain children in the list.
In the constructor I have :
shineAnimation = AnimationUtils.loadAnimation(ctx, R.anim.news_list_item_shine);
the animation is in my res/anim dir
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="#drawable/shine1" android:duration="200" />
<item android:drawable="#drawable/shine2" android:duration="200" />
<item android:drawable="#drawable/shine3" android:duration="200" />
<item android:drawable="#drawable/shine4" android:duration="200" />
<item android:drawable="#drawable/shine5" android:duration="200" />
</animation-list>
I'm getting an exception :
Unknown animation name: animation-list
Help would be much appreciated
Thanks
S
I don't think you load AnimationDrawables via AnimationUtils. AnimationDrawable is a Drawable more than it is an Animation. Try this sample code from the SDK guide.
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.anim.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();