在SurfaceView中添加系統控件,並且相互交互數據!

轉載自【黑米GameDev街區】 原文鏈接: http://www.himigame.com/android-game/306.html

          ☞ 點擊訂閱 ☜
 本博客最新動態!及時將最新博文通知您!

———————————————————————

多童鞋說我的代碼運行後,點擊home或者back後會程序異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完Himi的博文,第十九篇Himi專門寫了關於這些錯誤的原因和解決方法,這裏我在博客都補充說明下,省的童鞋們總疑惑這一塊;請點擊下面聯繫進入閱讀:

【Android遊戲開發十九】(必看篇)SurfaceView運行機制詳解—剖析Back與Home按鍵及切入後臺等異常處理! 

——————————————————————-

昨天聖誕節,沒有出去,而是一天時間全部糾結在如何在SurfaceView中添加組件,例如添加常用的Button,TextView等等、一開始也想着從網上找些資料看看有沒有可參考的,但是發現搜到的結果仍是些童鞋對此很疑惑並且也在找尋答案,那麼,這裏就把聖誕節一天的成果來和各位童鞋分享;

1.因爲我們的SurfaceView是個View對於添加的組件其實也是View,如果我們只是一味的想在SurfaceView中添加View組件其實是錯誤的思想,當然我一開始也是想着直接在SurfaceView中定義或者去使用組件,但是結果肯定是不成功的,因爲View不能添加View!

2.既然第一條肯定是錯誤的,那麼我們就應該想到把我們的SurfaceView和組件都放在一個Layout裏面,畢竟我們的的SurfaceView也是一個view和其他組件一同放在我們的layout裏,那麼這樣一來肯定就能完成在SurfaceView中添加組件的目的啦。下面先上截圖、

 

大家看到中間白色區域就是我們的SurfaceView啦,最上方是組件TextView ,最下方是Button 、對的,要的就是這個效果!而不是像前面文章中多個Activity切換,這樣都在一個界面中啦。哇哈哈啊。好、下面來看代碼吧:

先放上Xml 代碼:

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
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
   <LinearLayout
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
 
    <TextView
            android:id="@+id/textview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="This is Himi"
            android:textSize="32sp"
            android:textColor="#00FF00"
            android:gravity="center_horizontal"/>  
 
    </LinearLayout
 
    <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1">
    <com.himi.MySurfaceViewandroid:id="@+id/view3d"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>
    </FrameLayout>    
 
    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center">
        <Button 
 
         android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Himi Button_1"
                 android:id="@+id/button1"/> 
 
        <Buttonandroid:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Himi Button_2"
                  android:id="@+id/button2"/>
     </LinearLayout>
</LinearLayout>

以上代碼很簡單,都是一些佈局方式和各個組件一些屬性及顯示方式的設定,當然主要看如何對我們的SurfaceView如何註冊在xml中的,那麼每個組件都有id這樣爲了對後面其交互數據用到,因爲我們要對每個組件操作,所以這裏都索引了id方面從R文件中取出其對象。

那麼,xml我們定義好了,看看代碼中如何實現的,這裏先說下Activity類中代碼:

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
packagecom.himi;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.Window;
importandroid.view.WindowManager;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.TextView;
publicclass MainActivity extendsActivity implementsOnClickListener {
    /** Called when the activity is first created. */
    privateButton button1, button2;
    privateTextView tv ;
    @Override
    publicvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);//隱去標題(應用的名字)
        //此設定必須要寫在setContentView之前,否則會有異常)
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.main);//要先顯示,然後再對其組件取出、處理操作
        tv=(TextView)findViewById(R.id.textview);
        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(this);//這裏是監聽按鍵,因爲本類使用了OnClickListener接口
        button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(this);
        /* 其實大家也可以不用本類使用接口,可以內部類來完成。
         * 以下是不使用OnClickListener接口的綁定監聽方式;
        button2.setOnClickListener(new OnClickListener() {
 
            @Override
            public void onClick(View v) {
                //這裏處理按鍵操作
 
            }
        });
        */
    }
    @Override
    publicvoid onClick(View v) {
        if(v == button1) {
            MySurfaceView.button_str = "button 1被觸發";
            tv.setText("button 1被觸發");
        }elseif (v == button2) {
            MySurfaceView.button_str = "button 2被觸發";
            tv.setText("button 2被觸發");
        }
    }
}

該有的備註在代碼後面都備註了,MySurfaceView.button_str,這個是自己的SurfaceView中定義的一個static 的變量用來交互數據用到;在那麼下面就要看我們的SurfaceView,當在Xml註冊需要注意什麼了,我半天的時候都花在了這裏!!!一定要引起注意,這也是在SurfaceView中並顯示組件完成最重要的一步。

先分析:

1.SurfaceView類的創建和實現等等和之前都是一樣的,該怎麼去寫還怎麼去寫,但是!構造函數一定要注意!

1
2
3
4
/*
     * public MySurfaceView(Context context) { super(context); }//備註1(這裏一定要引起注意,仔細看下文對備註1的解釋 )
     */
publicMySurfaceView(Context context, AttributeSet attrs) {//備註1}

這裏解釋下備註1:  這裏有兩個構造函數,當然我們用哪個都是可以的,但是在此時我們需要明確我們到底要使用哪個。

一個參數的構造函數:如果是new出來的此類實例肯定是沒有問題,但是我們爲了能在顯示SurfaceView同時顯示別的組件,所以把自定義的SurfaceView也當作組件註冊在了main——xml中,所以這裏需要注意,當在xml中註冊的就必須在SurfaceView中使用這種含有兩個參數的構造函數的方法, xml初始化的時候會調用兩個參數的這個構造方法, (當時這個問題困擾了半天的研究時間,最後在一個羣友的幫助下才發現是這裏出了問題) 那麼含有兩個構造參數的方法裏第二個參數指的自定義的組件的一些屬性,就像長寬一樣,你可以給組件屬性,就是通過這個來傳遞的!

那麼在SurfaceView 中並一同顯示組件也就到底完結了,回顧下,一共分爲3步,1.將我們的SurfaceView 作爲一個組件view 和其他組件一同放置到佈局中,當然佈局的方式和顯示的方式大家自己隨自己喜歡定義! 2.在我們的SurfaceView中一定要使用兩個構造函數的構造函數,一定!一定! 就這裏有區別,別的還是該怎麼處理就怎麼處理,就是構造函數換了 3.交互數據,對其按鍵的綁定在 activity中完成,別把view綁定在咱們的SurfaceView中啊,否則報錯- -、

這裏說下爲什麼要在activity中去綁定按鍵處理 而不是在我們的surfaceview中去綁定:

 其實根據xml中定義button時的id 我們可以通過R.id 索引取到button,不管在activity中還是我們的surfaceview中都可以取到,但是!綁定button這一步如果在 surfaceview中去寫就一定報錯,原因我解釋下;

我們在xml中定義我們的surfaceview 和 組件button、textview等等的時候 他們是同一級別的!!而不是把button包含在 surfaceview

裏,所以雖然在surfaceview中可以根據id索引到button但綁定的時候是無法找到button的,只有我們的activitysetContentView(R.layout.main); 顯示的button,所以只能在顯示它的activity中去綁定,這裏需要注意下;

本章源碼下載: ”SurfaceView添加組件且交互數據.rar”        下載地址:  http://vdisk.weibo.com/s/hq3c0

 

我們已經可以在同一界面中既顯示我們的surfaceview和button、textview等組件,那麼基本算是成功了,但是身爲遊戲開發人員,如果不是想故意要這種類似電影形式的展現方式(我們的surfaceview在中間 – -.很想播放電影似的。。),是絕對不允許遊戲的分量只是佔了中間那麼一部分,肯定需要全屏顯示,別的組件只是一個配角的角色。那麼下面先上一張截圖看下爲什麼修改與調整。

(圖1):

 

看到我們畫出來的字體了吧,很悲劇被覆蓋了!只要有button就會有一塊長條,即使我們修改button中佈局的顏色也只是把長條的顏色變成白色,當然好看是好看了,但是仍舊遮擋我們的字體!這可不是我們想要的結果。我們想要的效果應該是下圖這樣的:

(圖2):

娃哈哈,這效果就對啦,我們的view佔滿全屏,而組件本身才會對我們的view中的內容有遮擋,不會多出一些無用的長條遮擋….

當時雖然想的方法就是佈局xml的問題,我一開始想在我們xml中定義的surfaceview中直接添加按鈕,但是view不能添加view!所以沒辦法,就想到是否是佈局的問題。經過多次嘗試才終於成功做到。

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" >
    <com.himi.MySurfaceView android:id="@+id/view3d"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>
        <Button
         android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:text="Himi Button_1"
                 android:id="@+id/button1"/> 
 
        <Button android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_toRightOf="@id/button1"
                android:text="Himi Button_2"
                  android:id="@+id/button2"/>
                     <TextView
            android:id="@+id/textview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="This is Himi"
            android:textSize="32sp"
            android:textColor="#00FF00"
            android:gravity="center_horizontal"/>
    </RelativeLayout>
</LinearLayout>

xml 修改的不大,主要將之前的線性佈局改成了相對佈局。雖然改動不大,但是也真的費了不少時間去調整、這樣一來大家就可以在自己的遊戲Surfaceview中隨意添加組件啦,娃哈哈~~~

源碼在上一篇已經給出下載地址,這裏也只是對xml的修改大家需要可以去下載上一篇的源碼,將xml調整即可、

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章