本文是我们名为“ Android UI设计–基础 ”的学院课程的一部分。
在本课程中,您将了解Android UI设计的基础知识。 您将了解用户输入,视图和布局以及适配器和片段。 在这里查看 !
1.概述
在本文中,我们将介绍Android中的一些多媒体和图形方面的内容。 Android SDK提供了一组API,用于处理多媒体文件,例如音频,视频和图像。 此外,SDK提供了其他API集,可帮助开发人员实现有趣的图形效果,例如动画等。
现代智能手机和平板电脑的存储容量不断增加,因此我们可以存储音乐文件,视频文件,图像等。不仅存储容量很重要,而且高清摄像头还可以拍摄令人印象深刻的照片。 在这种情况下,多媒体API扮演着重要的角色。
2.多媒体API
Android支持各种音频,视频和图像格式。 您可以在这里看看有什么想法; 仅列举几种受支持的格式:
音讯
- MP3
- MIDI
- Vorbis(ES:MKV)
视频
- H.263
- MPEG-4 SP
图片
- JPEG格式
- GIF
- PNG
此外,Android可以处理本地文件,这意味着使用数据流存储在智能手机或平板电脑内部的文件或远程文件。 我们可以利用这些功能来构建非常有趣的应用程序。
Android SDK提供的所有可用于向应用程序添加多媒体功能的类都在android.media
包下。 在此程序包中,心脏类称为MediaPlayer
。 此类有几种方法,我们可以用来播放存储在设备中或从远程服务器流式传输的音频和视频文件。
此类实现具有定义明确的状态的状态机,我们在播放文件之前必须了解它们。 如官方文档中所示,简化状态图,我们可以定义以下宏状态:
- 空闲状态:当我们创建MediaPlayer类的新实例时。
- 初始化状态:当我们使用
setDataSource
设置MediaPlayer
必须使用的信息源时,将触发此状态。 - 准备状态:在此状态下,准备工作已完成。 我们可以进入这种状态,调用
prepare
方法或prepareAsync
。 在第一种情况下,方法返回后,状态移至Prepared
。 以异步方式,我们必须实现一个侦听器,以便在系统准备就绪且状态移至Prepared
时得到通知。 我们必须记住,在调用prepare
方法时,整个应用程序可能会在方法返回之前挂起,因为该方法可能需要很长时间才能完成工作,尤其是从远程服务器流式传输数据时。 我们应该避免在主线程中调用此方法,因为它可能会导致ANR(应用程序无响应)问题。 一旦MediaPlayer
处于准备状态,我们就可以播放,暂停或停止文件。 - 完成状态:到达流的末尾。
我们可以通过几种方式播放文件:
// Raw audio file as resource
MediaPlayer mp = MediaPlayer.create(this, R.raw.audio_file);
// Local file
MediaPlayer mp1 = MediaPlayer.create(this, Uri.parse("file:///...."));
// Remote file
MediaPlayer mp2 = MediaPlayer.create(this, Uri.parse("http://website.com"));
或者我们可以通过以下方式使用setDataSource
:
MediaPlayer mp3 = new MediaPlayer();
mp3.setDataSource("http://www.website.com");
创建MediaPlayer
我们可以“准备”它:
mp3.prepare();
最后,我们可以播放它:
mp3.start();
请记住以上有关准备状态的注意事项。 根据他们的说法,我们可以使用异步操作,这样我们就不会停止主线程。 在这种情况下,我们有:
// Remote file
MediaPlayer mp2 = MediaPlayer.create(this, Uri.parse("http://website.com"));
mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.start();
}
});
mp2.prepareAsync();
当MediaPlayer
处于准备状态时,我们使用了一个侦听器来通知,因此我们可以开始播放。 最后,当我们不再需要MediaPlayer
实例时,应该释放它:
mp2.release();
使用Android相机
如果我们希望使用集成的智能手机摄像头向我们的应用程序添加拍照功能,那么最好的方法就是使用Intent
。 例如,假设我们要在按下按钮并在应用程序中显示结果后立即启动相机。
在Activity
的onCreate
方法中,我们必须设置Button
的侦听器,并在单击以激发意图时:
Button b = (Button) findViewById(R.id.btn1);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Here we fire the intent to start the camera
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, 100);
}
});
在onActivityResult
方法中,我们检索拍摄的照片并显示结果:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// This is called when we finish taking the photo
Bitmap bmp = (Bitmap) data.getExtras().get("data");
iv.setImageBitmap(bmp);
}
运行我们拥有的应用程序:
在上面的示例中,我们使用了仿真相机。
3.图形
到目前为止,我们已经讨论了可以在UI中使用的标准组件。 这很好,但是当我们要开发需要图形内容的游戏或应用程序时,这还不够。 Android SDK提供了一组用于绘制自定义2D和3D图形的API。 当我们编写需要图形的应用程序时,应考虑图形使用的强度。 换句话说,可能有一个应用程序使用了完全静态的图形而没有复杂的效果,并且可能有其他应用程序使用了密集的图形效果,例如游戏。
根据这种用法,我们可以采用不同的技术:
- Canvas和Drawable:在这种情况下,我们可以扩展现有的UI小部件,以便我们可以自定义其行为,也可以使用
Canvas
类提供的标准方法来创建自定义2D图形。 - 硬件加速:使用
Canvas
API进行绘制时,我们可以使用硬件加速。 从Android 3.0可以实现。 - OpenGL: Android使用NDK原生支持OpenGL。 当我们拥有一个使用大量图形内容(例如游戏)的应用程序时,此技术非常有用。
使用2D图形的最简单方法是扩展View
类并覆盖onDraw
方法。 当我们不需要图形密集型应用程序时,可以使用此技术。
在这种情况下,我们可以使用Canvas
类创建2D图形。 此类提供了一组以draw*
开头的方法,可用于绘制不同的形状,例如:
- 线
- 圈
- 长方形
- 椭圆
- 图片
- 弧
例如,让我们假设我们想要绘制一个矩形。 我们创建一个自定义视图,然后覆盖onDraw
方法。 在这里我们绘制矩形:
public class TestView extends View {
public TestView(Context context) {
super(context);
}
public TestView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
p.setColor(Color.GREEN);
p.setStrokeWidth(1);
p.setStyle(Paint.Style.STROKE);
canvas.drawRect(5, 5, 120, 120, p);
invalidate();
}
}
从上面的代码可以清楚地看到,在onDraw
方法中,我们使用了drawRect
Canvas
方法。 注意,我们使用了另一个名为Paint
类。 此类指定如何绘制形状。 它指定其颜色(如果必须填充),边框宽度等。
在这种情况下,布局如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.swa.customview.TestView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
运行该应用程序,我们有:
假设我们要用渐变颜色填充矩形,因此onDraw
方法变为:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
p.setColor(Color.GREEN);
p.setStrokeWidth(1);
p.setStyle(Paint.Style.FILL_AND_STROKE);
LinearGradient lg = new LinearGradient(0F, 0F, 115F,115F, Color.GREEN, Color.YELLOW, TileMode.CLAMP);
p.setShader(lg);
canvas.drawRect(5, 5, 120, 120, p);
invalidate();
}
运行我们拥有的应用程序:
如前所述,从Android 3.0(API 11)开始,我们可以使用硬件加速。 在这种情况下,如果要使用它,我们必须修改Manifest.xml
并添加以下行:
<application android:hardwareAccelerated="true" >
或者我们可以在“ Activity
级别使用它。
4.可绘制
在Android中, Drawable
是可以在屏幕上显示的图形对象。 从API的角度来看,所有Drawable
对象都源自Drawable
类。 它们在Android编程中具有重要作用,我们可以使用XML来创建它们。 它们与标准窗口小部件不同,因为它们不是交互式的,这意味着它们不会对用户的触摸做出反应。
图像,颜色,形状,根据其状态改变其外观的对象,可以动画的对象都是可绘制的对象。 在Android的res
目录下,有一个子目录保留给Drawable
,它称为res/drawable
。
在drawable
目录下,我们可以添加二进制文件,例如图像或XML文件。
正如我们在前面的文章中看到的,我们可以根据我们要支持的屏幕密度来创建几个目录。 这些目录的名称类似于drawable-<>
。
当我们使用图像时,这非常有用。 在这种情况下,我们必须创建多个图像版本:例如,我们可以为高dpi屏幕创建一个图像,或者为中dpi屏幕创建另一个图像。 将文件保存在drawable
目录下后,可以在类中使用R.drawable.file_name
引用它。 虽然很容易将二进制文件添加到这些目录之一,但这是复制和粘贴的问题,如果我们要使用XML文件,则必须创建它。
有几种可绘制的类型:
- 位图
- 九补丁
- 图层清单
- 状态清单
- 等级清单
- 过渡绘图
- 插图可绘制
- 剪贴画
- 可缩放比例
- 可绘制形状
一个有趣的方面是,我们可以使用XML或直接从代码中创建此类元素。 上面显示的元素和API类之间存在对应关系。 我们可以添加Drawable
后缀,并创建相应的类名:例如,如果Bitmap
drawable的相应类是BitmapDrawable
,以此类推。
如果您想了解更多信息,可以在这里看看。 我们不会在本文中介绍所有这些对象,而只会介绍最受欢迎的对象。
可绘制形状
这是通用形状。 使用XML,我们必须创建一个以shape元素为根的文件。 该元素作为名为android:shape
的属性,在其中定义矩形,椭圆形,直线和环形等形状的类型。 我们可以使用以下子元素来自定义形状:
例如,让我们假设我们要创建一个具有纯背景颜色的椭圆。 我们创建一个XML文件,例如,名为oval.xml
:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#FF0000" />
<size
android:height="100dp"
android:width="120dp" />
</shape>
这样,我们创建了一个椭圆形的形状,具有红色作为背景色,尺寸为120dpx100dp。 然后我们可以在布局文件中引用它:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/oval" />
运行该应用程序,我们获得:
例如,我们可以假设我们想要更改Button
小部件的外观。 我们要创建一个带有圆角的矩形,并创建渐变色作为背景。 我们在XML文件中定义了一个名为round_corner.xml
的形状,并将其添加到drawable
目录中:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="2dp"
android:color="#00FF00" />
<gradient
android:angle="-90"
android:endColor="#FFFFFF"
android:startColor="#00FF00"
android:type="linear" />
<corners android:radius="3dp" />
<padding
android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp" />
</shape>
在布局文件中,我们有:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/round_corner"
android:text="Click me" />
运行该应用程序,我们有:
如我们所见,仅使用XML,我们就可以修改小部件背景或创建形状。
状态清单
此可绘制对象可以根据对象状态显示多个可绘制对象。 当我们要定制一些具有内部状态的对象时,这非常有用。 例如,“ Button
小部件是这些对象之一,它具有几种状态:按下,聚焦等。
在XML中,此drawable由选择器标记表示。 此标记具有子项元素:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable=""drawable1" android:state_pressed="true"/>
<item android:drawable=""drawable2" android:state_focused="true"/>
</selector>
假设我们要在按下布局时自定义Button
小部件。 此外,我们希望将其背景更改为红色渐变颜色。 因此,我们要做的第一件事是定义两个形状:
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#00FF00" />
</shape>
green.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="-90"
android:endColor="#FFFFFF"
android:startColor="#AA0000"
android:type="linear" />
</shape>
一旦有了形状,就可以将它们分配给不同的对象状态:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/red_gradient" android:state_pressed="true"/>
<item android:drawable="@drawable/green"/>
</selector>
这样,我们在按下按钮时分配了red_gradient可绘制对象,而在默认状态下则分配了绿色可绘制对象。 运行我们拥有的应用程序:
九补丁
九修补图像是可以调整大小的特殊背景图像,以便可以容纳View
内容。 如果您想了解更多信息,可以在这里查看 。 当我们要创建图像但不知道View
内容的确切大小时可以使用它。
简要地说,在创建此图像时,我们定义了可以拉伸的边界和静态区域。 Android提供了一个工具来帮助我们在tools目录下创建此类图像。 假设我们要创建一个Button
小部件背景,我们可以创建一个图像,如下所示:
现在,我们可以在tools目录下运行draw9patch.bat
。 现在我们可以将该图像拖放到刚刚打开的窗口中:
该窗口分为两个区域:左侧是“工作窗口”,而右侧是最终结果。 现在我们必须选择可以缩放的图像区域,我们可以在左侧和顶部绘制线条,如图所示:
现在我们设置内容区域,选择图像的右侧和底部。
我们可以在右侧看到最终结果。 现在我们可以保存我们的工作。 完成后,我们可以在Android项目的res/drawable
下复制此图像。
要查看最终效果,我们可以创建如下所示的布局:
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/stdbox"
android:text="This is a standard background with red border" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn1"
android:layout_marginTop="10dp"
android:background="@drawable/box"
android:text="This is a 9 patch background with red border" />
在第一个按钮中,我们使用标准图像,如上面所示的红色框,而在第二个按钮中,我们使用9-patch
图像。
运行示例,我们有:
您会注意到9-patch
图像的缩放比标准图像更好。
5.下载源代码
这是有关如何在Android上使用多媒体的课程。 您可以在此处下载源代码:
翻译自: https://www.javacodegeeks.com/2015/09/android-ui-adding-multimedia-to-an-app.html