I created a custom ProgressDialog which has a lively ImageView. But this giving error for use within a AsyncTask execution.
AsyncTask out of work. I tried to use the animation with a runOnUiThread and not worked. How can I use this animation while running AsyncTask?
layout_progress.xml (only image)
<ImageView
android:id="#+id/ivLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#anim/loading"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"/>
loading.xml (animation)
<?xml version="1.0" encoding="utf-8"?>
<animation-list android:id="#+id/animation" android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/load5_1" android:duration="150" />
<item android:drawable="#drawable/load5_2" android:duration="150" />
<item android:drawable="#drawable/load5_3" android:duration="150" />
<item android:drawable="#drawable/load5_4" android:duration="150" />
<item android:drawable="#drawable/load5_5" android:duration="150" />
<item android:drawable="#drawable/load5_6" android:duration="150" />
<item android:drawable="#drawable/load5_7" android:duration="150" />
<item android:drawable="#drawable/load5_8" android:duration="150" />
<item android:drawable="#drawable/load5_9" android:duration="150" />
<item android:drawable="#drawable/load5_10" android:duration="150" />
</animation-list>
method show of the custom progress dialog
public void show() {
super.show();
setContentView(layoutId);
final ImageView imageView = (ImageView) findViewById(R.id.ivLoading);
final AnimationDrawable anim = (AnimationDrawable) imageView.getDrawable();
final Runnable run = new Runnable() {
#Override
public void run() {
anim.start();
}
};
imageView.post(run);
//test 2 - doesnt work
/*
final Runnable run = new Runnable() {
#Override
public void run() {
anim.start();
imageView.post(this);
}
};
activity.runOnUiThread(run);
*/
}
You should not do this in an AsyncTask. Manipulation of the UI should be done only in the UI thread.
There is a simple example of what you are trying to achieve here:
http://developer.android.com/guide/topics/graphics/drawable-animation.html
Try and start the animation after you are sure that the ImageView has been attached to the view hierarchy. Quoting the link I posted:
It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. If you want to play the animation immediately, without requiring interaction, then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus.
i want to ask that i want to make this animation as single image and wanted to apply some other view animation on it like move or alpha etc. how this can be done ? any idea ? simply i wanted to apply view animation on drawable animation.
i have some drawable like s1,s2,s3,s4 to s16 the XML is
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/s1" android:duration="200" />
<item android:drawable="#drawable/s2" android:duration="200" />
<item android:drawable="#drawable/s3" android:duration="200" />
<item android:drawable="#drawable/s12" android:duration="200" />
<item android:drawable="#drawable/s13" android:duration="200" />
<item android:drawable="#drawable/s14" android:duration="200" />
<item android:drawable="#drawable/s15" android:duration="200" />
<item android:drawable="#drawable/s16" android:duration="200" />
</animation-list>
and java code is
anim = (ImageView) findViewById(R.id.black);
anim.setBackgroundResource(R.drawable.smurf);
AnimationDrawable hello = (AnimationDrawable) anim.getBackground();
hello.start();
here smurf in drawable is the xml file for drawable animation.
we can do that animation but we have to maintain handler for that.
private int index = 0;
private Handler handler = new Handler();
private AnimationDrawable drawable;
Runnable runnable = new Runnable() {
#Override
public void run() {
imageView.setImageDrawable(drawable.getFrame(index));
index++;
if (index == drawable.getNumberOfFrames()) {
index = 0;
}
handler.postDelayed(runnable, drawable.getDuration(index));
}
};
in your onclick or where you want to start animation write like this:
handler.postDelayed(runnable, drawable.getDuration(index));
and your onDestroy() remove the handeler call backs like this:
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runnable);
}
I'm showing a DialogFragment when the user taps on a row in a ListView. I'd like to animate the showing of the dialog so that it grows from the center of the row. A similar effect can be seen when opening a folder from the launcher.
One idea that I've had is a combination of TranslateAnimation and ScaleAnimation. Is there another way?
Being DialogFragment a wrapper for the Dialog class, you should set a theme to your base Dialog to get the animation you want:
public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Set a theme on the dialog builder constructor!
AlertDialog.Builder builder =
new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );
builder
.setTitle( "Your title" )
.setMessage( "Your message" )
.setPositiveButton( "OK" , new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
return builder.create();
}
}
Then you just need to define the theme that will include your desired animation. In styles.xml add your custom theme:
<style name="MyCustomTheme" parent="#android:style/Theme.Panel">
<item name="android:windowAnimationStyle">#style/MyAnimation.Window</item>
</style>
<style name="MyAnimation.Window" parent="#android:style/Animation.Activity">
<item name="android:windowEnterAnimation">#anim/anim_in</item>
<item name="android:windowExitAnimation">#anim/anim_out</item>
</style>
Now add the animation files in the res/anim folder:
( the android:pivotY is the key )
anim_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:fillAfter="false"
android:startOffset="200"
android:duration="200"
android:pivotX = "50%"
android:pivotY = "-90%"
/>
<translate
android:fromYDelta="50%"
android:toYDelta="0"
android:startOffset="200"
android:duration="200"
/>
</set>
anim_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/linear_interpolator"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="0.0"
android:fillAfter="false"
android:duration="200"
android:pivotX = "50%"
android:pivotY = "-90%"
/>
<translate
android:fromYDelta="0"
android:toYDelta="50%"
android:duration="200"
/>
</set>
Finally, the tricky thing here is to get your animation grow from the center of each row. I suppose the row is filling the screen horizontally so, on one hand the android:pivotX value will be static. On the other hand, you can't modify the android:pivotY value programmatically.
What I suggest is, you define several animations each of which having a different percentage value on the android:pivotY attribute (and several themes referencing those animations). Then, when the user taps the row, calculate the Y position in percentage of the row on the screen. Knowing the position in percentage, assign a theme to your dialog that has the appropriate android:pivotY value.
It is not a perfect solution but could do the trick for you. If you don't like the result, then I would suggest forgetting the DialogFragment and animating a simple View growing from the exact center of the row.
Check it out this code, it works for me
// Slide up animation
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="#android:integer/config_mediumAnimTime"
android:fromYDelta="100%"
android:interpolator="#android:anim/accelerate_interpolator"
android:toXDelta="0" />
</set>
// Slide dowm animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="#android:integer/config_mediumAnimTime"
android:fromYDelta="0%p"
android:interpolator="#android:anim/accelerate_interpolator"
android:toYDelta="100%p" />
</set>
// Style
<style name="DialogAnimation">
<item name="android:windowEnterAnimation">#anim/slide_up</item>
<item name="android:windowExitAnimation">#anim/slide_down</item>
</style>
// Inside Dialog Fragment
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.DialogAnimation;
}
DialogFragment has a public getTheme() method that you can over ride for this exact reason. This solution uses less lines of code:
public class MyCustomDialogFragment extends DialogFragment{
...
#Override
public int getTheme() {
return R.style.MyThemeWithCustomAnimation;
}
}
To get a full-screen dialog with animation, write the following ...
Styles:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="actionModeBackground">?attr/colorPrimary</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.NoActionBar.FullScreenDialog">
<item name="android:windowAnimationStyle">#style/Animation.WindowSlideUpDown</item>
</style>
<style name="Animation.WindowSlideUpDown" parent="#android:style/Animation.Activity">
<item name="android:windowEnterAnimation">#anim/slide_up</item>
<item name="android:windowExitAnimation">#anim/slide_down</item>
</style>
res/anim/slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="#android:interpolator/accelerate_quad">
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="100%"
android:toYDelta="0%"/>
</set>
res/anim/slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="#android:interpolator/accelerate_quad">
<translate
android:duration="#android:integer/config_shortAnimTime"
android:fromYDelta="0%"
android:toYDelta="100%"/>
</set>
Java code:
public class MyDialog extends DialogFragment {
#Override
public int getTheme() {
return R.style.AppTheme_NoActionBar_FullScreenDialog;
}
}
private void showDialog() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment previous = getSupportFragmentManager().findFragmentByTag(MyDialog.class.getName());
if (previous != null) {
fragmentTransaction.remove(previous);
}
fragmentTransaction.addToBackStack(null);
MyDialog dialog = new MyDialog();
dialog.show(fragmentTransaction, MyDialog.class.getName());
}
In DialogFragment, custom animation is called onCreateDialog. 'DialogAnimation' is custom animation style in previous answer.
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
return dialog;
}
Use decor view inside onStart in your dialog fragment
#Override
public void onStart() {
super.onStart();
final View decorView = getDialog()
.getWindow()
.getDecorView();
decorView.animate().translationY(-100)
.setStartDelay(300)
.setDuration(300)
.start();
}
If you want to work over APIs you have to do inside your DialogFragemnt->onStart and not inside onCreateDialog
#Override
public void onStart()
{
if (getDialog() == null)
{
return;
}
getDialog().getWindow().setWindowAnimations(
R.style.DlgAnimation);
super.onStart();
}
Note: This is just a complement to other answers.
No matter which the solutions you pick you might have the same problem as me.
I need to UNINSTALL the game from my development device before installing the new version for the animation changes to take effect.
I am not sure why but I guess it has to do with the optimized deployment on Android studio not recognizing the changes.
Have you looked at Android Developers Training on Zooming a View? Might be a good starting point.
You probably want to create a custom class extending DialogFragment to get this working.
Also, take a look at Jake Whartons NineOldAndroids for Honeycomb Animation API compatibility all the way back to API Level 1.
Add this code on values anim
<scale
android:duration="#android:integer/config_longAnimTime"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:toXScale="1.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"/>
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="#android:integer/config_longAnimTime"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"/>
call on styles.xml
<style name="DialogScale">
<item name="android:windowEnterAnimation">#anim/scale_in</item>
<item name="android:windowExitAnimation">#anim/scale_out</item>
</style>
On java code: set Onclick
public void onClick(View v) {
fab_onclick(R.style.DialogScale, "Scale" ,(Activity) context,getWindow().getDecorView().getRootView());
// Dialogs.fab_onclick(R.style.DialogScale, "Scale");
}
setup on method:
alertDialog.getWindow().getAttributes().windowAnimations = type;
My Problem is I have Some Images & I used frame animation to display this images on click event of button but if i click button first time the image is display in sequence & if i click this button another time that time the image is not displayed. following is my code.
Animation.java file:-
public class Animation extends Activity {
Button mBtnOK;
AnimationDrawable frameAnimation;
ImageView imgView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBtnOK = (Button) findViewById(R.id.mBtnOK);
mBtnOK.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
animate();
}
});
}
private void animate() {
imgView = (ImageView) findViewById(R.id.simple_anim);
imgView.setVisibility(ImageView.VISIBLE);
imgView.setBackgroundResource(R.anim.simple_animation);
AnimationDrawable frameAnimation = (AnimationDrawable) imgView
.getBackground();
frameAnimation.start();
frameAnimation.setOneShot(true);
}
}
Animation file:-
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" id="selected" android:oneshot="false">
<item android:drawable="#drawable/monkey_1" android:duration="50" />
<item android:drawable="#drawable/monkey_2" android:duration="50" />
<item android:drawable="#drawable/monkey_3" android:duration="50" />
<item android:drawable="#drawable/monkey_4" android:duration="50" />
<item android:drawable="#drawable/monkey_5" android:duration="50" />
<item android:drawable="#drawable/monkey_6" android:duration="50" />
<item android:drawable="#drawable/monkey_7" android:duration="50" />
<item android:drawable="#drawable/monkey_8" android:duration="50" />
<item android:drawable="#drawable/monkey_9" android:duration="50" />
<item android:drawable="#drawable/monkey_10" android:duration="50" />
</animation-list>
The only way to restart a frame animation is to use the setVisible() which contains a flag to force the animation to reset to the first frame. If you modify the animating section of code like so:
AnimationDrawable frameAnimation = (AnimationDrawable) imgView.getBackground();
frameAnimation.setOneShot(true);
frameAnimation.setVisible(true, true);
frameAnimation.start();
The animation should always start from the first frame and run to completion each time you click the button. The animation can also be reset by toggling visibility on the drawable itself, instead of the ImageView that contains it.
HTH
#Dipak,
I have done with the animation using the same way you have done. Try to add this code, hope your error will be resolved. And also one more thing is use thread to run the animation. This will surely run it nicely.
if(frameAnimation.isRunning()) {
frameAnimation.stop();
frameAnimation.start();
}
I'm trying to get the AnimationDrawable on my Android app to repeat.
I configured the android:oneshot on false. (tried both with java and with XML)
Still, whenever the animation is played, once it's done, it goes back to the first frame, and stops
This is my XML file
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:id="#+id/network_scanning" android:oneshot="false">
<item android:drawable="#drawable/network_wireless_0" android:duration="300" />
<item android:drawable="#drawable/network_wireless_1" android:duration="300" />
<item android:drawable="#drawable/network_wireless_2" android:duration="300" />
<item android:drawable="#drawable/network_wireless_3" android:duration="300" />
<item android:drawable="#drawable/network_wireless_4" android:duration="300" />
</animation-list>
and this is the code to start the animation:
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
LinearLayout network = (LinearLayout) findViewById(R.id.wifi_anim);
AnimationDrawable anim = (AnimationDrawable) network.getBackground();
if (hasFocus)
{
anim.setOneShot(false);
anim.setCallback(network);
anim.setVisible(true, true);
anim.start();
}
}
hi you can get solution from here
http://docs.mono-android.net/Android.Graphics.Drawables.AnimationDrawable