Android 图形系统及其应用

. Android 图形系统

本着知其然,要知其所以然的精神,我探索了Android的图形系统。Android 的图形系统采用client/server架构。Server(SurfaceFlinger)主要由C++代码编写而成。Client 端代码分为两部分, 一部分是由Java提供的供应用使用的api, 另一部分则是由C++写成的底层实现。Android 图形系统的框架如下图,下面我就介绍几个概念.

Application

Java

View/widgets/canvas

opengl

surface

Skia 作为Android的图形系统,由如下特征

· 高度优化的软件 rasteriser (module sgl/)

· 选择性透过 OpenGL/ES,加速特定操作,如 shader textures (module gl/)

· 动画处理能力(module animator/)

· 内建 SVG 支援 (module (svg/)

· 内建若干 image codec,如 PNG, JPEG, GIF, BMP (modules images/)

· 内建文字处理,但缺乏泰文、藏文一类复杂文字处理的能力

· 效能特性:

· image 与特定数据型态的 Copy-on-write

· 内部存储器管理,谨慎地被免 fragmentation

· Thread-safety

SurfaceFlinger
SurfaceFlinger
在整个图形系统中担任 server 角色,它负责将各个 surface 根据 Z order 合成 (composer) 起来。

Surface

Android图形系统中一个重要的概念和线索是surfaceView及其子类(如 TextView, Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理viewsurface上的绘图操作,如画点画线。每个 canvas对象对应一个bitmap,存储画在surface上的内容。

每个Surface通常对应两个buffer,一个front buffer, 一个back buffer。其中, back buffer就是canvas绘图时对应的bitmap (研究 android _view_Surface.cpp::lockCanvas)。因此,绘画总是在back buffer上,需要更新时,则将back bufferfront buffer互换。

除了surfaceviews, 具有相同的vievrootview 共享surface

Layer

surface又对应一个layer, SurfaceFlinger负责将各个layerfront buffer合成(composite)绘制 到屏幕上。

具体想进一步了解图形系统可以参看Android图形系统

总结: 理解Android 图形系统,对于编写Android 图形程序是有帮助的。当然想换个图形引擎的话,就不是那么简单,图形系统代码多达十万行左右,没有一定的功底是无法胜任的。

图形系统应用

编写图形应用,我遵循了明确需求,建立模型,编写核心算法,实现功能的软件工程方法。

(1) 明确需求: 实现浏览图片时的酷眩效果。如下图

1. 向下触屏时,图片由上而下逐渐变大。

2. 向上触屏时,图片由下而上逐渐变小。

3. 向右触屏时,每张图片有向右滑出手机屏幕的动作。同时有新的系列图片从屏幕左边飞进来。同样向左边触屏,动作, 方向与向右屏幕相反。

4. 当点击某个图片的时候,图片放大,同时透明度达到最大。

(2) 建立模型

1. 定义图片集合(目前一个屏幕五个图形)

定义 private int[] mImageIds = { R.drawable.gallery_photo_1,

R.drawable.gallery_photo_2, R.drawable.gallery_photo_3,

R.drawable.gallery_photo_4, R.drawable.gallery_photo_5 };

每次触屏时,更换数组的数据,达到更新图片数据的目的.

2. 定义方向

根据触摸的坐标值来判断上下左右.

3. 计算图片间的间隙以及伸缩,透明度比例

4. 采用Animation实现图片飞进,飞出的效果。

(3) 编写核心算法

目前仅实现了图片伸缩,以及透明度变化,代码如下

private void drawBitmap(Canvas canvas, int i, float diffScale, int diffAlpha) {

int offset = myposition - i;

if (offset != 0) {

int alpha = 255 - Math.abs(offset) * 50 + diffAlpha;

mPaint.setAlpha(alpha > 255 ? 255 : alpha);

float scale = getScale(offset); // 根据不同位置的offset计算出缩放比例

scale = scale * diffScale;

// scale = (scale > 1 ? 1 : scale);

matrix.postScale(scale, scale);

} else {

mPaint.setAlpha(255);

}

Bitmap bp = BitmapFactory.decodeResource(ctx.getResources(),

mImageIds[i]);

canvas.drawBitmap(bp, matrix, mPaint);

matrix.reset();

}

鼠标控制

if (event.getAction() == event.ACTION_DOWN) {

return true;

}

if (event.getAction() == event.ACTION_MOVE) {

int p = (int) ((event.getY() - downPointY) / 5);

direction = (p > 0) ? 1 : -1;

diffScale += 0.01;

diffAlpha += 10;

this.invalidate();

return true;

}

if (event.getAction() == event.ACTION_UP) {

diffScale = 1;

diffAlpha = 0;

direction = 0;

this.invalidate();

Log.i("TAG", "up");

return true;

}

(4) 实现功能

哈,顺着我的思路做下去,实现功能不会很难了。 接下来你可能想到优化了, 提高性能了

更多相关文章

  1. android系统自带的主题与样式(theme and style)
  2. android之4.0的系统主题style修改android:Theme.Holo.Light
  3. android 电池(三):android电池系统
  4. Android入门学习:Android 系统框架及应用程序执行过程
  5. 数据显示Android“姜饼”系统用户数增多
  6. Ice Cream Sandwich系统将统一Android版本
  7. Android之系统自带的文字外观设置及实际显示效果图
  8. Android常用控件六之图片框(ImageView)
  9. 理解 Android Build 系统

随机推荐

  1. Android(安卓)3.0新亮点,新机会
  2. Android环形进度条
  3. Android教程之Android(安卓)SDK1.5模拟器
  4. cocos2dx中利用xcode 调用java中的函数
  5. Android(安卓)GreenDao 3.0使用实例讲解
  6. android 多国语言对照表
  7. Ubuntu 下 Android(安卓)反编译 apk
  8. 使用Retrofit+LiveData时的Error/Loading
  9. android 监听EditText 的变化
  10. h5和app交互