AndroidStudyDemo之Android4.x介紹

Android4.x 思維導圖

作者:李旺成###

時間:2016年4月7日###


AndroidStudyDemo 系列篇章開始了!!!

AndroidStudyDemo 你值得擁有
AndroidStudyDemo之Android4.x介紹
AndroidStudyDemo之Android5.x新API介紹(一)
AndroidStudyDemo之Android5.x新API介紹(二)

今天給大家介紹一下我的 AndroidStudyDemo 下的 Android4Study 中的相關內容,先看下面的動態圖,演示了該 Demo 中所包含的內容。

提示:該 Demo 會以單獨項目的的形式提供,并且會集成到 AndroidStudyDemo 項目當中(周末),你可以根據自己的需要選取。

Android4新控件

下面我將闡述一下該 Demo 中所涉及的知識點。

目錄

一、 Switch
二、 Space
三、 PopupMenu
四、 GlidLayout
五、 TextureView

一、Switch

Switch 是一個可以在兩種狀態切換的開關控件,它只有兩個狀態:開和關;和 CheckBox 挺像。

Google 的 Nexus 系列的升級到 4.x(汗,就是原生系統),在系統設置頁面可以看到很多打開設備都使用了該控件。以前羨慕 iOS 上提供了漂亮的 UISwitch控件,OK,Google 也為廣大 Android 程序員提供了類似的開關(別高興的太早,設計師們會告訴你,我要的不是這個效果~~哈哈,我們早已習慣了不是,但是不妨礙我們自己用...)。

來看看效果圖:


Switch 控件

Switch 類關系圖

學習一個新控件的時候,我的習慣是先看看該控件的繼承結構(在 AndroidStudio 光標置類名上,點擊 F4 按鈕即可查看該類的繼承結構)。為什么?如果該控件是繼承自你熟悉的控件,那簡單了,看看是不是多加了幾個屬性就好了;如果不是,那可能就需要花點時間來熟悉下了。好了,不多說這些,上圖:

Switch 繼承結構

Button,熟悉吧!CompoundButton,這個不是很眼熟,那好來看看下面這個段代碼:

mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // TODO
    }
});

沒錯 CheckBox 的 setOnCheckedChangeListener 用的就是 CompoundButton 中的 OnCheckedChangeListener 接口,CompoundButton 出現了,還和 CheckBox 扯上了關系。好吧,這個時候要么去看看 CompoundButton,要么去看看 CheckBox,看你喜好。我選熟悉的 —— CheckBox,如下圖:

CheckBox 繼承結構

Switch 的簡單使用

這下清晰了吧!CheckBox 和 Switch 是兄弟。好了繞了這么一大圈,其實只是想分享下我一般怎么去學習一個新控件。
既然是兄弟,那應該很像,那直接當成 CheckBox 試一下啊!好,試一下設置 textXXX 相關的屬性,直接看提示有哪些 textXXX 屬性:

Switch 的 TextXXX 屬性

上圖用紅色框圈出來的有點面生,看下 CheckBox 的,類比學習嘛,上圖:

CheckBox 的 TextXXX 屬性

上面那幾個在 CheckBox 中沒有,嗯,看著字面上就是“關的文本”和“開的文本”的意思(方法二:),實踐出真知,多簡單的事。上代碼:

<Switch
    android:id="@+id/switch_test1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textOn="開"
    android:textOff="關"/>

好了,布局文件搞定了,來監聽下事件:

this.mTest1Switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // TODO
    }
});

毫無違和感,和 CheckBox 一樣。看到這里應該清楚了,這就是 CheckBox 的另一個版本,做成了開關的樣式而已,多加了幾個屬性,用法和 CheckBox 基本類似。

Switch 自定義樣式

android:thumb : 設置滑塊圖片
android:thumbTextPadding : 設置背景圖片和文字之間的間距,可用來控制 Switch 整體寬度
android:track : 設置背景圖

提示:等你高高興興的把自己的 .9 圖都設置上去后來看效果,怎么看都感覺不對勁。為什么?高度好像有點不聽使喚,layout_height 和 minHeight 齊上,還是不管用。好吧!這不是本文重點(咱就用原生的,要不就自己去實現一個,網上多的是仿 iOS 開關的自定義控件)

好了,Switch 的介紹到這里了。

二、Space

Space 是一個空白控件,那有什么用 —— 占位。要效果圖,好吧,上圖:

Space效果圖.png

Space 類關系圖

繼承結構很簡單,看圖:

Space 繼承結構

對,就是繼承自 View,熟悉吧!但是,這回沒轍了,View 基本上算是所有控件的基類了,這回看你怎么類比學習。確實,龍生九子各有不同,甚至很多都不像龍了。那就不類比了,直接點擊進去看看,看什么是個問題 —— 這還用說,當然是看 draw() 方法,上圖:

Space 的 draw()方法

坑!空方法,什么都沒有。對了,就是什么都沒有,所以才高效(沒什么要 draw 的當然高效了)。因為 Space 的定位就是空白控件,哥們就是用來占位的,不要想多了。

Space 的簡單使用

侮辱我的智商嗎?好吧,為了隊形整齊,看代碼吧:

<Space
    android:id="@+id/space_test1"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="#ff00ff"/>

background,這是幾個意思,別介,只是驗證一下,哥們就是個空白控件...

好了,Space 結束。

三、PopupMenu

PopupMenu 是彈出式菜單,它會在指定組件上方或下方彈出菜單。

PopupMenu 有沒有感覺和 PopupWindow 名字上很像,先看看效果圖:

PopupMenu 效果圖

PopupMenu 類關系圖

PopupMenu 繼承結構

繼承自 Object,這個更熟悉了,但是沒用...
那在看看它的基友 PopupWindow,上圖:

PopupWindow 繼承結構

沒轍了,只能看文檔了,看下 PopupMenu 的官方文檔:

PopupMenu 文檔

沒什么可說的,先看看怎么讓它顯示出來。

PopupMenu 的簡單使用

使用 PopupMenu 創建菜單的步驟:

  1. 調用new PopupMenu(Context context,View anchor)創建下拉菜單,anchor代表要激發該彈出菜單的組件。
  2. 調用MenuInflater的inflate()方法將菜單資源填充到PopupMenu中。
  3. 調用PopupMenu的show()方法顯示彈出式菜單。

看代碼,源碼之下,一切都無所遁形:

// 創建 PopupMenu
private void createPopupMenuByCode() {
    mPopupMenu1 = new PopupMenu(this, findViewById(R.id.btn_popupmenu1));
    Menu menu = mPopupMenu1.getMenu();

    // 通過代碼添加菜單項
    menu.add(Menu.NONE, MENU_ITEM_COPY_ID, 0, "唐僧");
    menu.add(Menu.NONE, MENU_ITEM_PASTE_ID, 1, "孫悟空");
}

private void createPopupMenuFromXML() {
    mPopupMenu2 = new PopupMenu(this, findViewById(R.id.btn_popupmenu2));
    Menu menu = mPopupMenu2.getMenu();

    // 通過XML文件添加菜單項
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.popupmenu, menu);
}

private void createPopupMenuFromMixture() {
    mPopupMenu3 = new PopupMenu(this, findViewById(R.id.btn_popupmenu3));
    Menu menu = mPopupMenu3.getMenu();
    // 通過代碼添加菜單項
    menu.add(Menu.NONE, MENU_ITEM_COPY_ID, 0, "唐僧");
    menu.add(Menu.NONE, MENU_ITEM_PASTE_ID, 1, "孫悟空");
    // 通過XML文件添加菜單項
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.popupmenu, menu);
}

// 顯示 PopupMenu
private void showPopupMenu1() {
    mPopupMenu1.show();
}

private void showPopupMenu2() {
    mPopupMenu2.show();
}

private void showPopupMenu3() {
    mPopupMenu3.show();
}

很簡單吧,這里就不和 PopupWindow 對比了,沒什么意思,也不是本文重點,PopupMenu 介紹到這里了。項目源碼在文末會給出 GitHub 地址。

四、GlidLayout

GridLayout 是網格布局,為解決嵌套而生,將布局以行和列進行分割。同樣的先看效果圖:

GlidLayout 效果圖

上圖將網格的行列顯示的很清晰,對人如其名(錯了,控件如其名),這貨就是個網格布局,使用虛細線將布局劃分為行,列和單元格——支持一個控件在行,列上都有交錯排列。(參考自:廖煜嶸——“Android 4.0新增Space及GridLayout初談”

前面說了,GridLayout 是為了解決嵌套而生(嵌套,不用說了吧!不好,不僅影響性能,還增加了布局文件的復雜度),如果僅僅是這個可能還體現不了 GlidLayout 的強大。拿 LinearLayout 開刀(誰讓它最容易寫出嵌套,不找它找誰),在一些復雜的布局中,有時會遇到這樣一個問題 —— 在 LinearLayout 中不能同時在 X,Y 軸方向上進行控件的對齊。

如下圖描述了這個缺點(引自:廖煜嶸——“Android 4.0新增Space及GridLayout初談”):

LinearLayout 的缺點

這里,當 Email address 這個標簽的文本發生變化時,既要保持跟其右邊控件的下部的基線對齊,又要保持跟下面的控件的右邊緣對齊,而用嵌套布局的方式是不能實現的,因為不能夠同時在 X,Y 軸上進行控件的對齊。于是我們便需要引入新的布局方式 GridLayout。(引自:廖煜嶸——“Android 4.0新增Space及GridLayout初談”

GlidLayout 類關系圖

GlidLayout 繼承結構

不出意料,沒有繼承自常見的那五大布局,那只能是 ViewGroup 了。來看看官方文檔:

GildLayout 文檔

一眼掃去,加了幾個行列相關的屬性,那就試試吧!

GlidLayout 簡單使用

簡易計算器布局

先看效果圖:

GlidLayout 實現計算器布局

布局代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"


    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:alignmentMode="alignBounds"
    android:columnCount="4"
    android:orientation="horizontal"
    android:rowCount="5">

    <!-- 第一行 -->
    <Button
        android:id="@+id/one"
        android:text="1"/>
    <Button
        android:id="@+id/two"
        android:text="2" />
    <Button
        android:id="@+id/three"
        android:text="3" />
    <Button
        android:id="@+id/devide"
        android:text="/" />

    <!-- 第二行 -->
    <Button
        android:id="@+id/four"
        android:text="4" />
    <Button
        android:id="@+id/five"
        android:text="5" />
    <Button
        android:id="@+id/six"
        android:text="6" />
    <Button
        android:id="@+id/multiply"
        android:text="×"
        android:layout_gravity="fill" />

    <!-- 第三行 -->
    <Button
        android:id="@+id/seven"
        android:text="7" />
    <Button
        android:id="@+id/eight"
        android:text="8" />
    <Button
        android:id="@+id/nine"
        android:text="9" />
    <Button
        android:id="@+id/minus"
        android:text="-"
        android:layout_gravity="fill"/>

    <!-- 第四行 -->
    <Button
        android:id="@+id/zero"
        android:layout_columnSpan="2"
        android:layout_gravity="fill"
        android:text="0" />
    <Button
        android:id="@+id/point"
        android:text="." />
    <Button
        android:id="@+id/plus"
        android:layout_gravity="fill"
        android:layout_rowSpan="2"
        android:text="+" />

    <!-- 第五行 -->
    <Button
        android:id="@+id/equal"
        android:layout_columnSpan="3"
        android:layout_gravity="fill"
        android:text="=" />

</GridLayout>

簡單解釋一下
GridLayout 提供了和 LinearLayout 類似的 API(降低使用門檻,它們也算兄弟不是),只是布局的思路不大一樣,GridLayout 有點像屏幕顯示的原理,占用不同的單元格來形成不同的圖案(當然只是簡單的類比一下,不要較真,為了便于理解而已)。

GridLayout的布局策略簡單分為以下三個部分:

首先,它與LinearLayout布局一樣,也分為水平和垂直兩種方式,默認是水平布局,一個控件挨著一個控件從左到右依次排列,但是通過指定android:columnCount 設置列數的屬性后,控件會自動換行進行排列。另一方面,對于 GridLayout 布局中的子控件,默認按照 wrap_content 的方式設置其顯示,這只需要在 GridLayout 布局中顯式聲明即可。

其次,若要指定某控件顯示在固定的行或列,只需設置該子控件的android:layout_row 和 android:layout_column 屬性即可,但是需要注意:android:layout_row=”0”表示從第一行開始,android:layout_column=”0”表示從第一列開始,這與編程語言中一維數組的賦值情況類似。

最后,如果需要設置某控件跨越多行或多列,只需將該子控件的android:layout_rowSpan 或者 layout_columnSpan 屬性設置為數值,再設置其 layout_gravity 屬性為 fill 即可,前一個設置表明該控件跨越的行數或列數,后一個設置表明該控件填滿所跨越的整行或整列。
(參考自:李響——"淺談android4.0開發之GridLayout布局"

LinearLayout 之殤

上面說了,LinearLayout 容易嵌套(那你不會用 RelativeLayout啊,“劇情”需要,不要較真),而且不能同時在X,Y軸方向上進行控件的對齊。好,GridLayout 閃亮登出的時刻到了,先看效果圖:

GridLayout 解決 LinearLayout 的問題

直接上代碼:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:alignmentMode="alignBounds"
    android:columnCount="4"
    android:columnOrderPreserved="false"
    android:useDefaultMargins="true">

    <!-- 第一行跨4列 -->
    <TextView
        android:layout_columnSpan="4"
        android:layout_gravity="center_horizontal"
        android:text="@string/text_emailsetup"
        android:textSize="22sp" />

    <!-- 第二行跨4列 -->
    <TextView
        android:layout_columnSpan="4"
        android:layout_gravity="left"
        android:text="@string/text_emailsetup_tip"
        android:textSize="14sp" />

    <!-- 第三行一列 -->
    <TextView
        android:layout_gravity="right"
        android:text="@string/text_emailaddress_tip" />
    <!-- 第三行二列 -->
    <EditText android:ems="8" />

    <!-- 第四行一列 -->
    <TextView
        android:layout_column="0"
        android:layout_gravity="right"
        android:text="@string/text_emailpassword_tip" />
    <!-- 第四行二列 -->
    <EditText android:ems="6" />

    <!-- 第五行跨三列 -->
    <Space
        android:layout_row="4"
        android:layout_column="0"
        android:layout_columnSpan="3"
        android:layout_gravity="fill" />

    <!-- 第六行四列 -->
    <Button
        android:layout_row="5"
        android:layout_column="3"
        android:text="@string/text_nextstep" />
</GridLayout>

看到 layout_row、layout_column 和 layout_columnSpan,有沒有覺得和 TabLayout 有點像,對,在這兩個布局中這些屬性的作用是相似的,看看注釋,自己再去試試,相信這沒什么難的。(Android 4.0新增Space及GridLayout初談 中有較詳細的說明,在這我就不贅述了)

GridLayout 的布局方向

在 GridLayout 中,默認的布局是水平方向的,即將控件從左到右,從上到下進行排列,比如下圖中的文本“1-1”即放置在第1行第1列中,以此類推。

要使用垂直的布局,很簡單,和 LinearLayout 一樣,它也有 orientation 屬性,設置為“vertical”即可,注意查看控件排列的變化。

直接看圖:

GridLayout 的默認布局為水平
GridLayout 使用垂直布局

GridLayout 中子控件 layout_gravity 和 gravity 使用

要實現控件間的對齊,可以通過設置android:layout_gravity="fill_horizontal",來,看看效果:

GridLayout 子控件的 layout_gravity 使用

使用android:layout_gravity="fill",可以使子控件伸展充滿被包含的父控件,看效果:

GridLayout 子控件的 layout_gravity / gravity 使用

GridLayout 中子控件的 xxxWeight 屬性

xxxWeight,與 LinearLayout 中子控件的 layout_weight 屬性功能類似,可以實現行或列平均分配,上圖:

GridLayout 中 xxxWeight 屬性.png

一切都在代碼里,你懂的:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gl_gridlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="4"
    android:rowCount="7">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#eee"
        android:text="0"
        android:textColor="#000"
        android:textSize="50sp"
        android:layout_columnSpan="4" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Clear"
        android:layout_columnSpan="4" />

    <Button
        android:id="@+id/one"
        android:text="1"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/two"
        android:text="2"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/three"
        android:text="3"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/devide"
        android:text="/"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />
      
    <Button
        android:id="@+id/four"
        android:text="4"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/five"
        android:text="5"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/six"
        android:text="6"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />
      
    <Button
        android:id="@+id/multiply"
        android:text="×"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/seven"
        android:text="7"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />
      
    <Button
        android:id="@+id/eight"
        android:text="8"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />
      
    <Button
        android:id="@+id/nine"
        android:text="9"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/minus"
        android:text="-"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/zero"
        android:text="0"
        android:layout_columnSpan="2"
        android:layout_columnWeight="1"
        android:layout_gravity="fill"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/point"
        android:text="."
        android:layout_columnWeight="1"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/plus"
        android:text="+"
        android:layout_columnWeight="1"
        android:layout_rowSpan="2"
        android:layout_rowWeight="1" />

    <Button
        android:id="@+id/equal"
        android:text="="
        android:layout_width="match_parent"
        android:layout_columnSpan="4"
        android:layout_rowWeight="1" />
</GridLayout>

好了,GridLayout 的介紹就到這里了。

五、TextureView

TextureView 作為 SurfaceView 的兄弟,可彌補其不足。老規矩了,先上圖:

TextureView 效果圖

如果你想顯示一段在線視頻或者任意的數據流比如視頻或者 OpenGL 場景,你可以用 android 中的 TextureView 做到。

TextureView 的兄弟 SurfaceView
應用程序的視頻或者opengl內容往往是顯示在一個特別的UI控件中:SurfaceView。SurfaceView 的工作方式是創建一個置于應用窗口之后的新窗口。這種方式的效率非常高,因為 SurfaceView 窗口刷新的時候不需要重繪應用程序的窗口(Android 普通窗口的視圖繪制機制是一層一層的,任何一個子元素或者是局部的刷新都會導致整個視圖結構全部重繪一次,因此效率非常低下,不過滿足普通應用界面的需求還是綽綽有余),但是 SurfaceView 也有一些非常不便的限制。

因為 SurfaceView 的內容不在應用窗口上,所以不能使用變換(平移、縮放、旋轉等)。也難以放在 ListView 或者 ScrollView 中,不能使用 UI 控件的一些特性比如 View.setAlpha()。

為了解決這個問題 Android 4.0 中引入了 TextureView。

(原諒我吧,上述內容引自: Android TextureView 簡易教程,該作者確實說得不錯,我沒什么好補充的了,哈哈,還有個原因就是有點累了,偷個懶)

TextureView 類關系圖

看看繼承結構,如下圖:


TextureView 繼承結構

繼承自 View,那沒什么說的,看看它的兄弟 SurfaceView,見圖:

SurfaceView 繼承結構

還真是好兄弟,一個“德性”。好吧,那看看文檔:

TextureView 文檔節選

(Tip:一個文檔還節選,別說屏幕不夠長,就是不愿折騰...呵呵)
不多說了,官方文檔上直接給了示例代碼,OK,那就用它的代碼試試(試試又不會**不是)。

TextureView 的簡單使用

TextureView 可以像一般的 View 一樣執行一些變換操作,設置透明度等。這里為了演示方便,我使用了兩個下拉列表來改變透明度和變換角度,看代碼吧:

public class TextureViewDemoActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {

    private static final String TAG = "TextureViewDemoActivity";

    private Spinner mSPSetAlpha;
    private Spinner mSPSetRotation;
    private TextureView mTTVTest;

    private Camera mCamera;
    private Float[] mAlphaValueArr = {0.2f, 0.4f, 0.6f, 0.8f, 1.0f};
    private Float[] mRotationValueArr = {15.0f, 30.0f, 45.0f, 60.0f, 90.0f};
    private float mAlphaValue = 1.0f;
    private float mRotationValue = 90.0f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_textureviewdemo);

        initView();
        initData();
        initListener();
    }

    private void initView() {
        this.mSPSetAlpha = (Spinner) this.findViewById(R.id.sp_setalphavalue);
        this.mSPSetRotation = (Spinner) this.findViewById(R.id.sp_setrotationvalue);
        this.mTTVTest = (TextureView) this.findViewById(R.id.ttv_test);
    }

    private void initData() {
        ArrayAdapter<Float> setAlphaAdapter = new ArrayAdapter<Float>(this,android.R.layout.simple_list_item_1, mAlphaValueArr);
        setAlphaAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        this.mSPSetAlpha.setAdapter(setAlphaAdapter);
        ArrayAdapter<Float> setRotationAdapter = new ArrayAdapter<Float>(this,android.R.layout.simple_list_item_1, mRotationValueArr);
        setRotationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        this.mSPSetRotation.setAdapter(setRotationAdapter);
    }

    private void initListener() {
        this.mTTVTest.setSurfaceTextureListener(this);
        this.mSPSetAlpha.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                mAlphaValue = mAlphaValueArr[position];
                mTTVTest.setAlpha(mAlphaValue);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        this.mSPSetRotation.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                mRotationValue = mRotationValueArr[position];
                mTTVTest.setRotation(mRotationValue);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mCamera = Camera.open();
        try {
            mCamera.setPreviewTexture(surface);
        } catch (IOException t) {
            Log.e(TAG, t.getMessage());
        }
        mCamera.startPreview();
        mTTVTest.setAlpha(mAlphaValue);
        mTTVTest.setRotation(mRotationValue);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
        }
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }
}

布局很簡單,這里就不貼了!

這里只是一個簡單的用法展示,具體的使用中有沒有坑,還未知,你要是遇到了,請告訴我。

推薦:一個不用翻墻的在線 Android 文檔網站:踏得網

GitHub

總結到這,講的比較簡單,你要是感覺有用,那就幫忙點個喜歡,祝好...

附錄:

Andorid4.x 新控件介紹思維導圖
Andorid4.x 新控件介紹思維導圖.png

參考:

http://blog.csdn.net/pku_android/article/details/7343258
http://blog.csdn.net/pku_android/article/details/7343258
http://blog.csdn.net/xerophyte000/article/details/46045041
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1213/2153.html
http://tech.it168.com/a2011/1122/1277/000001277274.shtml
http://blog.csdn.net/zhangzeyuaaa/article/details/40711047
http://www.tuicool.com/articles/Abu6ji

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容