Δημιουργήστε Μια 'Ζωντανή' Ταπετσαρία για το Android, Χρησιμοποιώντας ένα Κινούμενο GIF
() translation by (you can also view the original English article)
Έτυχε ποτέ να δείτε ένα πανέμορφο κινούμενο GIF που επαναλαμβάνεται απρόσκοπτα και να αναρωτηθείτε αν μπορείτε να το χρησιμοποιήσετε ως μια 'ζωντανή' ταπετσαρία για την Android συσκευή σας; Λοιπόν, μπορείτε να το κάνετε, και σε αυτό το σεμινάριο θα σας δείξω πώς.
Εισαγωγή
Η δημιουργία μιας ενδιαφέρουσας και όμορφης ζωντανής ταπετσαρίας από το μηδέν, χρησιμοποιώντας μόνο μαθηματικά και κώδικα για να δημιουργήσετε τα γραφικά σας μπορεί να είναι κουραστική και χρονοβόρα. Απαιτεί επίσης πολλή δημιουργικότητα. Από την άλλη πλευρά, η δημιουργία ενός κινούμενου GIF ή η εύρεση κάποιου online είναι ευκολότερη. Σε αυτό το σεμινάριο, θα έχετε την ευκαιρία να μάθετε πώς μπορείτε να μετατρέψετε οποιοδήποτε κινούμενο GIF σε μια ζωντανή ταπετσαρία.
Προαπαιτούμενα
Βεβαιωθείτε ότι έχετε εγκατεστημένη την τελευταία έκδοση του Android Studio. Μπορείτε να το βρείτε από την ιστοσελίδα Android Developer.
Ακόμα κι αν οποιοδήποτε κινούμενο GIF θα αρκέσει, σας προτείνω να κατεβάσετε ένα καλό cinemagraph. Ένα cinemagraph δεν είναι τίποτα άλλο από ένα κινούμενο GIF — συνήθως δημιουργούνται από ένα βίντεο — που επαναλαμβάνεται απρόσκοπτα. Μπορείτε να βρείτε πολλά καλά παραδείγματα στο Flickr.
Για αυτό το σεμινάριο, χρησιμοποιώ ένα cinemagraph που δημιουργήθηκε από το Flickr χρήστη djandyw.com, αφού είναι διαθέσιμα υπό την άδεια Creative Commons.
1. Δημιουργήστε ένα νέο Project
Ξεκινήστε το Android Studio, δημιουργήστε ένα νέο project και ονομάστε το GIFWallpaper. Διαλέξτε ένα μοναδικό όνομα πακέτοy αν σκοπεύετε να δημοσιεύσετε αυτό το app στο Google Play.



Ορίστε το ελάχιστο SDK σε API 8: Android 2.2 (Froyo).



Το app μας δεν πρόκειται να έχει ένα Activity
, έτσι επιλέξτε Add No Activity και κάντε κλικ στο κουμπί Finish.



2. Περιγράψτε την Ταπετσαρία
Μια ζωντανή ταπετσαρία χρειάζεται ένα αρχείο που την περιγράφει. Δημιουργήστε ένα νέο αρχείο XML που ονομάζεται res/xml/wallpaper.xml και αντικαταστήστε το περιεχόμενό της με την παρακάτω XML:
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<wallpaper
|
3 |
xmlns:android="http://schemas.android.com/apk/res/android" |
4 |
android:label="GIF Wallpaper" |
5 |
android:thumbnail="@drawable/ic_launcher"> |
6 |
</wallpaper>
|
Η ετικέτα και η μικρογραφία, είναι ιδιαίτερα σημαντικές καθώς θα χρησιμοποιηθούν όταν η ταπετσαρία θα εμφανίζονται στη λίστα από τις ταπετσαρίες που είναι διαθέσιμες στη συσκευή σας.
3. Επεξεργαστείτε το Manifest
Για να τρέξει ως μια ζωντανή ταπετσαρία, η εφαρμογή μας χρειάζεται μόνο το δικαίωμα, android.permission.BIND_WALLPAPER
.
Μια ζωντανή ταπετσαρία εκτελείται ως μια υπηρεσία Service
που μπορεί να λάβει το intent action android.service.wallpaper.WallpaperService
. Ονομάστε το Service
GIFWallpaperService και προσθέστε το στο manifest του έργου, AndroidManifest.xml.
1 |
<service
|
2 |
android:name=".GIFWallpaperService" |
3 |
android:enabled="true" |
4 |
android:label="GIF Wallpaper" |
5 |
android:permission="android.permission.BIND_WALLPAPER" > |
6 |
<intent-filter>
|
7 |
<action android:name="android.service.wallpaper.WallpaperService"/> |
8 |
</intent-filter>
|
9 |
<meta-data
|
10 |
android:name="android.service.wallpaper" |
11 |
android:resource="@xml/wallpaper" > |
12 |
</meta-data>
|
13 |
</service>
|
Στη συνέχεια, για να βεβαιωθείτε ότι η εφαρμογή μπορεί να εγκατασταθεί μόνο σε συσκευές που μπορούν να τρέξουν ζωντανές ταπετσαρίες, προσθέστε το ακόλουθο απόσπασμα μέσα στο manifest:
1 |
<uses-feature
|
2 |
android:name="android.software.live_wallpaper" |
3 |
android:required="true" > |
4 |
</uses-feature>
|
4. Προσθέστε κινούμενες εικόνες GIF
Αντιγράψτε το κινούμενο GIF που κατεβάσατε από το Flickr στο φάκελο στοιχείων assets του έργου. Έχω ονομάσει το GIF girl.gif.
5. Δημιουργήστε την Υπηρεσία
Δημιουργήστε μια νέα κλάση Java και ονομάστε την GIFWallpaperService.java. Αυτή η κλάση θα πρέπει να επεκτείνει την κλάση WallpaperService
.
1 |
public class GIFWallpaperService extends WallpaperService { |
2 |
|
3 |
}
|
Επειδή το WallpaperService
είναι μια αφηρημένη κλάση, πρέπει να κάνετε override στη onCreateEngine
μέθοδό της και να επιστρέψετε ένα στιγμιότυπο ενός δικού σας Engine
, το οποίο μπορεί να αποδώσει τα καρέ του GIF.
Για να χρησιμοποιήσετε το κινούμενο GIF, πρέπει πρώτα να το μετατρέψετε σε ένα αντικείμενο Movie
. Μπορείτε να χρησιμοποιήσετε την μέθοδο decodeStream
της κλάσης Movie
για να το επιτύχετε. Μόλις δημιουργηθεί το αντικείμενο Movie
, περάστε το ως παράμετρο στον κατασκευαστή του προσαρμοσμένου Engine
.
Έτσι θα πρέπει να μοιάζει η μέθοδος onCreateEngine
:
1 |
@Override
|
2 |
public WallpaperService.Engine onCreateEngine() { |
3 |
try { |
4 |
Movie movie = Movie.decodeStream( |
5 |
getResources().getAssets().open("girl.gif")); |
6 |
|
7 |
return new GIFWallpaperEngine(movie); |
8 |
}catch(IOException e){ |
9 |
Log.d("GIF", "Could not load asset"); |
10 |
return null; |
11 |
}
|
12 |
}
|
6. Δημιουργία της Μηχανής
Ας ξεκινήσουμε να δουλεύουμε πάνω στο Engine
. Δημιουργήστε μια κλάση που θα ονομάζεται GIFWallpaperEngine στο εσωτερικό της κλάσης GIFWallpaperService
και θα επεκτείνει την WallpaperService.Engine
.
Προσθέστε τα παρακάτω πεδία σε αυτήν την νέα κλάση:
-
frameDuration
: αυτός ο ακέραιος αντιπροσωπεύει την καθυστέρηση μεταξύ των διαδικασιών της επανασχεδίασης. Η τιμή 20 σας δίνει 50 καρέ ανά δευτερόλεπτο. -
visible
: αυτή η δυαδική τιμή επιτρέπει στη μηχανή (engine) να ξέρει αν η ζωντανή ταπετσαρία είναι ορατή αυτή τη στιγμή στην οθόνη. Αυτό είναι σημαντικό, επειδή δε θα πρέπει να σχεδιάζουμε την ταπετσαρία όταν δεν είναι ορατή. -
movie
: αυτό είναι το κινούμενο GIF με τη μορφή ενός αντικειμένουMovie
. -
holder
: Αυτό αναφέρεται στο αντικείμενοSurfaceHolder
που είναι διαθέσιμο στη μηχανή. Πρέπει να αρχικοποιηθεί, κάνοντας override τη μέθοδοonCreate
. -
handler
: αυτό είναι ένα αντικείμενοHandler
που θα χρησιμοποιηθεί για να ξεκινήσετε έναRunnable
που είναι υπεύθυνο για τον ίδιο το σχεδιασμό της ταπετσαρίας.
Η κλάση σας θα πρέπει τώρα να μοιάζει κάπως έτσι:
1 |
private class GIFWallpaperEngine extends WallpaperService.Engine { |
2 |
private final int frameDuration = 20; |
3 |
|
4 |
private SurfaceHolder holder; |
5 |
private Movie movie; |
6 |
private boolean visible; |
7 |
private Handler handler; |
8 |
|
9 |
public GIFWallpaperEngine(Movie movie) { |
10 |
this.movie = movie; |
11 |
handler = new Handler(); |
12 |
}
|
13 |
|
14 |
@Override
|
15 |
public void onCreate(SurfaceHolder surfaceHolder) { |
16 |
super.onCreate(surfaceHolder); |
17 |
this.holder = surfaceHolder; |
18 |
}
|
19 |
}
|
Έπειτα, δημιουργήστε μια μέθοδο που ονομάζεται draw
που σχεδιάζει τα περιεχόμενα του κινούμενου GIF. Ας δούμε λεπτομερώς από τί αποτελείται αυτή η μέθοδος:
- Ελέγχουμε πρώτα αν η μεταβλητή
visible
έχει οριστεί στην τιμήtrue
. Συνεχίζουμε μόνο εάν έχει γίνει αυτό. - Χρησιμοποιήστε τη μέθοδο
lockCanvas
τουSurfaceHolder
για να αποκτήσετε έναCanvas
πάνω στο οποίο μπορείτε να σχεδιάσετε. - Σχεδιάστε ένα καρέ από το κινούμενο GIF στον καμβά
Canvas
μετά την κλιμάκωση και την τοποθέτηση του. - Μόλις τελειώσει ο σχεδιασμός, περνάμε το
Canvas
πίσω στοSurfaceHolder
. - Ενημερώστε το τρέχον καρέ από το κινούμενο GIF, χρησιμοποιώντας τη μέθοδο
setTime
του αντικειμένουMovie
. - Καλέστε τη μέθοδο ξανά χρησιμοποιώντας το
handler
μετά από αναμονή για τόσα χιλιοστά του δευτερολέπτου όσα τοframeDuration
.
H μέθοδος draw
δεν καλείται ποτέ απευθείας. Πάντα καλείται χρησιμοποιώντας ένα Handler
και ένα αντικείμενο Runnable
. Επομένως, ας κάνουμε το αντικείμενο Runnable
ένα πεδίο της κλάσης και ας την καλέσουμε drawGIF
.
Προσθέστε τον ακόλουθο κώδικα στην κλάση GIFWallpaperService
:
1 |
private Runnable drawGIF = new Runnable() { |
2 |
public void run() { |
3 |
draw(); |
4 |
}
|
5 |
};
|
6 |
|
7 |
private void draw() { |
8 |
if (visible) { |
9 |
Canvas canvas = holder.lockCanvas(); |
10 |
canvas.save(); |
11 |
// Adjust size and position so that
|
12 |
// the image looks good on your screen
|
13 |
canvas.scale(3f, 3f); |
14 |
movie.draw(canvas, -100, 0); |
15 |
canvas.restore(); |
16 |
holder.unlockCanvasAndPost(canvas); |
17 |
movie.setTime((int) (System.currentTimeMillis() % movie.duration())); |
18 |
|
19 |
handler.removeCallbacks(drawGIF); |
20 |
handler.postDelayed(drawGIF, frameDuration); |
21 |
}
|
22 |
}
|
Η μέθοδος onVisibilityChanged
καλείται αυτόματα κάθε φορά που αλλάζει η ορατότητα της ταπετσαρίας. Πρέπει το κάνουμε override και, με βάση την τιμή του ορίσματος visible
, είτε να ξεκινήσουμε ή να σταματήσουμε το drawGIF
. Για να σταματήσετε οποιαδήποτε εκκρεμή περάσματα του drawGIF
, χρησιμοποιείται η μέθοδος removeCallbacks
του Handler
.
1 |
@Override
|
2 |
public void onVisibilityChanged(boolean visible) { |
3 |
this.visible = visible; |
4 |
if (visible) { |
5 |
handler.post(drawGIF); |
6 |
} else { |
7 |
handler.removeCallbacks(drawGIF); |
8 |
}
|
9 |
}
|
Τέλος, κάντε override τη μέθοδο onDestroy
της μηχανής Engine
για να σταματήσετε οποιαδήποτε εκκρεμή drawGIF
περάσματα εάν είναι απενεργοποιηµένη η ταπετσαρία.
1 |
@Override
|
2 |
public void onDestroy() { |
3 |
super.onDestroy(); |
4 |
handler.removeCallbacks(drawGIF); |
5 |
}
|
7. Κάντε Compile και Εγκαταστήστε
Η ζωντανή ταπετσαρία σας είναι τώρα έτοιμη. Μεταγλωττίστε και εγκαταστήστε το στην Android συσκευή σας. Μόλις εγκατασταθεί, θα πρέπει να μπορείτε να βρείτε την ταπετσαρία στη λίστα διαθέσιμων ταπετσαριών.
Οι περισσότεροι εκκινητές σας δίνουν την επιλογή να αλλάξετε την ταπετσαρία, μετά από μια κίνηση μακράς αφής (long tap) Εναλλακτικά, μπορείτε να πάτε στις ρυθμίσεις οθόνης για να αλλάξετε την ταπετσαρία.



Αν το GIF φαίνεται πάρα πολύ μικρό ή δεν είναι τοποθετημένο σωστά, τότε να επιστρέψετε στη μέθοδο draw
και να ρυθμίσετε το μέγεθος και τη θέση.
Συμπέρασμα
Ξέρετε τώρα πώς να χρησιμοποιήσετε ένα κινούμενο GIF για να δημιουργήσετε μια 'ζωντανή' ταπετσαρία. Μη διστάσετε να πειραματιστείτε με περισσότερες εικόνες GIF. Εάν σχεδιάζετε να δημοσιεύσετε την ζωντανή ταπετσαρία σας στο Google Play, βεβαιωθείτε ότι έχετε την άδεια του δημιουργού για εμπορική χρήση του κινούμενου GIF. Επισκεφθείτε την ιστοσελίδα Android Developer για να μάθετε περισσότερα σχετικά με την κλάση WallpaperService
.