- Android 系统概述
- 什么是智能手机?智能手机操作系统有哪些?
- Android(安卓)是什么?
- Android 系统架构(图解)
- Android 7 新特性介绍
- Android 开发环境搭建
- Android 开发环境搭建教程(图解)
- Android SDK 是什么?
- 通过 Android Studio 创建 Android 应用程序(附带解析)
- Android Studio 的基本调试
- Android 应用程序结构:Android 组件和资源详解
- Android 四大核心组件:Activity+Service+BroadcastReceiver+ContentProvider
- Android Activity 组件及其生命周期
- Android 资源(res 和 assets 目录)
- AndroidManifest.xml 配置文件详解
- Android App Widgets 组件详解
- Android 系统的进程和线程
- Android GUI(图形用户界面)开发
- Android View 和 ViewGroup
- Android 使用 XML 文件定义用户界面
- Android 五大布局:FrameLayout、LinearLayout、AbsoluteLayout、RelativeLayout 和 TableLayout
- Android 创建 Widget 组件实例详解
- Android Button:按钮控件
- Android CheckBox:多选按钮控件
- Android RadioGroup:单选按钮控件
- Android TextView:文本框控件
- Android EditText:编辑框控件
- Android Spinner:下拉列表控件
- Android AutoCompleteTextView:自动完成文本框控件
- Android DatePicker 和 TimePicker:时间日期选择器
- Android ProgressBar:进度条控件
- Android ScrollView:滚动视图
- Android SeekBar:拖动条控件
- Android RatingBar:评价条控件
- Android ImageView 和 ImageButton:图片视图和图片按钮
- Android ImageSwitcher 和 Gallery:图片切换器和图库
- Android GridView:网格视图
- Android Tab:面板标签控件
- Android 菜单:选项菜单+上下文菜单+子菜单
- Android Bitmap(点阵图像、绘制图像)
- Android 对话框(AlertDialog+ProgressDialog)
- Android 多窗口模式(分屏模式)
- Android 事件监听器和回调方法
- Android 电话短信拍照开发教程
- Android Intent:不同应用程序之间通信的桥梁
- Android 实现拨打电话功能
- Android 实现接收短信和发送短信功能
- Android 调用相机进行拍照
- Android 多媒体开发
- Android Service 生命周期和使用方法
- Android BroadcastReceiver:接收广播
- Android 音频以及音频播放器开发实例
- Android MediaRecorder 录制音频
- Android 视频以及视频播放器实例
- Android Camera 相机以及相机程序开发实例
- Android MediaRecorder 录制视频
- Android 数据存储(SQLite 数据库、Android App 数据备份和恢复 )
- Android 数据存储之 SharedPreferences
- Android 数据存储之文件存储
- Android 使用 SQLite 数据库存数数据
- Android SQLite 数据库操作实例
- Android ContentProvider(内容提供者)
- Android 使用系统提供的 ContentProvider
- Android 自定义 ContentProvider
- Android 使用自定义 ContentProvider
- Google App Engine 是什么?
- Android APP 数据备份与恢复
- Android BackupAgent 实现数据备份与恢复
- Android BackupAgentHelper 实现数据备份与恢复
- Android 网络编程
- 借助 GPE 让 Android APP 和 Google App Engine 通信
- Android HTTP 通信
- Android HttpURLConnection 访问互联网资源
- Android 通过 GET 方式获取互联网资源
- Android 通过 POST 方式获取互联网资源
- Android Socket 编程(附带实例)
- Bluetooth(蓝牙)是什么?
- Android 蓝牙通信开发教程(详解版)
- Android 蓝牙通信开发实例演示
- WIFI(无线局域网)是什么?
- Android WiFi 开发(WiFi 编程)实例演示
- WIFI Direct(WIFI 直连)是什么?
- Android WIFI Direct 开发教程
- Android WIFI Direct 开发实例演示
- NFC(近场通信)是什么?
- Android NFC 开发教程
- Android USB 开发简介
- Android USB 附件模式开发教程
- Android USB 主机模式开发教程
- Android SIP 开发教程
- Android 智能传感器
- LBS(位置服务)和 GPS(全球定位系统)简介
- Android LBS 位置服务开发简介
- Android GPS 定位开发教程
- Google Map API 开发简介
- Android Google Map API Key 详细申请步骤
- Google Map API 开发 Android 地图应用实例
- Android 传感器开发教程
- Android 运动传感器开发教程
- Android 位置传感器开发教程
- Android 环境传感器开发教程
- Android 绘图(2D 绘图、3D 绘图)
- Android 2D 绘图开发简介
- Android 使用自定义 View 绘图
- Android 使用 Bitmap 绘图
- Android 使用 SurfaceView 绘制静态图像
- Android 使用 SurfaceView 绘制动态图像
- Android Drawable 开发简介
- Android 3D 绘图开发简介
- Android 硬件加速开发简介
- Android RenderScript 开发简介
- Android App 的国际化和本地化
- Android 国际化和本地化开发简介
- Android 手机区域设置详细步骤
- Android 未本地化应用开发教程
- Android 本地化应用开发教程
- Android 文本输入与复制粘贴
- Android 剪贴板框架开发简介
- Android 剪贴板数据转文本开发简介
- Android 复制粘贴开发教程
- Android Content Provider 复制复杂数据开发教程
- Android 一键复制粘贴开发实例
- Android 企业级应用开发
- Android 设备管理 API 概述
- Android 开发设备管理 API 应用教程
- Android 文本语音 API 开发教程
- Android TV 应用开发教程
- Android TV 应用开发实例
- Android 可穿戴设备应用开发教程
- Android 应用程序的发布
- Android 应用程序发布的步骤
- Android 为什么要为应用程序签名?
- Android 导出未签名应用程序开发步骤
- Android 生成签名文件开发教程
- Android 应用程序签名开发教程
- zipalign 工具优化应用程序开发简介
- Google Play Store( Android Market)发布简介
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
Android 使用 SurfaceView 绘制动态图像
实例 SurfaceViewDrawDemo 绘制的是一幅静态图像,而使用 SurfaceView 可以绘制动态图像。
绘制动态图像的过程应该在一个单独的线程中完成,而不应该在主线程中进行。实例 SurfaceViewDynDrawDemo 演示了使用 SurfaceView 组件绘制动态图像的过程。
该实例修改自 Android SDK 提供的实例,绘制的是类似于 Windows 中的变幻线屏保的效果,运行效果如图 1 所示。 
图 1 实例 SurfaceViewDynDrawDemo 的运行效果
实例 SurfaceViewDynDrawDemo 的布局文件 main.xml 内容如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<SurfaceView
android:id="@+id/surfaceViewl"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>实例 SurfaceViewDynDrawDemo 的主 Activity 为 SurfaceViewDynDrawDemoActivity,其代码如下:
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfaceViewDynDrawDemoActivity extends Activity {
private SurfaceView mySurfaceView;
private DrawingThread mDrawingThread;
SurfaceHolder surfaceHolder;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mySurfaceView = (SurfaceView) findViewById(R.id.surfaceViewl);
surfaceHolder = mySurfaceView.getHolder();
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
mDrawingThread = new DrawingThread();
mDrawingThread.mSurface = surfaceHolder;
mDrawingThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mDrawingThread.mQuit = true;
}
});
}
static final class MovingPoint {
float x, y, dx, dy;
void init(int width, int height, float minStep) {
x = (float) ((width - 1) * Math.random());
y = (float) ((height - 1) * Math.random());
dx = (float) (Math.random() * minStep * 2) + 1;
dy = (float) (Math.random() * minStep * 2) + 1;
}
float adjDelta(float cur, float minStep, float maxStep) {
cur += (Math.random() * minStep) - (minStep / 2);
if (cur < 0 && cur > -minStep) cur = -minStep;
if (cur >= 0 && cur < minStep) cur = minStep;
if (cur > maxStep) cur = maxStep;
if (cur < -maxStep) cur = -maxStep;
return cur;
}
void step(int width, int height, float minStep, float maxStep) {
x += dx;
if (x <= 0 || x >= (width - 1)) {
if (x <= 0) x = 0;
else if (x >= (width - 1)) x = width - 1;
dx = adjDelta(-dx, minStep, maxStep);
}
y += dy;
if (y <= 0 || y >= (height - 1)) {
if (y <= 0) y = 0;
else if (y >= (height - 1)) y = height - 1;
dy = adjDelta(-dy, minStep, maxStep);
}
}
}
class DrawingThread extends Thread {
// These are protected by the Thread's lock
SurfaceHolder mSurface;
boolean mRunning;
boolean mActive;
boolean mQuit;
// Internal state
int mLineWidth;
float mMinStep;
float mMaxStep;
boolean mInitialized = false;
final MovingPoint mPoint1 = new MovingPoint();
final MovingPoint mPoint2 = new MovingPoint();
static final int NUM_OLD = 100;
int mNum0ld = 0;
final float[] m0ld = new float[NUM_OLD * 4];
final int[] m01dColor = new int[NUM_OLD];
int mBrightLine = 0;
// X is red, Y is blue
final MovingPoint mColor = new MovingPoint();
final Paint mBackground = new Paint();
final Paint mForeground = new Paint();
int makeGreen(int index) {
int dist = Math.abs(mBrightLine - index);
if (dist > 10) return 0;
return (255 - (dist * (255 / 10))) << 8;
}
@Override
public void run() {
mLineWidth = (int) (getResources().getDisplayMetrics().density * 1.5);
if (mLineWidth < 1) mLineWidth = 1;
mMinStep = mLineWidth * 2;
mMaxStep = mMinStep * 3;
mBackground.setColor(0xff000000);
mForeground.setColor(0xff00ffff);
mForeground.setAntiAlias(false);
mForeground.setStrokeWidth(mLineWidth);
while (true) {
if (mQuit) {
return;
}
// Lock the canvas for drawing
Canvas canvas = mSurface.lockCanvas();
if (canvas == null) {
Log.i("WindowSurface", "Failure locking canvas");
continue;
}
// Update graphics
if (!mInitialized) {
mInitialized = true;
mPoint1.init(canvas.getWidth(), canvas.getHeight(), mMinStep);
mPoint2.init(canvas.getWidth(), canvas.getHeight(), mMinStep);
mColor.init(127, 127, 1);
} else {
mPoint1.step(canvas.getWidth(), canvas.getHeight(), mMinStep, mMaxStep);
mPoint2.step(canvas.getWidth(), canvas.getHeight(), mMinStep, mMaxStep);
mColor.step(127, 127, 1, 3);
}
mBrightLine += 2;
if (mBrightLine > (NUM_OLD * 2)) {
mBrightLine = -2;
}
// Clear background
canvas.drawColor(mBackground.getColor());
// Draw old lines
for (int i = mNum0ld - 1; i >= 0; i--) {
mForeground.setColor(m01dColor[i] | makeGreen(i));
mForeground.setAlpha(((NUM_OLD - i) * 255) / NUM_OLD);
int p = i * 4;
canvas.drawLine(m0ld[p], m0ld[p + 1], m0ld[p + 2], m0ld[p + 3], mForeground);
}
// Draw new line
int red = (int) mColor.x + 128;
if (red > 255) red = 255;
int blue = (int) mColor.y + 128;
if (blue > 255) blue = 255;
int color = 0xff000000 | (red << 16) | blue;
mForeground.setColor(color | makeGreen(-2));
canvas.drawLine(mPoint1.x, mPoint1.y, mPoint2.x, mPoint2.y, mForeground);
// Add in the new line
if (mNum0ld > 1) {
System.arraycopy(m0ld, 0, m0ld, 4, (mNum0ld - 1) * 4);
System.arraycopy(m01dColor, 0, m01dColor, 1, mNum0ld - 1);
}
if (mNum0ld < NUM_OLD) mNum0ld++;
m0ld[0] = mPoint1.x;
m0ld[1] = mPoint1.y;
m0ld[2] = mPoint2.x;
m0ld[3] = mPoint2.y;
m01dColor[0] = color;
// All done
mSurface.unlockCanvasAndPost(canvas);
}
}
}
}需要注意的是,就像前面所提到的,绘制动态图像的过程必须在一个单独的线程中完成,而不能在主线程中进行。在该实例中,绘图过程是在 DrawingThread 中完成的。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论