Monday, September 10, 2018

Example Aquarium Live Wallpaper on Android - Live Wallpaper Android

Today I will guide you on how to create Aquarium live wallpaper on android most detailed and most specific.

Slep 1 : Create class Aquarium

public class Aquarium {
    private AquariumThread _aquariumThread;
    private SurfaceHolder _surfaceHolder;
    private ArrayList<Renderable> _fishes;
    public Bitmap _backgroundImage;
    private Context _context;

    public void render(){
        Canvas canvas = null;

        try{

            canvas = this._surfaceHolder.lockCanvas(null);
            synchronized (this._surfaceHolder) {
                this.onDraw(canvas);
            }

        }finally{
            if(canvas != null){
                this._surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }
    }

    protected void onDraw(Canvas canvas) {
        this.renderBackGround(canvas);
        for (Renderable renderable : this._fishes) {
            renderable.render(canvas);
        }
    };

    public void start(){
        this._aquariumThread.switchOn();
    }

    public void stop(){
        boolean retry = true;
        this._aquariumThread.switchOff();
        while (retry) {
            try {
                this._aquariumThread.join();
                retry = false;
            } catch (InterruptedException e) {
                // we will try it again and again...            }
        }
    }

    public int getLeft() {
        return 0;
    }

    public int getRight() {
        return this._backgroundImage.getWidth();
    }

    public void initialize(Context context, SurfaceHolder surfaceHolder) {
        this._aquariumThread = new AquariumThread(this);
        this._surfaceHolder = surfaceHolder;
        this._fishes = new ArrayList<Renderable>();
        this._context = context;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPurgeable = true;
        this._backgroundImage = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.aquarium, options);
        this.addFishes();
    }

    private void addFishes() {
        Point startPoint = new Point(50, 700);
        this._fishes.add(new ClownFish(this._context, this, startPoint, 90));

        Point startPoint1 = new Point(150, 500);
        this._fishes.add(new ClownFish(this._context, this, startPoint1, 70));

        Point startPoint2 = new Point(250, 300);
        this._fishes.add(new ClownFish(this._context, this, startPoint2, 50));

        // moi them        Point startPoint3 = new Point(350, 250);
        this._fishes.add(new ClownFish(this._context, this, startPoint3, 40));

        Point startPoint4 = new Point(450, 200);
        this._fishes.add(new ClownFish(this._context, this, startPoint4, 15));


    }

    private void renderBackGround(Canvas canvas)
    {
        canvas.drawBitmap(this._backgroundImage, 0, 0, null);
    }
}
Step 2: Create class AquariumThread extends Thread
public class AquariumThread extends Thread {

    private Aquarium _aquarium;
    private boolean _running;

    public AquariumThread(Aquarium aquarium) {
        this._aquarium = aquarium;
    }

    public void switchOn(){
        this._running = true;
        this.start();
    }

    public void pause(){
        this._running = false;
        synchronized(this){
            this.notify();
        }
    }

    public void switchOff(){
        this._running = false;
        synchronized(this){
            this.notify();
        }
    }

    @Override    public void run() {
        while(this._running){
            this._aquarium.render();
        }
    }
}
Step 3: Create Interface Renderable
public interface Renderable {
    void render(Canvas canvas);
}
Step 4: Create class FishSprite

public class FishSprite {

    /**     * Private fields     */    private Bitmap _currentSpriteBitmap;
    private Rect _drawRect;
    private int _fps;
    private int _noOfFrames;
    private int _currentFrame;
    private long _timer;
    private int _spriteWidth;
    private int _spriteHeight;
    private Point _position;

    public FishSprite(Bitmap spriteBitmap, int fps, int frameCount, Point startPoint) {

        this.initialize();

        this._position = startPoint;
        this._currentSpriteBitmap = spriteBitmap;
        this._spriteHeight = spriteBitmap.getHeight();
        this._spriteWidth = spriteBitmap.getWidth() / frameCount;
        this._drawRect = new Rect(0,0, this._spriteWidth, this._spriteHeight);
        this._fps = 1000 / fps;
        this._noOfFrames = frameCount;
    }


    private void initialize() {
        this._drawRect = new Rect(0,0,0,0);
        this._timer = 0;
        this._currentFrame = 0;
    }

    private void Update(long currentTime) {
        if(currentTime > this._timer + this._fps ) {
            this._timer = currentTime;
            this._currentFrame +=1;

            if(this._currentFrame >= this._noOfFrames) {
                this._currentFrame = 0;
            }
        }

        this._drawRect.left = this._currentFrame * this._spriteWidth;
        this._drawRect.right = this._drawRect.left + this._spriteWidth;
    }

    public void render(Canvas canvas, long currentTime) {

        this.Update(currentTime);

        Rect dest = new Rect(getXPos(), getYPos(), getXPos() + this._spriteWidth,
                getYPos() + this._spriteHeight);

        canvas.drawBitmap(this._currentSpriteBitmap, this._drawRect, dest, null);
    }

    public Point getPosition() {
        return _position;
    }

    public void setPosition(Point position) {
        this._position = position;
    }

    public int getYPos() {
        return this._position.y;
    }

    public int getXPos() {
        return this._position.x;
    }

    public void setYPos(int y) {
        this._position.y = y;
    }

    public void setXPos(int x) {
        this._position.x = x;
    }

    public int getWidth(){
        return this._spriteWidth;
    }

    public int getHeight(){
        return this._spriteHeight;
    }
}
Stempt 5: Create a class AquaticAnimal
public abstract class AquaticAnimal implements Renderable {

    private static int MAX_SPEED = 100;
    private Context _context;
    private Aquarium _aquarium;
    private FishSprite _leftSprite;
    private FishSprite _rightSprite;

    private int _direction = -1;
    private int _speedFraction;
    private long _previousTime;

    public AquaticAnimal(Context context, Aquarium aquarium){
        this._context = context;
        this._aquarium = aquarium;
    }

    protected void initialize(Bitmap leftBitmap, Bitmap rightBitmap,
                              int fps, int totalFrames, Point startPoint, int speed){
        this._leftSprite = new FishSprite(leftBitmap, fps, totalFrames, startPoint);
        this._rightSprite = new FishSprite(rightBitmap, fps, totalFrames, startPoint);
        this._speedFraction = (MAX_SPEED / speed) * 10;
    }

    private FishSprite getSprite(){
        if(this._direction < 0){
            return this._leftSprite;
        }
        return this._rightSprite;
    }

    public int getDirection(){
        FishSprite sprite = this.getSprite();
        int xPos = sprite.getXPos();
        if(this._direction < 0){
            xPos += sprite.getWidth();
        }
        if(xPos < this._aquarium.getLeft()){
            this._direction = 1;
        }else if(xPos > this._aquarium.getRight()){
            this._direction = -1;
        }else{
            // Do nothing        }

        return this._direction;
    }

    public Context getContext(){
        return this._context;
    }

    public Aquarium getAquarium(){
        return this._aquarium;
    }

    @Override    public void render(Canvas canvas){
        long currentTime = System.currentTimeMillis();
        this.getSprite().render(canvas, currentTime);
        this.swim(currentTime);
    }

    public void swim(long currentTime){
        long diff = currentTime - this._previousTime;
        if(diff > this._speedFraction){
            int currentX = this.getSprite().getXPos();
            this.getSprite().setXPos(currentX + this.getDirection());
            this._previousTime = currentTime;
        }
    }
}
Stemp 6: Create a class ClownFish
public class ClownFish  extends AquaticAnimal {
    private static final int TOTAL_FRAMES_IN_SPRITE = 20;
    private static final int CLOWN_FISH_FPS = 20;

    public ClownFish(Context context, Aquarium aquarium, Point startPoint, int speed){
        super(context, aquarium);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPurgeable = true;
        Bitmap leftBitmap = BitmapFactory.decodeResource(getContext().getResources(),
                R.drawable.left, options);
        BitmapFactory.Options options1 = new BitmapFactory.Options();
        options1.inPurgeable = true;
        Bitmap rightBitmap = BitmapFactory.decodeResource(getContext().getResources(),
                R.drawable.right , options1);
        this.initialize(leftBitmap, rightBitmap, CLOWN_FISH_FPS, TOTAL_FRAMES_IN_SPRITE,
                startPoint, speed);
    }

    public void render(Canvas canvas){
        super.render(canvas);
    }
}
Stemp 7: Create service by a class AquariumWallpaperService
public class AquariumWallpaperService extends WallpaperService {

    @Override    public Engine onCreateEngine() {
        return new AquariumWallpaperEngine();
    }

    class AquariumWallpaperEngine extends Engine{

        private Aquarium _aquarium;

        public AquariumWallpaperEngine() {
            this._aquarium = new Aquarium();
            this._aquarium.initialize(getBaseContext(), getSurfaceHolder());
        }

        @Override        public void onVisibilityChanged(boolean visible) {
            if(visible){
                this._aquarium.render();
            }
        }

        @Override        public void onSurfaceChanged(SurfaceHolder holder, int format,
                                     int width, int height) {
            super.onSurfaceChanged(holder, format, width, height);
        }

        @Override        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
            this._aquarium.start();
        }

        @Override        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            this._aquarium.stop();
        }

        @Override        public void onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);

            float x = event.getX();
            float y = event.getY();
            Log.d("anhtt","x = " +x +" yy == " +y);

        }
    }
}

Stemp 8: Setting file Manifest.xml
<application    android:allowBackup="true"    android:icon="@mipmap/ic_launcher"    android:label="@string/app_name"    android:roundIcon="@mipmap/ic_launcher_round"    android:supportsRtl="true"    android:theme="@style/AppTheme">
    <service        android:name=".demo.AquariumWallpaperService"        android:enabled="true"        android:label="Wallpaper Example"        android:permission="android.permission.BIND_WALLPAPER">
        <intent-filter>
            <action android:name="android.service.wallpaper.WallpaperService">
            </action>
        </intent-filter>

        <meta-data            android:name="android.service.wallpaper"            android:resource="@xml/mywallpaper">
        </meta-data>
    </service>

    <activity        android:name=".wallpaper.MyPreferencesActivity"        android:exported="true"        android:label="@string/app_name"        android:theme="@android:style/Theme.Light.WallpaperSettings">
    </activity>

    <activity        android:name=".MainActivity"        android:label="@string/app_name"        android:theme="@android:style/Theme.Light.WallpaperSettings">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

</application>

<uses-feature    android:name="android.software.live_wallpaper"    android:required="true">
</uses-feature>
Step 9: Create file xml by Wallpaper.xml and presf.xml
<?xml version="1.0" encoding="utf-8"?><wallpaper    xmlns:android="http://schemas.android.com/apk/res/android"    android:description="@string/app_name"    android:settingsActivity="com.anhttvn.fishlivewallpaper.wallpaper.MyPreferencesActivity"
    android:thumbnail="@mipmap/ic_launcher"/>

Image Aquarium, fish left and fish right you can download below



No comments:

Post a Comment