I am trying a simple frame by frame animation. My animation works on button tap, but I want it should start when the activity starts or load . I have tried onWindowFocusChanged() method also to start animation as per told in docs. I think i am making silly mistake. Anyone has idea.
public class FirstActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
Button btnalarm;
AnimationDrawable AniFrame;
ImageView images;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
images=(ImageView)findViewById(R.id.myImageView);
images.setBackgroundResource(R.drawable.demo_animation);
AniFrame = (AnimationDrawable)images.getBackground();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.v("in focus", "in focus");
AniFrame.start();
}
demo_animation.xml file---->
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/a" android:duration="50" />
<item android:drawable="#drawable/b" android:duration="50" />
<item android:drawable="#drawable/c" android:duration="50" />
<item android:drawable="#drawable/d" android:duration="50" />
<item android:drawable="#drawable/e" android:duration="50" />
<item android:drawable="#drawable/f" android:duration="50" />
<item android:drawable="#drawable/h" android:duration="50" />
<item android:drawable="#drawable/i" android:duration="50" />
<item android:drawable="#drawable/j" android:duration="50" />
<item android:drawable="#drawable/k" android:duration="50" />
</animation-list>
Add
AniFram.start() to the end of your onCreate().
Also inflate your R.layout.main.
Example:
LinearLayout layout = (LinearLayout)findViewById(R.id.main);
layout.startAnimation(AniFrame);
Also check your logcat for problems.
EDIT:
Check out this from the Docs Should help alot.
Animating a drawable
Just use anther thread.It will work fine.
public void onCreate(Bundle savedInstanceState) {
//your code
//At last of onCreate add these lines
images.post(new MyAnimation());
}
class MyAnimation implements Runnable{
#Override
public void run(){
AniFrame.start();
}
}
now it will work,just check it.
Try to use setCallback just before you start the animation as following:
AniFrame.setCallback(images);
Related
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 was following the Google provided example of how to use AnimationDrawable with an ImageView. You can find it here: http://developer.android.com/guide/topics/graphics/drawable-animation.html
imageView.setBackgroundResource(R.drawable.animation);
AnimationDrawable animation = (AnimationDrawable)imageView.getBackground();
animation.start();
When I run it I get the error:
java.lang.ClassCastException: android.graphics.drawable.BitmapDrawable cannot be cast to android.graphics.drawable.AnimationDrawable
Google seems to think this should work, but if you cannot cast a BitmapDrawable to AnimationDrawable I am not sure how this is supposed to work?
I figured out the solution to this problem.
imageView.setImageDrawable(getResources().getDrawable(R.drawable.animation));
AnimationDrawable animation = (AnimationDrawable) imageView.getDrawable();
animation.start();
I have no idea why Google's documentation says to use the background, but using setImageDrawable and getDrawable works. Honestly it makes more sense it would work this way than the other way anyways.
I had the same problem. I know this thread is some month old, but maybe somebody what to read about my experience.
I dont know why, but google doesnt accept Spacemarks like "_" in his Picturenames while using it for animation. I uses names like "loading_frame1", and it doesnt work. I changed the names to something like "loadingframe1" and it works....
Before:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/loading_frame1" android:duration="100" />
<item android:drawable="#drawable/loading_frame2" android:duration="100" />
<item android:drawable="#drawable/loading_frame3" android:duration="100" />
<item android:drawable="#drawable/loading_frame4" android:duration="100" />
<item android:drawable="#drawable/loading_frame5" android:duration="100" />
<item android:drawable="#drawable/loading_frame6" android:duration="100" />
<item android:drawable="#drawable/loading_frame7" android:duration="100" />
<item android:drawable="#drawable/loading_frame8" android:duration="100" />
<item android:drawable="#drawable/loading_frame9" android:duration="100" />
<item android:drawable="#drawable/loading_frame10" android:duration="100" />
<item android:drawable="#drawable/loading_frame11" android:duration="100" />
<item android:drawable="#drawable/loading_frame12" android:duration="100" />
<item android:drawable="#drawable/loading_frame13" android:duration="100" />
<item android:drawable="#drawable/loading_frame14" android:duration="100" />
<item android:drawable="#drawable/loading_frame15" android:duration="100" />
<item android:drawable="#drawable/loading_frame16" android:duration="100" />
<item android:drawable="#drawable/loading_frame17" android:duration="100" />
<item android:drawable="#drawable/loading_frame18" android:duration="100" />
<item android:drawable="#drawable/loading_frame19" android:duration="100" />
<item android:drawable="#drawable/loading_frame20" android:duration="100" />
</animation-list>
After:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/loadingframe1" android:duration="100" />
<item android:drawable="#drawable/loadingframe2" android:duration="100" />
<item android:drawable="#drawable/loadingframe3" android:duration="100" />
<item android:drawable="#drawable/loadingframe4" android:duration="100" />
<item android:drawable="#drawable/loadingframe5" android:duration="100" />
<item android:drawable="#drawable/loadingframe6" android:duration="100" />
<item android:drawable="#drawable/loadingframe7" android:duration="100" />
<item android:drawable="#drawable/loadingframe8" android:duration="100" />
<item android:drawable="#drawable/loadingframe9" android:duration="100" />
<item android:drawable="#drawable/loadingframe10" android:duration="100" />
<item android:drawable="#drawable/loadingframe11" android:duration="100" />
<item android:drawable="#drawable/loadingframe12" android:duration="100" />
<item android:drawable="#drawable/loadingframe13" android:duration="100" />
<item android:drawable="#drawable/loadingframe14" android:duration="100" />
<item android:drawable="#drawable/loadingframe15" android:duration="100" />
<item android:drawable="#drawable/loadingframe16" android:duration="100" />
<item android:drawable="#drawable/loadingframe17" android:duration="100" />
<item android:drawable="#drawable/loadingframe18" android:duration="100" />
<item android:drawable="#drawable/loadingframe19" android:duration="100" />
<item android:drawable="#drawable/loadingframe20" android:duration="100" />
</animation-list>
And here the LoadingAnimation.class Listing
package com.justkidding.animation;
import android.support.v7.app.ActionBarActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
public class LoadingAnimation extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading_animation);
}
#Override
public void onWindowFocusChanged (boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
ImageView animation = (ImageView)findViewById(R.id.aniimage);
animation.setBackgroundResource(R.drawable.loading_animation);
AnimationDrawable frameAnimation = (AnimationDrawable) animation.getBackground();
if(hasFocus) {
frameAnimation.start();
} else {
frameAnimation.stop();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.loading_animation, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Google's code works. The "can not be cast issue" which lead me here, was because I was not paying attention and put my animation.xml in res.anim instead of res.drawable.
However I agree using setImageDrawable and getDrawable works better.
About this problem, I had a little oversight on the detail on google's example code in the documentation and this might be the case for a couple of persons using the guide.
There is an separate xml file that holds the drawables, indicating the transitions and has the tag:
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="#drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="#drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="#drawable/rocket_thrust3" android:duration="200" />>
</animation-list>
The above file is named rocket_thrust, and it is this same file that is set as backgroundDrawable in the following lines:
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
Give a try at this and be sure that documentation has no errors.
Best of luck.
Complete process to do animation is :
1. Create XML layout with imageView
and
2. Create XML file for animation suppose drawable/animation.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/twit" android:duration="120"></item>
<item android:duration="120" android:drawable="#drawable/a111"></item>
<item android:duration="120" android:drawable="#drawable/a2"></item>
<item android:duration="120" android:drawable="#drawable/a3"></item>
<item android:duration="120" android:drawable="#drawable/a4"></item>
<item android:duration="120" android:drawable="#drawable/a5"></item>
<item android:duration="120" android:drawable="#drawable/a6"></item>
</animation-list>
now
3. Create Main Activity
Then Type this code
public class AnimationMe extends AppCompatActivity {
private ImageView imgView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.logoo);
imgView = (ImageView) findViewById(R.id.imgView);
// the frame-by-frame animation defined as a xml file within the drawable folder
/*imgView.setBackgroundResource(R.drawable.animation);*/
imgView.setImageDrawable(getResources().getDrawable(R.drawable.animation));
// It's not possible to start the animation during the onCreate.
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
AnimationDrawable animationDrawable = (AnimationDrawable)imgView.getDrawable();
if(hasFocus)
{
animationDrawable.start();
}
else
{
animationDrawable.stop();
}
}
}
*
Note : ImageView have background as drawable and give a name of
animation.xml not for a particular image and then call with
imageview.getDrawable in AnimationDrawable.
---- You can't Run Animation in onCreate Method. Set drawable property in Imageview in onCreate() but call AnimationDrawable method out of
block of onCreate().
*
Sure it will work !
Just to add more answer to this page based on my experience because Stackoverflow seems has a very limited answer for this issue
I my case I tried to animate my background layout which using drawable for rounded radius. I got logcat error
java.lang.ClassCastException: android.graphics.drawable.GradientDrawable cannot be cast to android.graphics.drawable.AnimationDrawable
Turn out I must set the background attribute on my layout file to this drawable file
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="#drawable/rounded_corner" android:duration="80" />
<item android:drawable="#drawable/rounded_corner_gray_background" android:duration="80" />
<item android:drawable="#drawable/rounded_corner" android:duration="80" />
<item android:drawable="#drawable/rounded_corner_gray_background" android:duration="80" />
<item android:drawable="#drawable/rounded_corner" android:duration="80" />
<item android:drawable="#drawable/rounded_corner_gray_background" android:duration="80" />
<item android:drawable="#drawable/rounded_corner" android:duration="80" />
And then call this code on my Main Activity
val backgroundAnim = info_layout?.background as AnimationDrawable
backgroundAnim.start()
My mistake is previously I put #drawable/rounded_corner on layout file as background attribute.
Hope this can help somebody, as I spend 3 hours just to solve this issue.
I have created a custom Loading Progress Dialog. And its working well.
I am rotating 12 square Images here is one of them
But when I want to use it with AsynTask, The animation not working.
My Sample code is below.
Activity Where I Start Loading... Animation and Stop.
MainActivity.java
public class MainActivity extends Activity {
AnimationDrawable loadingViewAnim;
TextView loadigText;
ImageView loadigIcon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadigText = (TextView) findViewById(R.id.textView1);
loadigText.setText("Loading...");
loadigText.setVisibility(View.GONE);
loadigIcon = (ImageView) findViewById(R.id.imageView1);
loadigIcon.setVisibility(View.GONE);
loadigIcon.setBackgroundResource(R.anim.progress_animation_white);
loadingViewAnim = (AnimationDrawable) loadigIcon.getBackground();
}
//When User Touch on Screen The Loading... Animation Starts With Image Rotation
//If I start below code in AsynTask's onPreExecute method it doesn't work
public boolean onTouchEvent(MotionEvent event)
{
loadigText.setVisibility(View.VISIBLE);
loadigIcon.setVisibility(View.VISIBLE);
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
loadingViewAnim.start();
return true;
}
return super.onTouchEvent(event);
}
}
XML layout with Simple Text and Image for Progress Dialog.
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/progress_sm_w01" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Loading..."
android:textColor="#ffffff"
android:textSize="12sp" />
</LinearLayout>
Animation List having 12 Images I am Rotating with Angle & Time Duration
progress_animation_white.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/progress_sm_w01" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w02" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w03" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w04" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w05" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w06" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w07" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w08" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w09" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w10" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w11" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w12" android:duration="50" />
</animation-list>
Here is the result Loading Screen..
My Question is Is there anyway to Achieve the same Loading Animation
with AsynTask.
Your Small Help will appreciated.
Well thanks to #Brontok and #URAndroid for their help. I got solved my problem.
So let me answer my own question, Hoe i achieved that Custom Loading animation
I have added few Image for Image Rotation Animation
Step 1 - in res/drawable folder
progress_sm_w00.png (Default blank transparent image)
progress_sm_w01.png (first animtion position)
progress_sm_w02.png
progress_sm_w03.png
progress_sm_w04.png
progress_sm_w05.png
progress_sm_w06.png
progress_sm_w07.png
progress_sm_w08.png
progress_sm_w09.png
progress_sm_w10.png
progress_sm_w11.png
progress_sm_w12.png (last animation position).
Example : one of these is below i have added
Step 2 - in res/anim folder created animation file name "loading_animation.xml"
<item android:drawable="#drawable/progress_sm_w01" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w02" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w03" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w04" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w05" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w06" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w07" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w08" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w09" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w10" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w11" android:duration="50" />
<item android:drawable="#drawable/progress_sm_w12" android:duration="50" />
</animation-list>
Step 3 - now created Custom Loading View layout in my Screen (Activity) wherever I need to show loading
example.
XML layout for my Facebook login screen
<LinearLayout
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0D000000"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone" >
<ImageView
android:id="#+id/imageView111"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/progress_sm_w00"
android:visibility="gone" />
<TextView
android:id="#+id/textView111"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Searching..."
android:textColor="#ffffff"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
Step 4 - In java code (Activity) I created Loading view and after completing OnCreate method I started Asyn Task so my Animation get work properly.
public class ResultActivity extends Activity {
private static final String TAG = "ResultActivity";
private AnimationDrawable loadingViewAnim=null;
private TextView loadigText = null;
private ImageView loadigIcon = null;
private LinearLayout loadingLayout = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
loadingLayout = (LinearLayout)findViewById(R.id.LinearLayout1);
loadingLayout.setVisibility(View.GONE);
loadigText = (TextView) findViewById(R.id.textView111);
loadigText.setVisibility(View.GONE);
loadigIcon = (ImageView) findViewById(R.id.imageView111);
loadigIcon.setVisibility(View.GONE);
loadigIcon.setBackgroundResource(R.anim.loading_animation);
loadingViewAnim = (AnimationDrawable) loadigIcon.getBackground();
// This line is to start Asyn Task only when OnCreate Method get completed, So Loading Icon Rotation Animation work properly
loadigIcon.post(new Starter());
}
class Starter implements Runnable {
public void run() {
//start Asyn Task here
new LongOperation().execute("");
}
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//ToDo your Network Job/Request etc. here
return "Executed";
}
#Override
protected void onPostExecute(String result) {
//ToDo with result you got from Task
//Stop Loading Animation
loadingLayout.setVisibility(View.GONE);
loadigText.setVisibility(View.GONE);
loadigIcon.setVisibility(View.GONE);
loadingViewAnim.stop();
}
#Override
protected void onPreExecute() {
//Start Loading Animation
loadingLayout.setVisibility(View.VISIBLE);
loadigText.setVisibility(View.VISIBLE);
loadigIcon.setVisibility(View.VISIBLE);
loadingViewAnim.start();
}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
Step 5 - Here is the Result Screen with Progress Loading animation.
Hope this will help you. Cheers!!
Maybe you can use GLIDE, for example
Glide.with(context)
.load(imageUrl)
.asGif()
.placeholder(R.drawable.loading2)
.crossFade()
.into(imageView);
Show GIF file with Glide (image loading and caching library)
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();
}
yesterday I noticed the possibility to integrate Fragments in older API Levels through the Compatibility package, but thats not really essential for the question. :)
I have a Button with an OnClickListener
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
doSomething();
button.setPressed(true);
}
});
Because of the actual clicking, it is shown as pressed and after releasing the click, the button state is not pressed and stays that way.
Is there a simple way that keeps the button state pressed after releasing?
First thing I can think of would be some sort of timer, but that seems unreasonable.
Just to note this is because Android is changing the setPressed both before and after your onClickEvent, so changing it yourself has no effect. Another way to get around this is to use the onTouchEvent.
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// show interest in events resulting from ACTION_DOWN
if (event.getAction() == MotionEvent.ACTION_DOWN) return true;
// don't handle event unless its ACTION_UP so "doSomething()" only runs once.
if (event.getAction() != MotionEvent.ACTION_UP) return false;
doSomething();
button.setPressed(true);
return true;
}
});
Use ToggleButton instead of Button.
<ToggleButton
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/topping_selector"
android:checked="false"
android:textOff="Topping2"
android:textOn="Topping2" />
topping_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/btn_topping_on" />
<item android:state_checked="false"
android:drawable="#drawable/btn_topping_off" />
</selector>
You can keep the button states in xml file under drawable folder, then used as background for button.
For example:
android:background="#drawable/buttonstate"
buttonstate.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/back_focused" />
<item android:drawable="#drawable/back" /> <!-- default -->
</selector>
Better solution:
In xml file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_activated="true">
<bitmap android:src="#drawable/image_selected"/>
</item>
<item>
<bitmap android:src="#drawable/image_not_selected"/>
</item>
</selector>
And in java:
#Override
public void onClick(View v) {
v.setActivated(!v.isActivated());
}
You can use android.os.Handler class. Ugly, but works also:
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
doSomething();
new Handler().post(new Runnable() {
#Override
public void run() {
button.setPressed(true);
}
});
}
});
Another solution is to extend Button and override setPressed(boolean pressed) method so you can handle platform calls from the onClickEvent using a flag, for example changing the boolean pressed parameter depending on your needs.
public class MyButton extends Button {
boolean isSelected = false; //this is your flag
#Override
public void setPressed(boolean pressed) {
if(isSelected) {
//here you change the parameter so it stays pressed
super.setPressed(true);
return;
}
super.setPressed(pressed);
}
public void setIsSelected(boolean selected) {
this.isSelected = selected;
}
public MyButton(Context context) {
super(context);
}
}
This is the solution I used, It also works on android 7.0 at the moment.
YourActivity.java
public void onStandbyStart(String message) {
startStandbyBtn.setActivated(true);
}
public void onBackOnline(String message) {
startStandbyBtn.setActivated(false);
}
YourActivityLayout
<Button
...
style="#style/generic_btn_style"
... />
values/styles.xml
<style name="generic_btn_style" parent="#android:style/Widget.Button">
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:background">#drawable/generic_btn</item>
<item name="android:textColor">#color/selector_white_black</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
</style>
drawable/generic_btn.xml
This selector chooses the button background. I use the pressed as the activated.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/generic_btn_disabled" android:state_enabled="false" />
<item android:drawable="#drawable/generic_btn_pressed" android:state_enabled="true" android:state_pressed="true" />
<item android:drawable="#drawable/generic_btn_pressed" android:state_activated="true" />
<item android:drawable="#drawable/generic_btn_focused" android:state_enabled="true" android:state_focused="true" />
<item android:drawable="#drawable/generic_btn_enabled" android:state_enabled="true" />
</selector>
color/selector_black_white
Here I set the text color. In my case, I need to pick the textcolor black when pressed.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#fff" android:state_pressed="true" /> <!-- pressed -->
<item android:color="#fff" android:state_activated="true" /> <!-- pressed -->
<item android:color="#000" /> <!-- default -->
</selector>