I have two animations xml file, i use these in java class. I want my animation repeats 1000 msec. I write this code but when i run this program, animation not repeat. I use Timer in repeatAnim() function but i think this is not work in 1000msec.
relative.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txt1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/txt1"
></TextView>
<ImageButton
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/pic1"
android:layout_gravity="center"/>
</LinearLayout>
SwitchClass.java:
public class SwitchClass extends Activity implements AnimationListener{
Animation animation1;
Animation animation2;
boolean frontButton=true;
ImageButton btn;
Timer timer;
TimerTask mTimerTask;
Handler handler=new Handler();
boolean repeat=true;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.relative);
animation1=AnimationUtils.loadAnimation(this, R.anim.to_middle);
animation1.setAnimationListener(this);
animation2=AnimationUtils.loadAnimation(this, R.anim.from_middle);
animation2.setAnimationListener(this);
btn=(ImageButton)findViewById(R.id.btn2);
btn.setOnClickListener(onClickListener);
repeatAnimation();
repeatAnim();
}
private OnClickListener onClickListener=new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent(SwitchClass.this,AnimClass.class);
startActivity(intent);
}
};
#Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
if(animation==animation1){
if(frontButton){
btn.setImageResource(R.drawable.pic2);
}
else{
btn.setImageResource(R.drawable.pic1);
}
btn.clearAnimation();
btn.setAnimation(animation2);
btn.startAnimation(animation2);
}
else{
frontButton=!frontButton;
btn.setEnabled(true);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
public void repeatAnim(){
timer=new Timer();
mTimerTask=new TimerTask(){
public void run(){
handler.post(new Runnable(){
public void run(){
repeatAnimation();
}
});
}
};
timer.schedule(mTimerTask, 1000);
}
public void repeatAnimation(){
btn.setEnabled(false);
btn.clearAnimation();
btn.setAnimation(animation1);
btn.startAnimation(animation1);
}
}
Thanks for advise.Cheers
What about to use use Handler, see below:
private int mSampleDurationTime = 1000; // 1 sec
private boolean continueToRun = true;
Handler mHandler = new Handler();
mHandler.postDelayed(mRunnable, mSampleDurationTime);
where mRunnable is your task:
private final Runnable mRunnable = new Runnable() {
//...
public void run() {
// do your stuff here, like update
// this block of code you going to reach every second
if(continueToRun == true){
mHandler.postDelayed(mRunnable, mSampleDurationTime);
}
}
...
};
First time you call postDelayed and invoke new Runnable(). After, if you want to continue,
call the same method into run()
why not just use handler.postDelayed(runnable, delay) instead of using a timer?
Also, try using animation1.startNow() after setting the animation on the button, and call btn.invalidate() after setting the animation to redraw the view
Related
hi i am new to Android programming i need little help in building a media player app in which i am using a seek bar to update the progress as below:
Handler handler = new Handler();
paly.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
s_player.start();
p_bar.run();
}
});
Runnable p_bar = new Runnable() {
#Override
public void run() {
start_time = s_player.getCurrentPosition();
s_bar.setProgress((int) start_time);
handler.postDelayed(p_bar, 100);
}
};
so this code is updating sekkbar after 100ms, but the song is not playing smoothly???
I've spotted a mistake here, it might be related to the problem, might not.
Runnable p_bar = new Runnable() {
#Override
public void run() {
start_time = s_player.getCurrentPosition();
s_bar.setProgress((int) start_time);
handler.postDelayed(p_bar, 100);
}
};
in the p_bar you are calling the postDelayed within the run() method, while postDelay() will add the runnable object to the MessageQueue, and the run() method of the Runnable will be called by the System when this Runnable Object is reached in the Queue.
So it is like a loop, you can run, and postDelay will call run(), and run() will call postDelay() ....
So please don't call postDelay() in the run method.
Here is how i am doing;
paly.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
s_player.start();
handler.postDelayed(p_bar,100);
}
});
Runnable p_bar = new Runnable() {
#Override
public void run() {
s_bar.setProgress((int) s_player.getCurrentPosition());
}
};
now the problem is its playing smothly but not updating progress bar
You have to implement seekbar listener....and this works for me
SeekBar.OnSeekBarChangeListener seekBarOnSeekChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
if (fromUser) {
mediaPlayer.seekTo(progress);
seekBar.setProgress(progress);
}
}
};
I want to create an android project. Which there is a layout that I want it to move smoothly on another layout. I have tried to use thread in order to do this. But in the result of my code, the layout jumps to its final position and do not move smoothly from the offset to its destination.
abs1 = (AbsoluteLayout) findViewById(R.id.absoluteLayout2);
ImageButton ib1 = (ImageButton) findViewById(R.id.imageButton1);
ib1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
display(100);
display(100);
display(100);
display(100);
display(100);
display(100);
display(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void display(int i) throws InterruptedException {
AbsoluteLayout.LayoutParams param = (AbsoluteLayout.LayoutParams) abs1
.getLayoutParams();
param.x = param.x + 10;
// param.y=param.x+20;
abs1.setLayoutParams(param);
if (Thread.interrupted()) {
throw (new InterruptedException());
}
Thread.sleep(i);
}
};
r.run();
main file:
<AbsoluteLayout
android:id="#+id/absoluteLayout2"
android:layout_width="107dp"
android:layout_height="308dp"
android:layout_x="10dp"
android:layout_y="12dp"
android:background="#color/red" >
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="0dp"
android:layout_y="0dp"
android:background="#null"
android:src="#drawable/calendar" />
EDIT: this is available starting from API 11
Just use an ObjectAnimator for that:
ObjectAnimator moveToSide = ObjectAnimator.ofFloat(myView, "translationX", 0f, 400f);
moveToSide.setDuration(700);
moveToSide.start();
Just try it out with different float values. Now, it starts from it's original position to 400f along the X-axis.
Afterwards it will stay in this position. You could also add an AnimatorListener if you want to do some stuff on the start or at the end.
moveToSide.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator arg0) {
}
});
Your Runnable is actually running on Android's UI thread.
So sleep() will block UI's drawing process, show the view on final position.
Use a Thread to wrap it.
(new Thread(new Runnable() {
#Override
public void run() {
// your code
}
}
})).start();
Then, remember that updating views from non-UI thread is forbidden.
You should use runOnUiThread to update views.
runOnUiThread(new Runnable() {
#Override
public void run() {
display(100);
}
}
Maybe, use Android's Animation class is a better way to do this.
Okay a little help here, so I have two images loading in my splash screen. The first image opens (starting the splash screen) then the second image opens, once the second image closes the mainactivity starts. Now my question is how do I make my first image fade out, then fade in with my second image?
-Oh yes, and no cross fading
-Just a complete fade out and in transition
-Thanks in advance
-The splash.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:id="#+id/lin_lay"
android:gravity="center" >
<ImageView
android:contentDescription="#string/desc"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/spinning_wheel_image"
android:background="#drawable/splashscreen1" />
</LinearLayout>
The mainanim.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/splashscreen1" android:duration="2500" />
<item android:drawable="#drawable/splashscreen2" android:duration="4000" />
</animation-list>
The Splash.java
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
ourSong = MediaPlayer.create(Splash.this, R.raw.splashsound);
ourSong.start();
Thread timer = new Thread(){
public void run(){
try{
sleep(10500);
} catch (InterruptedException e){
e.printStackTrace();
}finally{
Intent openStartingPoint = new Intent("com.theapplication.app.STARTINGPOINT");
startActivity(openStartingPoint);
}
}
};
timer.start();
}
#Override
public void setRequestedOrientation(int requestedOrientation) {
// TODO Auto-generated method stub
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
ImageView mainimage = (ImageView)findViewById(R.id.spinning_wheel_image);
mainimage.setBackgroundResource(R.anim.mainamin);
mainanimation = (AnimationDrawable) mainimage.getBackground();
mainanimation.start();
use ImageSwitcher instead of ImageView which support animations by it self.
see this sample:
http://www.java2s.com/Code/Android/UI/UsingImageSwitcher.htm
you can add animation like this:
imageSwitcher.setInAnimation(fadeInAnimation);
imageSwitcher.setOutAnimation(fadeOutAnimation);
//
my test:
public class IntroActivity extends Activity implements ViewFactory {
private static final String TAG = "IntroActivity";
private final int[] images = { R.drawable.img3, R.drawable.img2,
R.drawable.img1, R.drawable.img4, R.drawable.img5, R.drawable.img6,
R.drawable.img7, R.drawable.img8 };
private int index = 0;
private final int interval = 10000;
private boolean isRunning = true;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_intro);
startAnimatedBackground();
}
private void startAnimatedBackground() {
Animation aniIn = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
aniIn.setDuration(3000);
Animation aniOut = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);
aniOut.setDuration(3000);
final ImageSwitcher imageSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher1);
imageSwitcher.setInAnimation(aniIn);
imageSwitcher.setOutAnimation(aniOut);
imageSwitcher.setFactory(this);
imageSwitcher.setImageResource(images[index]);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
if (isRunning) {
index++;
index = index % images.length;
Log.d("Intro Screen", "Change Image " + index);
imageSwitcher.setImageResource(images[index]);
handler.postDelayed(this, interval);
}
}
};
handler.postDelayed(runnable, interval);
}
#Override
public View makeView() {
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
return imageView;
}
#Override
public void finish() {
isRunning = false;
super.finish();
}
}
to start next activity, in
#Override
public void run() {
if (isRunning) {
just check for the index,
if the index equals to 1 then start the next activity and finish the current;
You can simply just fade out the image, change it, and then finally fade it in again.
imageView.animate()
.alpha(0f)
.setDuration(100)
.setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) { }
#Override
public void onAnimationEnd(Animator animator) {
imageView.setImageResource(R.drawable.newimg);
imageView.animate().alpha(1).setDuration(200);
}
#Override
public void onAnimationCancel(Animator animator) { }
#Override
public void onAnimationRepeat(Animator animator) { }
});
my application is question/answer application , the user ask for a question , then the server send question to a user, when user receives the question , a ShowQuestion button appears , when user click it , i want to start timer , because a user have to answer in just 36 Second
i build a textView in my xml like this
<TextView
android:id="#+id/tvRemaingTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
/>
and in my Java activity i make this
TextView remaingTimer;
CountDownTimer timer;
private void initialize() {
remaingTimer=(TextView)findViewById(R.id.tvRemaingTime);
}
and when a user click ShowQuestion i make this
timer =new CountDownTimer(360000,100) {
public void onTick(long millisUntilFinished) {
remaingTimer.setText(millisUntilFinished+"");
}
public void onFinish() {
remaingTimer.setText("finish");
}
};
timer.start();
but it doesn't print anything, what am i doing wrong ?
NOTE
i am using AsyncTask to get question from server like this:
public class getQuestionFromServer extends
AsyncTask<String, Integer, String[]> {}
but i don't thing it effect on textView because the ShowQuestion button will not appear else a user have got a question from the server
you can use runOnUiThread for updateing TextView from Thread as:
TextView remaingTimer;
CountDownTimer timer;
private boolean mClockRunning=false;
private int millisUntilFinished=36;
private void initialize() {
remaingTimer=(TextView)findViewById(R.id.tvRemaingTime);
}
ShowQuestionbutn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mClockRunning==false)
{
mClockRunning=true;
millisUntilFinished=0;
myThread();
}
public void myThread(){
Thread th=new Thread(){
#Override
public void run(){
try
{
while(mClockRunning)
{
Thread.sleep(100L);// set time here for refresh time in textview
CountDownTimerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(mClockRunning)
{
if(millisUntilFinished<0)
{
mClockRunning=false;
millisUntilFinished=36;
}
else
{
millisUntilFinished--;
remaingTimer.setText(millisUntilFinished+"");//update textview here
}
}
};
}
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
This is my code following,I am changing some iamges dynamically in my image view.
public class LoadingScreen extends Activity{
public static Integer[] imageList={R.drawable.food_pics1,R.drawable.food_pics2,R.drawable.food_pics3,
R.drawable.food_pics4,R.drawable.food_pics5,R.drawable.food_pics6,R.drawable.food_pics7,
R.drawable.food_pics8,R.drawable.food_pics9};
Thread thread;
ImageView foodImageView;
final Handler myHandler=new Handler();
public int currentImageIndex=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.load_xml);
foodImageView=(ImageView)findViewById(R.id.imageView_food);
// final int i=0;
final Runnable runnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
animateImages();
}
};
final int delay=500;
final long period=1000;
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
myHandler.post(runnable);
}
}, delay, period);
}
private void animateImages() {
// TODO Auto-generated method stub
foodImageView.setImageResource(imageList[currentImageIndex%imageList.length]);
currentImageIndex++;
foodImageView.getAnimation();
}
I want to stop the timer and finish this activity after 20 secs.how can I do that.
Try using this,
View v = new View(this);
v.postDelayed(new Runnable(){
public void run() {
// TODO Auto-generated method stub
//cancel your animation and finish the Activity here.
finish();
}
}, (long) 20000.0);
You can say something like this :
timer.cancel();
timer = null;
Save the TimerTask instance in the class and invoke cancel on it.
Here's a tip I found very useful without using Java's Timer: Try synchronizing things in the UI thread, especially if you want to do UI tasks. Example:
... onCreate() {
getUiThreadHandler().post(new Runnable(){
if (canceled()) {
return;
}
// Actual work
...
// Invoke again after delay
getUiThreadHandler().postDelayed(this, 500);
});
Good luck