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) {

    }
}

布局很简单,这里就不贴了!

这里只是一个简单的用法展示,具体的使用中有没有坑,还未知,你要是遇到了,请告诉我。

推荐:一个不用FQ的在线 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

文/diygreen(简书作者)
原文链接:http://www.jianshu.com/p/7ca6525fddcb
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

时间: 2024-09-30 23:52:14

AndroidStudyDemo之Android4.x介绍的相关文章

Android4.4 以太网和DHCP启动过程介绍

转自:http://blog.csdn.net/wlwl0071986/article/details/51451843 Android4.4已经加入了以太网的支持.现在对以太网的初始化流程.网络策略配置.dhcp交互过程等做一些简单的介绍. 一.以太网启动流程 1. 创建ConnectivityService SystemServer.Java // networkmanagement.networkStats.networkPolicy已经提前创建好,并作为参数传入 connectivity

Android 开源框架Universal-Image-Loader全然解析(一)--- 基本介绍及使用

大家好!差点儿相同两个来月没有写文章了.前段时间也是在忙换工作的事,准备笔试面试什么的事情,如今新工作找好了,新工作自己也比較惬意.唯一遗憾的就是自己要去一个新的城市,新的环境新的開始.希望自己能尽快的适应新环境,如今在准备交接的事情,自己也有一些时间了,所以就继续给大家分享Android方面的东西. 相信大家平时做Android应用的时候,多少会接触到异步载入图片,或者载入大量图片的问题.而载入图片我们常常会遇到很多的问题,比方说图片的错乱.OOM等问题,对于新手来说,这些问题解决起来会比較吃

Android bluetooth介绍(一):基本概念及硬件接口

关键词:蓝牙硬件接口 UART  PCM  blueZ 版本:基于android4.2之前版本 bluez内核:linux/linux3.08系统:android/android4.1.3.4作者:xubin341719(欢迎转载,请注明作者,请尊重版权谢谢)欢迎指正错误,共同学习.共同进步!! 一.基本概念补充 1.AP:ApplicationProcessor应用处理器 采用ARM架构的CPU,通常负责运行OS和一些特定设置和载入开机预设.比如一个没有电话功能的平板电脑,只跑android或

Android bluetooth介绍(二): android 蓝牙代码架构及其uart 到rfcomm流程

关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP RFCOMM  版本:基于android4.2之前版本 bluez内核:linux/linux3.08系统:android/android4.1.3.4作者:xubin341719(欢迎转载,请注明作者,请尊重版权谢谢)欢迎指正错误,共同学习.共同进步!!一.Android Bluetooth Architecture蓝牙代码架构部分(google 官方蓝牙框架) Android的蓝牙系统,自下而上包括以下一些

Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比

比较的指标: 1.cpu 2.流量 3.电量 4.内存占用 5.联网时间 功能点: 1.重试机制 2.提供的扩展功能 3.易用性 4.是否https 5.是否支持reflect api,OkHttp有配套方法 6.缓存.重试 7.cookie支持session  id会话支持 8.弱网性能和稳定性 9.超时时间,几种超时时间   连接超时,响应超时 10.适配各种机型.4.4和之前版本  2.3  4.1 5.0 4种网络连接方式提供的功能对比表格: 缓存 重试 Https/Http 稳定性 C

Android系统性能调优工具介绍

经作者授权,发表Tieto某青年牛的一篇<程序员>大作. Android系统性能调优工具介绍 在软件开发过程中,想必很多读者都遇到过系统性能问题.而解决系统性能问题的几个主要步骤是: 测评:对系统进行大量有针对性的测试,以得到合适的测试数据. 分析系统瓶颈:分析测试数据,找到其中的hotspot(热点,即bottleneck). 性能优化:对hotspot相关的代码进行优化. 由上述步骤可知,性能优化的目标对象是hotspot.如果找到的hotspot并非真正的热点,则性能优化的结果必然是事倍

Android笔记1——开发前奏1开发环境搭建和开发工具使用介绍

转载请注明http://www.cnblogs.com/devtrees/p/4382234.html 欢迎指正错误,共同进步! 一背景知识 1.1G-4G的介绍 Generation(一代) WAP(wait and pay) Wireless Markup Language(WML)精简版的html语言 二.Android概述 1.Android操作系统介绍 2.Android历史介绍 3.Android系统架构(重点) 第一层:应用层Application 第二层:应用框架层Applica

编译android4.2.2

上一篇中介绍了如何编译android4.2.2源码前的准备工作,现在介绍android源码编译流程.这里我们编译一个ARM处理器的模拟器版本. 执行envsetup.sh脚本 执行lunch命令,可以显示出可供编译的目标 在上图中看到有eng版本,userdebug版本,还有user版本我没有截图上去,这三者的区别如下 eng:debug版本 ,执行adb shell命令时,默认是root用户,权限最高 user: release版本  最终发布版本,权限低 userDebug版本:部分debu

android4.4 编译报错,和llvm 有关的

问题描述 最近想看一下android4.4 的source ,但是在编译的过程中遇到了下面的问题,各位大哥帮忙看一下,我实在是搞不定了,网上介绍的关于4.0 的类似的错误修改方法在4.4 上无效,其实错误也不是一样的. 4.0 的错误修改方法: $vi external/llvm/llvm-host-build.mk + LOCAL_LDLIBS := -lpthread -ldl 下面的是4.4 编译报错信息 external/llvm/lib/Transforms/Vectorize/BBV