標籤:android style class blog code java
昨天在給用戶端做天氣展示頁面的時候,發現很多app的天氣頁面背景圖片都會緩慢移動,形成了一種3d的感覺。例如下雨,靜態圖片緩慢移動,雨滴位置變換感覺就真的在下雨。雲朵的移動也很酷。於是研究了一下午。寫了一個自訂view控制項。
我的自訂控制項繼承了view,重寫ondraw方法。本人C#轉android才3個月,以下代碼如有錯或者有可以改進的地方,請各位在評論中指出。望不吝賜教!
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
/** * 圖片跑馬燈,圖片無限迴圈滾動效果控制項 * 圖片長寬必須大於手機長寬,否則會報錯退出 * @author sy */ public class MarqueeImageView extends View { // 背景圖片 Bitmap back; int nowX = 0; int backWidth; int vw; int vh; int speed; public MarqueeImageView(Context context) { super(context); } public MarqueeImageView(Context context, AttributeSet attrs) { super(context, attrs); } public MarqueeImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } // 啟動 public void Start(Bitmap backMap, Window windows) { int h = backMap.getHeight(); int w = backMap.getWidth(); // 擷取裝置高度和寬度 Rect frame = new Rect(); windows.getDecorView().getWindowVisibleDisplayFrame(frame);<br> vh = frame.height(); vw = frame.width(); // 設定捲動速度 speed = 1; //裁剪一下 back = Bitmap.createBitmap(backMap, 0, 0, backMap.getWidth(), vh); backWidth = back.getWidth(); final Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 0x123) { // 該函數的作用是使整個視窗客戶區無效。視窗的客戶區無效意味著需要重繪 invalidate(); } } }; new Timer().schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(0x123); } }, 0, 80); } @Override protected void onDraw(Canvas canvas) { int w = backWidth - nowX; if (vw <= w) { // 圖片剩餘寬度大於螢幕寬度,從原圖上截取螢幕視窗大小的一塊地區 Bitmap bitmap = Bitmap.createBitmap(back, nowX, 0, vw, vh); canvas.drawBitmap(bitmap, 0, 0, null); } else { Bitmap bitmap = Bitmap.createBitmap(back, nowX, 0, w, vh); canvas.drawBitmap(bitmap, 0, 0, null); Bitmap bitmap2 = Bitmap.createBitmap(back, 0, 0, vw - w, vh); canvas.drawBitmap(bitmap2, w, 0, null); } if (nowX + speed >= backWidth) { nowX = 0; } else { nowX += speed; } } } |
使用這個控制項的前提是原圖大小一定要大於顯示地區,不然滾動就沒有意義,變成平鋪了。
說下思路。滾動初始時,原圖就上就能截取到滿足顯示地區大小的圖片。所以這時,我在ondraw裡面直接從原圖產生一個新的bitmap,然後畫到canvas上就行了。
滾動的臨界點之一是當原圖的右上方和顯示地區的右上方重合時,這意味著下一次調用ondraw,從原圖截取出來的bitmap已經不能填滿整個地區,這時需要再從原圖中截取一次bitmap,2張圖片拼接起來佔滿整個顯示地區。如果是從左向右滾動圖片,臨界點後,第一次截取的是原圖右邊界部分圖片,第二次截取的是左邊界部分圖片。這樣看上去就是一張圖片無限滾動了。
第二個臨界點是原圖的右上方和顯示地區的左上方重合。這意味著已經完成一次原圖的滾動了。這時就不需要再用兩張圖片拼接填滿顯示地區了,只需要從原圖的左上方開始截取顯示地區大小的一塊即可。這時才算完成了無限滾動。
這個控制項目前只能滾動一張圖片,不過稍微改一改也可以做成畫廊控制項。加入手勢控制應該可以做一個不錯的圖片瀏覽器。不過先就這樣吧~有時間有需求再改!