android-Canvas and Drawables
2015-12-15 23:18
344 查看
Applications such as video games should be drawing to the Canvas on its own. However, there's more than one way to do this:
In the same thread as your UI Activity, wherein you create a custom View component in your layout, call
then handle the
Or, in a separate thread, wherein you manage a
perform draws to the Canvas as fast as your thread is capable (you do not need to request
However, if you need to create a new Canvas, then you must define the
drawing will actually be performed. The Bitmap is always required for a Canvas. You can set up a new Canvas like this:
It's recommended that you ultimately draw your final graphics through a Canvas offered to you by
The Android framework will only call
that your application is prepared to be drawn, you must request your View be invalidated by calling
This indicates that you'd like your View to be drawn and Android will then call your
be instantaneous).
Note: In order to request an invalidate from a thread other than your main Activity's thread,
you must call
> Instead of handling the Surface object directly, you should handle it via a
So, when your SurfaceView is initialized, get the SurfaceHolder by calling
You should then notify the SurfaceHolder that you'd like to receive SurfaceHolder callbacks (from
by calling
it this). Then override each of the
inside your SurfaceView class.
> A
a general abstraction for "something that can be drawn." You'll discover that the Drawable class extends to define a variety of specific kinds of drawable graphics, including
and several more. Of course, you can also extend these to define your own custom Drawable objects that behave in unique ways.
There are three ways to define and instantiate a Drawable: using an image saved in your project resources; using an XML file that defines the Drawable properties; or using the
normal class constructors. Below, we'll discuss each the first two techniques (using constructors is nothing new for an experienced developer).
Note: Image resources placed in
be automatically optimized with lossless image compression by the
more than 256 colors may be converted to an 8-bit PNG with a color palette. This will result in an image of equal quality but which requires less memory. So be aware that the image binaries placed in this directory can change during the build. If you plan
on reading an image as a bit stream in order to convert it to a bitmap, put your images in the
> The following code snippet demonstrates how to build an
uses an image from drawable resources and add it to the layout.
> Here's some XML that defines a TransitionDrawable:
With this XML saved in the file
> Here's a basic extension of the View class that does just this, to draw a ShapeDrawable as a View:
> A NinePatch drawable is a standard PNG image that includes an extra 1-pixel-wide border. It must be saved with the extension
and saved into the
To clarify the difference between the different lines, the left and top lines define which pixels of the image are allowed to be replicated in order to stretch the image. The bottom
and right lines define the relative area within the image that the contents of the View are allowed to lie within.
This NinePatch defines one stretchable area with the left and top lines and the drawable area with
the bottom and right lines. In the top image, the dotted grey lines identify the regions of the image that will be replicated in order to stretch the image. The pink rectangle in the bottom image identifies the region in which the contents of the View are
allowed.
In the same thread as your UI Activity, wherein you create a custom View component in your layout, call
invalidate()and
then handle the
onDraw()callback.
Or, in a separate thread, wherein you manage a
SurfaceViewand
perform draws to the Canvas as fast as your thread is capable (you do not need to request
invalidate()).
However, if you need to create a new Canvas, then you must define the
Bitmapupon which
drawing will actually be performed. The Bitmap is always required for a Canvas. You can set up a new Canvas like this:
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b);
It's recommended that you ultimately draw your final graphics through a Canvas offered to you by
View.onDraw()or
SurfaceHolder.lockCanvas()
The Android framework will only call
onDraw()as necessary. Each time
that your application is prepared to be drawn, you must request your View be invalidated by calling
invalidate().
This indicates that you'd like your View to be drawn and Android will then call your
onDraw()method (though is not guaranteed that the callback will
be instantaneous).
Note: In order to request an invalidate from a thread other than your main Activity's thread,
you must call
postInvalidate()
> Instead of handling the Surface object directly, you should handle it via a
SurfaceHolder.
So, when your SurfaceView is initialized, get the SurfaceHolder by calling
getHolder().
You should then notify the SurfaceHolder that you'd like to receive SurfaceHolder callbacks (from
SurfaceHolder.Callback)
by calling
addCallback()(pass
it this). Then override each of the
SurfaceHolder.Callbackmethods
inside your SurfaceView class.
> A
Drawableis
a general abstraction for "something that can be drawn." You'll discover that the Drawable class extends to define a variety of specific kinds of drawable graphics, including
BitmapDrawable,
ShapeDrawable,
PictureDrawable,
LayerDrawable,
and several more. Of course, you can also extend these to define your own custom Drawable objects that behave in unique ways.
There are three ways to define and instantiate a Drawable: using an image saved in your project resources; using an XML file that defines the Drawable properties; or using the
normal class constructors. Below, we'll discuss each the first two techniques (using constructors is nothing new for an experienced developer).
Note: Image resources placed in
res/drawable/may
be automatically optimized with lossless image compression by the
aapttool during the build process. For example, a true-color PNG that does not require
more than 256 colors may be converted to an 8-bit PNG with a color palette. This will result in an image of equal quality but which requires less memory. So be aware that the image binaries placed in this directory can change during the build. If you plan
on reading an image as a bit stream in order to convert it to a bitmap, put your images in the
res/raw/folder instead, where they will not be optimized.
> The following code snippet demonstrates how to build an
ImageViewthat
uses an image from drawable resources and add it to the layout.
LinearLayout mLinearLayout; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a LinearLayout in which to add the ImageView mLinearLayout = new LinearLayout(this); // Instantiate an ImageView and define its properties ImageView i = new ImageView(this); i.setImageResource(R.drawable.my_image); i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); // Add the ImageView to the layout and set the layout as the content view mLinearLayout.addView(i); setContentView(mLinearLayout); }
> Here's some XML that defines a TransitionDrawable:
<transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image_expand"> <item android:drawable="@drawable/image_collapse"> </transition>
With this XML saved in the file
res/drawable/expand_collapse.xml, the following code will instantiate the TransitionDrawable and set it as the content of an ImageView:
Resources res = mContext.getResources(); TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.expand_collapse); ImageView image = (ImageView) findViewById(R.id.toggle_image); image.setImageDrawable(transition);
> Here's a basic extension of the View class that does just this, to draw a ShapeDrawable as a View:
public class CustomDrawableView extends View { private ShapeDrawable mDrawable; public CustomDrawableView(Context context) { super(context); int x = 10; int y = 10; int width = 300; int height = 50; mDrawable = new ShapeDrawable(new OvalShape()); mDrawable.getPaint().setColor(0xff74AC23); mDrawable.setBounds(x, y, x + width, y + height); } protected void onDraw(Canvas canvas) { mDrawable.draw(canvas); } }
> A NinePatch drawable is a standard PNG image that includes an extra 1-pixel-wide border. It must be saved with the extension
.9.png,
and saved into the
res/drawable/directory of your project.
To clarify the difference between the different lines, the left and top lines define which pixels of the image are allowed to be replicated in order to stretch the image. The bottom
and right lines define the relative area within the image that the contents of the View are allowed to lie within.
This NinePatch defines one stretchable area with the left and top lines and the drawable area with
the bottom and right lines. In the top image, the dotted grey lines identify the regions of the image that will be replicated in order to stretch the image. The pink rectangle in the bottom image identifies the region in which the contents of the View are
allowed.
相关文章推荐
- android获取短信验证码并自动填写的实现一
- Android
- Android TextView中添加图片
- Android 获取uri的正确文件路径的办法
- AndroidStudio中配置NDK开发环境和编译Fresco
- Android-JNI(2)-NDK环境搭建和简单案例
- Android 应用程序无响应(ANR)报错原因
- Android 源码解析: 图片加载库Picasso 3 核心类
- Android初识-adb启动失败原因
- android系统颜色color资源问题分析
- Android PullToRefresh 详解
- Android Studio——android中的文件操作详解以及内部存储和外部存储
- 回忆:2014进入android三个月时的那种初心!纯属个人分享初学的心态。
- Android 动态添加Spinner(.java文件内实现) 实现 改变spinner 内文字属性
- [Android]代码实现ColorStateList及StateListDrawable
- Android 动态添加线性布局(.java文件内) 实现控件按比例分割空间
- Android四大组件之ConentProvider.
- Android studio使用与设置
- android中Service组件总结
- Android Studio系列教程四--Gradle基础