I am writing a splash screen in android 2.1. I want 20 png images to be shown in an order at the splash screen. I tried to use animation-list but couldn't manage to do it.
Here is my code. Now, there is an image called firstLoadingImage.png. Only that is shown for 5000ms. Then the myappactivity starts. However, I couldn't manage to update the image source during this waiting time. How do you think I can do this?
SplashScreenActivity
package myapp.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
public class SplashScreenActivity extends Activity {
protected boolean _active = true;
protected int _splashTime = 5000; // time to display the splash screen in ms
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splashscreen);
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(_active && (waited < _splashTime)) {
sleep(100);
if(_active) {
waited += 100;
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
startActivity(new Intent(SplashScreenActivity.this, MyAppActivity.class));
stop();
}
}
};
splashTread.start();
}
}
splashscreen.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/linearLayout"
android:background="#drawable/loading_screen_background" >
<ImageView
android:id="#+id/firstLoadingImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/loading100" />
</LinearLayout>
Frame animations can be achieved by setting it to an AnimationDrawable to the background of an ImageView.
Example:
final AnimationDrawable anim = new AnimationDrawable();
anim.addFrame(Context.getResources().getDrawable(R.drawable.resource_id_of_frame1, durationInMs);
anim.addFrame(Context.getResources().getDrawable(R.drawable.resource_id_of_frame2, durationInMs);
anim.addFrame(Context.getResources().getDrawable(R.drawable.resource_id_of_frame3, durationInMs);
...
anim.addFrame(Context.getResources().getDrawable(R.drawable.resource_id_of_framen, durationInMs);
anim.setOneShot(false);
ImageView myImageView = getImageViewToSet();
myImageView.setBackgroundDrawable(anim);
myImageView.post(new Runnable(){
public void run(){
anim.start();
}
}
So make your splash screen a simple layout with an ImageView or create one and add it to the layout. Set the AnimationDrawable to it and run.
My guess would be to use the function runOnUiThread() after calling sleep in your splash thread. Make a runnable class to change the ImageView background, and run in this function perhaps?
Activity.runOnUiThread()
You could find the tutorial for it
here
Related
I wanna make splash screen while loading the main activity.
So, I added Splash activity.
package com.originerd.tau;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Thread logoTimer = new Thread(){
#Override
public void run() {
// TODO Auto-generated method stub
try {
Intent i = new Intent(Splash.this, Main.class);
startActivity(i);
sleep(4500);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally{
finish();
}
}
};
logoTimer.start();
}
}
and activity_splash xml.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/splash" />
But when I executed it, the screen shows just black window and shows main activity after 3 seconds. I think it is becuse of image loading time of splash activity. So I added sleep(1000); before Intent i = new Intent(Splash.this, Main.class); line. And it works, but I think it is not that good solution.
I wanna know what is good solution at this situation. The purpose is showing up image while main activity is preparing the contents(It takes around 3 seconds). If there are any solutions(Loading image) instead of splash screen, please let me know.
Instead of using sleep method in Thread you can do same easily using Handler.postDelayed as:
Handler handler = new Handler();
handler.postDelayed(runnable, 1000);
Runnable runnable = new Runnable() {
#Override
public void run() {
Intent i = new Intent(Splash.this, Main.class);
startActivity(i);
handler.removeCallbacks(runnable);
}
};
How large (bytes) is your image? Perhaps the delay could be minimized by shrinking the image size/complexity with graphics tools. As a test, you could try a single color image which should be quite small. That would at least tell you whether the delay is a function of image size.
I'm trying to make a simple slideshow that fades out and fades in a few images without a button click. I had found a few examples to assist me, but I am having trouble getting the first image to fade into the second image. As of now, it just fades out and that is it. I have my code below.
fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="5000"
android:repeatCount="infinite"
/>
</set>
fade_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="5000"
android:repeatCount="infinite"
/>
</set>
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:inAnimation="#anim/fade_in"
android:outAnimation="#anim/fade_out" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/image1" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/image2" />
</ViewSwitcher>
MainClass.Activity
public class MainClass extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.next);
slideshow();
}
public void slideshow() {
ViewSwitcher switching = (ViewSwitcher)findViewById(R.id.switcher);
if (switching.getDisplayedChild() == 0) {
switching.showNext();
} else {
switching.showPrevious();
}
}
}
In that case, you need to use a timer. You use it like so:
public class MainClass extends Activity {
private Timer timer;
private ViewSwitcher switching;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.next);
switching = (ViewSwitcher)findViewById(R.id.switcher);
timer = new Timer();
timer.scheduleAtFixedRate(new NextImageTask(), 0, 5000);
//5000 is in milliseconds, meaning 5 seconds
}
public void slideshow() {
if (switching.getDisplayedChild() == 0) {
switching.showNext();
} else {
switching.showPrevious();
}
}
private class NextImageTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
slideshow();
}
});
}
}
}
What does this chunk of code do? Well, let's go at it step by step. First declare the views
private Timer timer;
private ViewSwitcher switching;
And then initialize them in the onCreate method
switching = (ViewSwitcher)findViewById(R.id.switcher);
timer = new Timer();
Then we start the timer! To start a timer and tell it what to do, we do it like so
timer.scheduleAtFixedRate(new NextImageTask(), 0, 5000);
This line of code basically means Hey timer, schedule a task at a fixed rate of 5 seconds. Start immediately!
The first argument is the task to be scheduled, an object, the NextImageTask(). This object contains a Runnable that contains the code to run every interval. The interval is a fixed rate of 5 seconds. In the code however it is written as 5000. This is because the method accepts the third argument as millisecond. To get 5 seconds, we must multiply 5 by 1,000 which results to, yep you guessed it right, 5,000. The timer is asked to start immediately by passing a second argument as 0. This is the delay. If you pass 2000 there, the timer will start after a 2 second delay. Just like the third argument, the method accepts this second argument as millisecond.
Next is the method slideshow() which is the same as the OP. This is what the OP wants to do.
Lastly is the private object, NextImageTask().
private class NextImageTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
slideshow();
}
});
}
}
This is the task that will be done by the timer at the fixed rate/every 5 seconds. It should extend TimerTask for the timer to work properly. TimerTask is an abstract class so the NextImageTask() should implement one method, the run() method. This method should contain the code that the timer will run at a fixed interval. This runs on a different thread so if you need to do something in the UI just like the OP's case, we need to run on the UI thread. This is the reason why we called runOnUiThread here. Finally, inside is another runnable calling the OP's method slideshow().
when the app opens I want the image to appear immediately and remain still for 5 seconds and then after those 5 seconds have the image slide off screen to the left, instead my image appears like I want it but as soon as it appears it immediately begins to slides off screen, I would like to achieve this animation in code and not in xml. appreciate any advice, thank you.
package your.package2.test3;
import android.app.Activity;
import android.os.Bundle;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class Test3Activity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView img = (ImageView) findViewById(R.id.img1);
AnimationSet animSet = new AnimationSet(true);
TranslateAnimation Anim1 = new TranslateAnimation(0,0,0,0);
Anim1.setDuration(5000);
TranslateAnimation Anim2 = new TranslateAnimation(0,-300,0,0);
Anim2.setDuration(2000);
animSet.addAnimation(Anim1);
animSet.addAnimation(Anim2);
img.startAnimation(animSet);
}
}
I can't think of any situations where creating a thread just to sleep a duration is a good idea. Instead, try postDelayed:
img.postDelayed(new Runnable() {
public void run() {
TranslateAnimation anim = new TranslateAnimation(0,-300,0,0);
anim.setDuration(2000);
img.startAnimation(anim);
}
}, 5000);
Use a Thread for displaying the image and the Thread.sleep(5000) method. I think this is actually the best practice in doing this kind of stuff.
Thread timer = new Thread() {
public void run(){
try{
sleep(5000);
} catch (InterruptedException e){
e.printStackTrace();
}finally{
Intent openStartingPoint = new Intent("your.package2.test3.A New Class");
startActivity(openStartingPoint);
}
}
};
timer.start();
I wanted my app to had a fading picture first before going into another page using threads. Below is the code i used and it worked well for me. However, it stops in the white page at the end of the thread. What will i do so that it will go to the next activity without clicking on anything? Or after the page turns white, what code should i use so that it will go now to the next activity?
package com.kfc;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.*;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class Intro extends Activity {
LinearLayout screen;
Handler handler = new Handler();
int i;
Intent intent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.introxml);
screen = (LinearLayout) findViewById(R.id.myintro);
(new Thread(){
#Override
public void run(){
for(i=0; i<255; i++){
handler.post(new Runnable(){
public void run(){
screen.setBackgroundColor(Color.argb(255, i, i, i));
}
});
// next will pause the thread for some time
try{ sleep(10); }
catch(Exception e){ break; }
}
for(i=255; i>0; i--){
handler.post(new Runnable(){
public void run(){
screen.setBackgroundColor(Color.argb(255, i, i, i));
}
});
// next will pause the thread for some time
try{ sleep(10); }
catch(Exception e){ break; }
}
startActivity(new Intent(Intro.this,NewKFCActivity.class));
}
}).start();
}
}
After the for loop exits. Add the code to start a new activity.
startActivity(new Intent(Intro.this,NewACtivity.class));
You need to put it outside the for loop. If you put it after start method, it will execute before the thread is completed. You may also need to scope the 'this variable' using Intro.this. Also remember to add the new activity in the manifest file as
<activity android:name=".NewActivity"/>
Just use this
screen = (FrameLayout) findViewById(R.id.layout);
(new Thread(){
#Override
public void run(){
for(i=0; i<255; i++){
handler.post(new Runnable(){
public void run(){
screen.setBackgroundColor(Color.argb(255, i, i, i));
}
});
// next will pause the thread for some time
try{ sleep(100); }
catch(Exception e){ break; }
}
startActivity(new Intent(TabTester.this,NewKFCActivity.class));
}
}).start();
this pointer should point to the Intro activity object. But inside the thread, this will refer to the the current thread object(am not sure to what it point exactly) so you need to scope it using 'Intro.this' which mean 'use this that points to the Intro activity'
You background picture will be overwritten when you use setBackgroundColor to the same view. A way to do this will be to use to layouts, the outer layout will have the background picture and the inner layout will be the one that has setBackgroundColor applied to.
Eg:
You also need to alter the code
screen.setBackgroundColor(Color.argb(255, i, i, i));
to
screen.setBackgroundColor(Color.argb(120, i, i, i));
The alpha value is set to 255 which means opaque and will not show the background image.
I wrote a splash screen. But the problem is as the splash screen shown in the screen a keyboard also invoked. What could be the possible reason for this??
Please find the image below
and the code gos as below for the activity
public class SplashActivity extends Activity{
private final int SPLASH_DISPLAY_LENGHT = 2000;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
/* New Handler to start the Menu-Activity
* and close this Splash-Screen after some seconds.*/
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent splash2 = new Intent(SplashActivity.this,SplashActivityRed.class);
SplashActivity.this.startActivity(splash2);
SplashActivity.this.finish();
overridePendingTransition(R.anim.fadein,R.anim.fadeout);
}
}, SPLASH_DISPLAY_LENGHT);
}
}
and the xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:id="#+id/imageViewSplash" android:layout_height="fill_parent" android:layout_width="fill_parent" android:background="#drawable/splash1" android:src="#drawable/splash1"></ImageView>
</LinearLayout>
PS: Sorry I had to hide the text and logo as they come under non-disclosure policy of the company I work for.
Please Remove the imageView from the Layout and add the following line the Linear Layout element
android:background="#drawable/splash1"
Like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background:"#drawable/splash1">
</LinearLayout>
Hope this helps
Also Change the implementation of the SplashScreen with above layout. To change the time line change the value of welcomeScreenDisplay to wotever you want. Currently it is 4 seconds i.e. 4000 mili seconds.
public class SplashScreen extends Activity {
String status, subscriber;
Intent i = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("FIRST");
setContentView(R.layout.splash);
System.out.println("in HOME SCREEN");
/** set time to splash out */
final int welcomeScreenDisplay = 4000;
/** create a thread to show splash up to splash time */
Thread welcomeThread = new Thread() {
int wait = 0;
#Override
public void run() {
try {
super.run();
/**
* use while to get the splash time. Use sleep() to increase
* the wait variable for every 100L.
*/
while (wait < welcomeScreenDisplay) {
sleep(100);
wait += 100;
}
} catch (Exception e) {
System.out.println("EXc=" + e);
} finally {
/**
* Called after splash times up. Do some action after splash
* times up. Here we moved to another main activity class
*/
finish();
}
}
};
welcomeThread.start();
}
}
Use this method:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
probably you need to disable the touch event for image. However as remove the imageView from the Layout and add background image to the linear layout element
android:background="#drawable/splash1"