1. 程式人生 > >Android使用SurfaceView製作卷軸開啟效果

Android使用SurfaceView製作卷軸開啟效果

SurfaceView是檢視(View)的繼承類,這個視圖裡內嵌了一個專門用於繪製的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪製位置。

surface是縱深排序(Z-ordered)的,這表明它總在自己所在視窗的後面。surfaceview提供了一個可見區域,只有在這個可見區域內 的surface部分內容才可見,可見區域外的部分不可見。surface的排版顯示受到檢視層級關係的影響,它的兄弟檢視結點會在頂端顯示。這意味者 surface的內容會被它的兄弟檢視遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文字和按鈕等控制元件)。注意,如果surface上面 有透明控制元件,那麼它的每次變化都會引起框架重新計算它和頂層控制元件的透明效果,這會影響效能。

surfaceview變得可見時,surface被建立;surfaceview隱藏前,surface被銷燬。這樣能節省資源。如果你要檢視 surface被建立和銷燬的時機,可以過載surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。

1> 所有SurfaceView和SurfaceHolder.Callback的方法都應該在UI執行緒裡呼叫,一般來說就是應用程式主執行緒。渲染執行緒所要訪問的各種變數應該作同步處理。

2> 由於surface可能被銷燬,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之間有效,所以要確保渲染執行緒訪問的是合法有效的surface。
接下來呢,說說自己對它的理解

1、定義

可以直接從記憶體或者DMA等硬體介面取得影象資料,是個非常重要的繪圖容器。

它的特性是:可以在主執行緒之外的執行緒中向螢幕繪圖上。這樣可以避免畫圖任務繁重的時候造成主執行緒阻塞,從而提高了程式的反應速度。在遊戲開發中多用到SurfaceView,遊戲中的背景、人物、動畫等等儘量在畫布canvas中畫出。

2、實現

首先繼承SurfaceView並實現SurfaceHolder.Callback介面
使用介面的原因:因為使用SurfaceView 有一個原則,所有的繪圖工作必須得在Surface 被建立之後才能開始(Surface—表面,這個概念在 圖形程式設計中常常被提到。基本上我們可以把它當作視訊記憶體的一個對映,寫入到Surface 的內容
可以被直接複製到視訊記憶體從而顯示出來,這使得顯示速度會非常快),而在Surface 被銷燬之前必須結束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了繪圖處理程式碼的邊界。

需要重寫的方法

 (1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}

  //在surface的大小發生改變時激發

 (2)public void surfaceCreated(SurfaceHolder holder){}

  //在建立時激發,一般在這裡呼叫畫圖的執行緒。

 (3)public void surfaceDestroyed(SurfaceHolder holder) {}

  //銷燬時激發,一般在這裡將畫圖的執行緒停止、釋放。

整個過程:繼承SurfaceView並實現SurfaceHolder.Callback介面 —-> SurfaceView.getHolder()獲得SurfaceHolder物件 —->SurfaceHolder.addCallback(callback)添加回調函式—->SurfaceHolder.lockCanvas()獲得Canvas物件並鎖定畫布—-> Canvas繪畫 —->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)結束鎖定畫圖,並提交改變,將圖形顯示。

3、SurfaceHolder

這裡用到了一個類SurfaceHolder,可以把它當成surface的控制器,用來操縱surface。處理它的Canvas上畫的效果和動畫,控制表面,大小,畫素等。
幾個需要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
// 給SurfaceView當前的持有者一個回撥物件。
(2)、abstract Canvas lockCanvas();
// 鎖定畫布,一般在鎖定後就可以通過其返回的畫布物件Canvas,在其上面畫圖等操作了。
(3)、abstract Canvas lockCanvas(Rect dirty);
// 鎖定畫布的某個區域進行畫圖等..因為畫完圖後,會呼叫下面的unlockCanvasAndPost來改變顯示內容。
// 相對部分記憶體要求比較高的遊戲來說,可以不用重畫dirty外的其它區域的畫素,可以提高速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
// 結束鎖定畫圖,並提交改變。

4、例項,畫軸的實現

下面也就是我利用他做的一個卷軸效果了,技術含量比較低。。。。

public class MSurfaceView extends SurfaceView implements Callback {

    SurfaceHolder surfaceHolder;
    ViewThread    viewThread;
    int ani_process = 0;
    public boolean direction = true;
    int width, height;
    private Bitmap bmp_right;
    private Bitmap bmp_middle;

    private int imgHeight;//
    private int scrollBarWidth;
    int    scrollWidth = 900;//卷軸要繪製的寬度
    Canvas canvas      = null;

    public MSurfaceView(Context context) {
        super(context);
        init();
    }

    public MSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MSurfaceView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {

    }

    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        width = this.getWidth();
        height = this.getHeight();
        viewThread = new ViewThread();
        viewThread.flag = true;
        viewThread.start();
    }

    private void init() {
        surfaceHolder = this.getHolder();
        surfaceHolder.addCallback(this);
        /**
         * 將150dp轉化為px
         *
         */
        imgHeight = ScreenUtil.dp2px(150, getContext());
        scrollWidth = ScreenUtil.getScreenWidth(getContext());
        scrollBarWidth = (int) (scrollWidth * 0.089);
        loadRes();
    }

    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        viewThread.flag = false;
    }

    public void loadRes() {
        Bitmap localBitmap;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.scroll);
        localBitmap = Bitmap.createScaledBitmap(bitmap, scrollWidth, imgHeight, true);
        bmp_middle = Bitmap.createBitmap(localBitmap, 0, 0, scrollWidth, imgHeight);
        bmp_right = Bitmap.createBitmap(localBitmap, (scrollWidth - scrollBarWidth), 0,
                scrollBarWidth, imgHeight);
    }

    class ViewThread extends Thread {
        public boolean flag;

        public void run() {
            while (flag) {
                try {
                    if (direction) {
                        if (ani_process > scrollWidth - scrollBarWidth) {
                            direction = false;
                        }
                        ani_process += 3;
                    } else {
                        viewThread.flag = false; // 銷燬執行緒
                    }
                    canvas = surfaceHolder.lockCanvas(null); // 鎖定畫布 並獲取canvas
                    myDraw();
                    surfaceHolder.unlockCanvasAndPost(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void myDraw() {
        canvas.drawBitmap(bmp_right, ani_process - 6, 0, null);
        if (canvas.clipRect(0, 0, ani_process, scrollWidth))
            canvas.drawBitmap(bmp_middle, 0, 0, null);
    }
}

這裡寫圖片描述

相關推薦

Android使用SurfaceView製作卷軸開啟效果

SurfaceView是檢視(View)的繼承類,這個視圖裡內嵌了一個專門用於繪製的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪製位置。 surface是縱深排序(Z-ordered)的,這表明它總

6.如何使用CardView製作卡片佈局效果

/** * 作者:Pich * 原文連結:http://me.woblog.cn/ * QQ群:129961195 * 微信公眾號:woblog * Github:https://github.com/lifengsofts */ 詳解RecyclerView系列文章目錄

HTML5 - 用CSS3動畫製作場景切換效果(移動,旋轉,淡入淡出等)

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>HTML5-頁面切換動畫</title> 6 <l

ionic3 製作九宮格效果

我們在app中常會看到一排類似九宮格形式的圖示,它們可以引導我們執行自己需要使用的功能,那麼這個清新亮麗的九宮格效果是怎樣製作出來的呢?接著往下看吧。 程式碼部分如下: (1)html部分:         採用的方式結合了ionic與html兩種

ppt怎麼製作快閃效果的倒計時動畫?

ppt怎麼製作快閃效果的倒計時動畫? 1、首先,我們新建一個ppt,如下圖:   2、然後我們在ppt中插入一個文字,文字內容為3,如下圖: 3、然後我們將我們的文字設定為“Arial Black”,如下圖: 4、然後將我們的文字放大,這裡我們測試文字可以放到的最大為“4000

PopupWindow 使用詳解(二) Popwindow 製作常見花哨效果

帝都幾日降溫,終於被撂倒了。but 只要一息尚存就得不斷進步!於是,寫出 《PopupWindow 使用詳解》的第二篇 筆記,先奉上 第一篇連結: 《PopupWindow 使用詳解(一) 中文API 文件 贈送 ListPopupWindow 中文 API》

用CSS製作凸出按鈕效果

本文包含HTML效果,閱讀原文以體驗最佳效果:原文 按鈕在各種軟體的開發中幾乎都是少不了的部分,好看的按鈕有很多。今天我們來試著使用CSS製作簡單的凸出按鈕。 凸出按鈕,顧名思義就是讓使用者覺得它是凸出於網頁這個平面的,點選的時候會把它戳進去。 很多按鈕都會有這樣的效果,因為這的確是不錯的使用者體驗。我們

SVG初步瞭解,製作圓圈進度效果

SVG實現圓圈進度效果 1、viewBox 2、 基於stroke-dasharray和stroke-dashoffset圓形進度條 stroke-dasharray:定義描邊的虛線長度,如果提供奇數個,則會自動複製該值成偶數 stroke-dashoffset:定義虛線描邊

利用Clip製作打洞效果

原文: 利用Clip製作打洞效果 起因 如上篇博文所說,連線原型需要在中間文字上下各留15畫素的空白。設計師完成原型之後,問我有沒有辦法實現,我說,我能想到兩種實現方式。其中一種就是上篇博文所說的OpacityMask。第二種就是使用Clip了。下面是效果圖: 程式碼實現 Clip Clip定義

利用OpacityMask製作打洞效果

原文: 利用OpacityMask製作打洞效果 起因 專案上存在一個連線功能,在設計的原型中,在連線中間文字上下各有15畫素的空白。接手的同事覺得沒思路,問我能不能在不影響連線後面的背景情況下解決該問題。我就抽了點時間給他寫了個Demo。回家後趁熱打鐵,重新寫了個Demo,新增和完善了些功能。下面是效果圖

通過CAGradientLayer製作漸變色效果【原創】

看了極客學院的視訊之後寫的一篇部落格,覺得不錯,還是作為筆記使用。 簡單介紹一下CAGradientLayer吧。 Gradient:本身就是梯度的意思,所以在這裡就是作為漸變色來理解 1,CAGradientLayer用於處理漸變色的層結構 2,CAGradie

ps例項二:使用高斯濾鏡製作圖片陰影效果

例項二:使用高斯濾鏡製作圖片陰影效果 1、ctrl+單擊圖層,選中圖片選區; 2、在該圖層下面,新建一圖層; 3、填充灰色:alt+delete(如果快捷鍵不行,就用油漆桶填充也行) 4、ctrl+Del:取消選區; 5、選中灰色圖層,濾鏡-》高斯濾鏡; 6、移動圖層到合適

HTML5 Canvas 製作水波紋效果

今天,我們繼續分享 JavaScript 實現的效果例子,這篇文章會介紹使用 JavaScript 實現水波紋效果。水波效果以圖片為背景,點選圖片任意位置都會觸發。有時候,我們可以建立一個很有趣的解決功能。 線上演示      原始碼下載 Step 1. HTML

css製作抽獎輪盤效果/扇形選單

先上效果圖 附上程式碼: <!DOCTYPE html> <html><head><meta charset="utf-8" /><title>輪盤</

如何用Unity開發出大製作的遊戲效果(外掛推薦)

我們來為美術設計師謀個福利,那些大片即視感是如何打造的?有沒有一些外掛能快速實現高逼格的效果呢?所以,巨人的肩膀來了,您可得踩穩了哦! The Amazing Wireframe Shader 在開發中我們常常希望通過非真實感渲染達到一些有趣的效果。在此,我們為大家介紹這款效果不錯的外掛:T

虛幻4RenderTarget製作多pass效果

這是一個實時繪製汙漬的多pass效果。虛幻裡實現多pass的方式目前用得比較多的就rendertarget還有一個是多重疊模型。也許後期虛幻4會暴露出更多介面和特性。 首先我們要準備一下幾個資源 第一個BP-DamageCHaracter,繼承於ACharacter類,

每天一點點 PS製作照片撕裂效果

程式碼敲累了,來點PS調劑調劑,動手製作照片像紙一樣的撕裂效果,應該算有特色的吧!製作過程中的引數可以根據具體情況調整。方法/步驟1、首先開啟一張圖片,雙擊右下角的圖層面板上的圖層讓背景圖層變為普通圖層,也就是圖層0,然後新建一個圖層1,將圖層1和圖層0的上下位置調換(如圖所

製作banner切換效果

  這邊首先上圖:   、   要製作上面的切換banner效果,可以使用background-position加padding來實現,挺有意思的css2的功能,這階段在製作手機版的幫助系統以及專題大量用到,當然是參考了很多其他的外掛來完成,先上css樣式: /* Used

box-shadow 製作單邊陰影效果,不影響其它邊的效果

以前在使用box-shadow製作單邊陰影效果的時候發現或多或少會影響其它邊的展示效果. 今天在閱讀文章的時候,終於發現了一個解決的方法. 就是利用box-shadow中的一個引數.spread來解決這個問題. 首先我們先要區分 box-shadow:0 10px 10p

android 製作ios毛玻璃效果(圖片模糊處理)

先不說廢話直接上效果圖 毛玻璃效果在ios裡是非常常見的,但是在android上卻很少見,這是為什麼呢? ios系統本身就應用了非常多的毛玻璃效果,系統對這種效果有相對比較好的處理,但是android系統並沒有類似的api,直到現在的SDK22也沒有