Android 動態背景的實現以及SurfaceView中添加EditText控件


  首先還是一貫作風,我們先看案例:

\

   靜態圖看不出來效果,如果用過此軟件(扎客)的同學們都知道,她的背景會動.怎么樣,是不是覺得很時尚,起碼比靜態的要好(個人觀點).其實實現起來並不復雜,這個如果讓做游戲程序員做簡直太小兒科了,這里我說明一點,其實我們做應用的也應該多少了解下游戲編程思維,起碼對我們做應用有很好的幫助.

    下面我簡單介紹下實現方式.
    實現原理:自定義一個SurfaceView控件.對之不停的onDraw,使得其背景動起來.
    對於SurfaceView如果不了解的同學們麻煩你先上網查找下,網上相關介紹很多.
    這里我簡單介紹下其功能:首先這個 控件是View的子類.好處就是可以在線程中(非UI線程)對UI進行更新.
MySurfaceView.java
package com.jj.dynamic;  
  
import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.Canvas;  
import android.graphics.Color;  
import android.graphics.Paint;  
import android.graphics.PorterDuff;  
import android.util.AttributeSet;  
import android.view.SurfaceHolder;  
import android.view.SurfaceView;  
import android.view.SurfaceHolder.Callback;  
  
public class MySurfaceView extends SurfaceView implements Callback, Runnable {  
    private Context mContext;  
    private SurfaceHolder surfaceHolder;  
    private boolean flag = false;// 線程標識  
    private Bitmap bitmap_bg;// 背景圖  
  
    private float mSurfaceWindth, mSurfaceHeight;// 屏幕寬高  
  
    private int mBitposX;// 圖片的位置  
  
    private Canvas mCanvas;  
  
    private Thread thread;  
  
    // 背景移動狀態  
    private enum State {  
        LEFT, RINGHT  
    }  
  
    // 默認為向左  
    private State state = State.LEFT;  
  
    private final int BITMAP_STEP = 1;// 背景畫布移動步伐.  
  
    public MySurfaceView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        flag = true;  
        this.mContext = context;  
        setFocusable(true);  
        setFocusableInTouchMode(true);  
        surfaceHolder = getHolder();  
        surfaceHolder.addCallback(this);  
    }  
  
    /*** 
     * 進行繪制. 
     */  
    protected void onDraw() {  
        drawBG();  
        updateBG();  
    }  
  
    /*** 
     * 更新背景. 
     */  
    public void updateBG() {  
        /** 圖片滾動效果 **/  
        switch (state) {  
        case LEFT:  
            mBitposX -= BITMAP_STEP;// 畫布左移  
            break;  
        case RINGHT:  
            mBitposX += BITMAP_STEP;// 畫布右移  
            break;  
  
        default:  
            break;  
        }  
        if (mBitposX <= -mSurfaceWindth / 2) {  
            state = State.RINGHT;  
        }  
        if (mBitposX >= 0) {  
            state = State.LEFT;  
        }  
    }  
  
    /*** 
     * 繪制背景 
     */  
    public void drawBG() {  
        mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);// 清屏幕.  
        mCanvas.drawBitmap(bitmap_bg, mBitposX, 0, null);// 繪制當前屏幕背景  
    }  
  
    @Override  
    public void run() {  
        while (flag) {  
            synchronized (surfaceHolder) {  
                mCanvas = surfaceHolder.lockCanvas();  
                onDraw();  
                surfaceHolder.unlockCanvasAndPost(mCanvas);  
                try {  
                    Thread.sleep(100);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
  
    }  
  
    @Override  
    public void surfaceCreated(SurfaceHolder holder) {  
  
        mSurfaceWindth = getWidth();  
        mSurfaceHeight = getHeight();  
        int mWindth = (int) (mSurfaceWindth * 3 / 2);  
        /*** 
         * 將圖片縮放到屏幕的3/2倍. 
         */  
        bitmap_bg = BitmapUtil.ReadBitmapById(mContext, R.drawable.hypers_bg,  
                (int) mWindth, (int) mSurfaceHeight);  
  
        thread = new Thread(this);  
        thread.start();  
  
    }  
  
    @Override  
    public void surfaceChanged(SurfaceHolder holder, int format, int width,  
            int height) {  
  
    }  
  
    @Override  
    public void surfaceDestroyed(SurfaceHolder holder) {  
        flag = false;  
    }  
  
}  
上訴代碼相當簡單,我也不過多介紹.相信大家都看得懂.
下面是我們只需要在Main.xml中引用即可.
<?xml version="1.0" encoding="utf-8"?>  
<com.jj.dynamic.MySurfaceView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" >  
  
</com.jj.dynamic.MySurfaceView>  

這個的效果圖我就不展示了.就是一個時時變動的背景圖片,下面我展示下我最近在開發的一個內部小型項目,針對開年會娛樂場所用的.(里面東西都是會動的.)看是簡單我加了好多動畫特效,做這個頁面花了我一個星期呢.

\ \

怎么樣,看起來還不錯吧.其實我只是想說明一點.我們應用中完全可以把游戲融入進去,這樣我們可以得到另一番景象,不過話說回來,這樣也會帶來相應的負面影響,因為都是畫上去的,所以工作量也會翻倍.總之根據自己需要來開發就好了.
下面我上傳下APK,大家可以下載安裝下看看,說不定你可以從中找到靈感.
HypersParty.apk
下面我們再看一個頁面:
我想說明的是這個密碼后面的EditText的問題,要加上去很簡單,我們直接可以通過布局搞定,下面我們看布局文件
這里我沒有上布局文件代碼,是因為我覺得看這個視圖更好理解一點,不是么,有很多一上來就把布局文件啪啦啪啦貼出來,還得讀取半天.
我說下詭異問題.看下面張圖片:
這張圖片是我點擊鍵盤后讓鍵盤小時候的結果(注:此時軟鍵盤可以遮擋輸入框).其實如果你再次點擊edittext,其實它還在原位,只是 surfaceView在繪制的時候影響到了,原因不明.(下面我說個更詭異的問題,真是一個接一個,弄的我有想摔手機的心都有了.我的測試機是華為 S8600,android2.3的,然后我用oppo手機android4.0測試的時候用截圖工具竟然截不出來上面這張bug圖片,手機助手顯示是 OK,但是手機上顯示是BUG,NND,當時郁悶的要死,不管了這也不是重點.)
解決方法很簡單:我們只需要在我們的activity中執行這段話就ok了.(同樣適用於自定義的dialog.)
getWindow().setSoftInputMode(  
        WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE  
                | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);  
網上有的說可以在配置文件中配置,可是我配置了竟然無動於衷.大家可以去研究研究,總之代碼這種方案可行.
效果圖:
問題又出來了,看着怎么這么別扭呢,為什么密碼跑了那么高呢?
這個問題沒有解決,希望同學們有解決方案的朋友們麻煩告知下,(嘗試多次不行,個人感覺系統是以edittext為對象,將之彈起,中間的距離和edittext本身在布局中的位置有關,如果在底部的話,那么正好在鍵盤的上面)。
有文章說   getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); 這句話可以解決,可惜試了試不盡人意.
 總之看着還說的過去,臨時就這樣了,昨天在群里問了問,有朋友們提出,弄一個透明的dialog,activity,想想雖然沒有這么搞的,但是確實可行,只要你處理得好,根本看不出來他們不是一個布局.
 最后簡單說明一點:其實在surfaceView中一般不需要加edittext 控件的,比如說游戲,即使要的話,也會彈出一個性感的dialog.在其中加載控件(尤其是edittext)幾乎就不會有這樣的需求,即使有了,我們換個思維實現就OK了.
   
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM