Tạo Một Hình Nền Sinh Động trên Android Bằng Một Hình GIF Động
Vietnamese (Tiếng Việt) translation by Na Dang (you can also view the original English article)
Bạn đã từng thấy một hình GIF động đẹp, hiển thị lặp lại liên tục và bạn có tự hỏi nếu mình có thể biến nó thành một hình nền sống trên điện thoại Android của mình? À, bạn có thể đấy, và trong bài hướng dẫn này tôi sẽ chỉ cho bạn cách thực hiện.
Giới thiệu
Tạo ra một hình nền động đẹp và thú vị từ đầu sử dụng toán học và mã nguồn để tạo dựng nên các hình ảnh có thể rất tẻ nhạt và tốn thời gian. Nó cũng đòi hỏi rất nhiều sự sáng tạo. Mặt khác, tạo một hình GIF động hoặc tìm một cái trên mạng thì dễ hơn nhiều. Trong bài hướng dẫn này, bạn sẽ học cách chuyển bất kỳ hình GIF động nào thành một hình nền sinh động.
Yêu cầu bắt buộc
Hãy chắc rằng bạn cài đặt phiên bản mới nhất của Android Studio. Bạn có thể tải về từ website Android Developer.
Thậm chí bất kỳ hình GIF động nào cũng được, tôi khuyến nghị bạn tải về một hình cinemagraph. Một cinemagraph là một ảnh GIF động - thường được tạo ra từ một video - được trình diễn lặp đi lặp lại liên tục. Bạn có thể tìm thấy rất nhiều trên Flickr.
Trong bài viết này, tôi đang dùng một hình cinemagraph được tạo ra bởi người dùng djandyw.com với giấy cấp phép của Creative Commons.
1. Tạo một dự án mới
Bắt đầu Android, tạo một dự án mới, và đặt tên cho dự án GIFWallpaper. Chọn một tên package độc nhất nếu bạn dự định xuất bản ứng dụng này trên Google Play.



Thiết lập bản SDK tối thiểu đến API 8: Android 2.2 (Froyo).



Ứng dụng của chúng ta không có Activity
, vì thế chọn Add No Activity and click Finish.



2. Mô tả hình nền
Một hình nền sinh động cần một tập tin mô tả nó. Tạo một tập tin XML có tên gọi là res/xml/wallpaper.xml và thêm vào nội dung XML sau đây:
<?xml version="1.0" encoding="UTF-8"?> <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:label="GIF Wallpaper" android:thumbnail="@drawable/ic_launcher"> </wallpaper>
Label và Thumbnail đặc biệt quan trọng khi được dùng đến khi hình nền hiền thị trên danh sách các hình nền đang có trong thiết bị của bạn.
3. Chỉnh sửa Manifest
Để chạy một hình nền sống động, ứng bạn của bạn cần một sự cho phép. android.permission.BIND_WALLPAPER.
Một hình nền sống động hoạt động như một Service
có thể nhận android.service.wallpaper.WallpaperService
intent action (yêu cầu hành động). Đặt tên Service
GIFWallpaperService và bổ sung vào trong manifest của dự án, AndroidManifest.xml
<service android:name=".GIFWallpaperService" android:enabled="true" android:label="GIF Wallpaper" android:permission="android.permission.BIND_WALLPAPER" > <intent-filter> <action android:name="android.service.wallpaper.WallpaperService"/> </intent-filter> <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" > </meta-data> </service>
Tiếp đến, để chắc rằng ứng dụng có thể cài đặt được chỉ trên những thiết bị có thể dùng hình nền sinh động, thêm dòng sau vào manifest:
<uses-feature android:name="android.software.live_wallpaper" android:required="true" > </uses-feature>
4. Thêm hình GIF động
Copy hình GIF động bạn tải về từ Flickr vào thư mục assets của dự án. Tôi đặt tên hình GIF là girl.gif.
5. Tạo Service
Tạo mới một Java class và đặt tên nó là GIFWallpaperService.java. Class nên extend WallpaperService
class.
public class GIFWallpaperService extends WallpaperService { }
Bởi vì WallpaperService
là một abstract class, bạn phải override phương thức onCreateEngine
của nó và trả về một giá trí của Engine
riêng của bạn, dùng để có thể hiển thị các khung hình của hình GIF động.
Để dùng hình GIF động, bạn đầu tiên phải đổi nó sang một object Movie
. Bạn có thể sử dụng Movie
class có phương thức decodeStream
để làm điều này. Một khi object Movie
đã được tạo ra, đưa nó vào như một parameter (tham số) của constructor của Engine
.
Phương thức onCreateEngine
sẽ trông giống thế này:
@Override public WallpaperService.Engine onCreateEngine() { try { Movie movie = Movie.decodeStream( getResources().getAssets().open("girl.gif")); return new GIFWallpaperEngine(movie); }catch(IOException e){ Log.d("GIF", "Could not load asset"); return null; } }
6. Tạo Engine
Hãy bắt đầu làm việc với Engine
ngay bây giờ: Tạo một class đặt tên là GIFWallpaperEngine bên trong class GIFWallpaperService
và cho nó extend WallpaperService.Engine
Thếm cái fields sau đây vào class mới:
-
frameDuration
: số integer này đại diện cho độ trễ giữa các hoạt động vẽ lại. Một giá trị của 20 cho bạn 50 khung hình mỗi giây. -
visible
: giá trị boolean cho engine biết nếu hình nền đang được hiển thị trên màn hình. Điều này rất quan trọng, bởi chúng ta không nên vẽ hình nền khi nó không thể được hiển thị. -
movie
: đây là hình GIF động trong hình thái của một objectMovie
. -
holder
: đề cập đến objectSurfaceHolder
có sẵn của engine. Nó phải được khởi tạo bằng các override phương thứconCreate
. -
handler
: đây là một objectHandler
sẽ được dùng để khởi động mộtRunnable
- chịu trách nhiệm vẽ hình nền.
Class của bạn nên giống thề này:
private class GIFWallpaperEngine extends WallpaperService.Engine { private final int frameDuration = 20; private SurfaceHolder holder; private Movie movie; private boolean visible; private Handler handler; public GIFWallpaperEngine(Movie movie) { this.movie = movie; handler = new Handler(); } @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); this.holder = surfaceHolder; } }
Tiếp theo, tạo một phương thức có tên draw
- vẽ nội dụng của hình GIF động. Hãy chia nhỏ phương thức này ra:
- Đầu tiên kiểm tra nếu biến
visible
được xét làtrue
. Chúng chỉ tiếp tục nếu đúng như thế. - Sử dụng phương thức
lockCanvas
củaSurfaceHolder
để tạo mộtCanvas
để vẽ. - Vẽ một khung hình của hình GIF động trên
Canvas
sau khi phóng to và đinh vị nó. - Một khi các hình vẽ hoàn tất, đưa
Canvas
trở vềSurfaceHolder
. - Cập nhật khung hình hiện tại của hình GIF động đang sử dụng phương thức
setTime
của objectMovie
. - Gọi phương thức một lần nữa sử dụng
handler
sau khi đợi giá trị phần ngàn giâyframeDuration
.
Phương thức draw
chưa bao giợ được gọi trực tiếp. Nó luôn được gọi sử dụng một đối tượng Handler
và một đối tượng Runnable
. Do đó, hãy làm object Runnable
là một field của class và gọi nó là drawGIF
.
Bổ dung vào đoạn code sau đây cho class GIFWallpaperService
:
private Runnable drawGIF = new Runnable() { public void run() { draw(); } }; private void draw() { if (visible) { Canvas canvas = holder.lockCanvas(); canvas.save(); // Adjust size and position so that // the image looks good on your screen canvas.scale(3f, 3f); movie.draw(canvas, -100, 0); canvas.restore(); holder.unlockCanvasAndPost(canvas); movie.setTime((int) (System.currentTimeMillis() % movie.duration())); handler.removeCallbacks(drawGIF); handler.postDelayed(drawGIF, frameDuration); } }
Phương thức onVisibilityChanged
được tự động gọi bất cứ khi nào sự hiển thị của hình nền thay đổi. Chúng ta cần override nó, dựa trên giá trị của tham số visible
, hoặc bắt đầu hoặc dừng lại drawGIF
. Phương thức removeCallbacks
của Handler
được sử dụng để dừng bất kỳ lượt chạy drawGIF
đang tạm dừng.
@Override public void onVisibilityChanged(boolean visible) { this.visible = visible; if (visible) { handler.post(drawGIF); } else { handler.removeCallbacks(drawGIF); } }
Sau cùng, override phương thức onDestroy
của Engine
để dừng bất cứ hoạt động drawGIF
đang đợi nếu hình nền bị vô hiệu hoá.
@Override public void onDestroy() { super.onDestroy(); handler.removeCallbacks(drawGIF); }
7. Biên dịch và cài đặt
Hình nền của bạn đã sẵn sàng. Biên dịch và cài đặt nó trên thiết bị Android của bạn. Một khi được cài đặt, bạn có thể tìm hình nền trong danh sách các hình nền đang có.
Hầu hết những launcher cho bạn một lựa chọn để thay đổi hình nền sau một cử động long tap. Mặt khác, bạn có thể đền phần cấu hình hiển thị để thay đổi hình nền.



Nếu hình GIF quá nhỏ hoặc không được định vị đúng, vậy thì trở lại phương thức draw
và điều chỉnh vị trí và tỷ lệ.
Tóm Tắt
Giờ bạn biết làm cách nào để dùng hình động GIF để tạo ra một wallpaper sinh động. Hãy tự do trải nghiệm với thêm nhiều hình GIFs. Nếu bạn có kế hoạch xuất bản hình nền của bạn trên Goolge Play, hãy chắc bạn có sự đồng ý của người tạo ra để hình GIF động đã được thương mại. Thăm website Android Developer để học thêm về class WallpaperService