CanvasとDrawable
CanvasとDrawable
Androidはあなたのインタフェースをカスタマイズするために絵描きAPIを提供しています.2 Dインタフェースをカスタマイズするには2つの方法があります.1、Layoutでviewを描くには、自分の画像やアニメーションを修正するだけです.2,Canvasで直接描画
Canvasはキャンバスで、ブラシをカスタマイズしてキャンバスに絵を描くことができます.
メソッド2:aでは、UIスレッドの場合、カスタムViewを作成し、invalidate()を呼び出して再描画する必要があります.onDraw()コールバックで図面をカスタマイズします.b、個別のプロセスでは、Canvasを描画するためにSurfaceViewを管理する必要があります(invalidate()を呼び出す必要はありません).
Canvas図面の使用
Canvasで絵を描くと、Canvasは本物のsurfaceを操作するインタフェースのようなものです.Canvasは様々なdrawの方法を提供し、図面を描くのに役立ちます.Canvasはその下のBitmapに描かれています.
どこでCanvasを手に入れることができますか?はonDraw()メソッドで入手できます.このメソッドパラメータはCanvasで、Canvas上で描画できます. またはSurface Viewオブジェクトの操作時にSurface Holderを通過する.lockCanvas()を使用してCanvasを取得します.
もちろん、新しいCanvasを再作成することもできます.方法は次のとおりです.
Bitmapは必須!!Canvasのすべてのdraw描画動作は、実際の効果を反映するために特定のBitmap画像に描画する必要があります.
このときCanvasの様々な描画方法を呼び出してBitmap上に描画することができます.(Canvasの新規作成はお勧めしませんが、上記2の方法でCanvasを取得します)
CanvasクラスにはdrawBitmap(...)、drawRect(...)、drawText(...)などの一連の描画方法があります.他のクラスにもdraw()メソッドがあります.たとえば、以下のDrawableオブジェクトにはdrawメソッドがありますが、Canvasをパラメータとしてdrawメソッドに転送します.
ビューに描画
アプリケーションが高速処理を必要としない場合や、将棋ゲームなどの高いフレームレートを必要としない場合.カスタムビューを作成することも考えられます.そして、提供されるCanvas上で、ViewのonDrawメソッドで直接描画します.
Androidフレームワークは必要に応じてonDrawメソッドを呼び出すだけで、システムにonDrawメソッドを呼び出すにはinvalidate()メソッドを使用します.
onDrawメソッドでは、Canvasが様々なdrawXXXメソッドを呼び出すと、AndroidシステムはこのCanvasを使用して対応するBitmap上に描画します.
サンプルコード:
このサンプルコードは/samples/スナke/.カスタマイズされたTileView.
Surface Viewで描画
Surface ViewはViewのサブクラスであり、Viewレベルで専用のペイントインタフェースを提供し、UI以外のスレッドでペイントできるメリットがあります.非UIスレッドは、Android固有の描画スケジュールに従うことなく、Surface Viewオブジェクトを保持し、その上に描画することができます.
まず、SurfaceViewのサブクラスを作成し、SurfaceHolderを実装する必要があります.Callbackインタフェース.このインタフェースには、次の方法があります.
戻りタイプ
方法
void
surfaceChanged(SurfaceHolder holder, int format, int width, int height)
void
surfaceCreated(SurfaceHolder holder)
void
surfaceDestroyed(SurfaceHolder holder)
これらのコールバックは、Surface Viewに対応するSurfaceが作成され、変更され、破棄されたときに呼び出されます.
SurfaceViewクラスでは、描画する別のスレッドクラスを定義できます.
SurfaceはSurfaceHolderによって操作されるべきであり、SurfaceViewの初期化が終了すると、
SurfaceHolderオブジェクトを取得し、SurfaceHolderのaddCallback(this)を呼び出すことによって、このSurfaceViewをSurfaceHolderのコールバックに追加します(urfaceViewがSurfaceHolder.Callbackインタフェースを実装しているため).
スレッドをSurfaceに描画できるようにするには、Surface Holderをスレッドに渡す必要があります.次に、SurfaceHolderのlockCanvas()からCanvasオブジェクトを取得して描画し、描画が終了したらunlockCanvasAndPost(Canvas canvas)を呼び出してCanvasの描画をSurfaceに適用することができます.
サンプルコード:
このサンプルコードは/samples/lunarLander/.カスタマイズされたLunarView.
注意:SurfaceHolderからCanvasを得るたびに、Canvasの前の状態は維持されます.あなたの描画をよりよく表示するために、Surface全体を再描画する必要があります.たとえば、drawColor()を使用してカラーまたはdrawBitmap()を塗りつぶして背景を設定し、Canvasの前の状態をクリアできます.そうでなければ、前のCanvasの内容(重ね合わせ)が表示されます.
Drawables
Drawableは私たちがよく使うリソースで、画像でもxml定義の形状でも構いません.Drawableは、BitmapDrawable、ShapeDrawable、PictureDrawable、LayerDrawableなどを含むベースクラスです.これらのクラスを継承して独自のDrawableクラスを定義することもできます.Drawableオブジェクトを定義して初期化するには、3つの方法があります.-エンジニアリングリソースで使用されるピクチャファイル-drawableディレクトリのxml、定義されたDrawableオブジェクトを使用します.-Drawableクラスを使用して作成します.
リソースピクチャから作成
画像フォーマットはPNG,JPG,GIFに限定され,アプリケーションアイコン,Logo,ゲームリソースなどに用いられることが多い.画像ファイルはres/drawable/ディレクトリに配置され、コードまたはlayoutファイルで使用できます.注意:res/drawable/ディレクトリの下のピクチャファイルは、パッケージ化時にaaptツールによって自動的に最適化される可能性があります.例えば、256色未満の真色のPNGピクチャが8-bitのPNGピクチャに変換され、メモリを節約することができます(ただし、ピクチャの品質はそれほど悪くありません).コードで画像のデータストリームを取得してBitmapを取得したい場合は、res/rawディレクトリの下に画像を置くことができます.res/rawディレクトリは最適化されません.
サンプルコード:次のコードは、ピクチャリソースを使用してImageViewを作成し、Layoutに追加する方法を示しています.
Drawableオブジェクトを入手したい場合は、(IntのIDではなく)次のように操作できます.
xmlファイル:
注意:このリソースを使用してオブジェクトをインスタンス化しても、プロジェクト内の各リソースは1つの状態しか維持できません.たとえば、1つのピクチャを使用して、2つのDrawableオブジェクトをインスタンス化し、alphaなどのプロパティを変更します.では、この修正は別のDrawableにも影響します.同じリソースを使用する複数のインスタンスを処理したい場合は、Viewアニメーションを使用することを考慮してください.
XMLリソースファイルを使用したDrawableのカスタマイズ
Drawableがピクチャでない場合、コードを使用してDrawableリソースを初期化することに対して、XMLを使用する利点は明らかであり、ここでは後述しない.DrawableのXMLファイルはres/drawable/ディレクトリの下にあり、同じようにResourcesを通じて使用できます.getDrawable(resourceID)を使用してDrawableオブジェクトを取得します.inflate()メソッドを実装したDrawableサブクラスはすべてXMLによって定義および初期化でき、DrawableサブクラスはXMLで定義されたプロパティによってDrawableオブジェクトを作成します.
Drawableサブクラス:
TransitionDrawableの例:TransitionDrawableは遷移効果のあるdrawableです.
継承関係:android.graphics.drawable.Drawable android.graphics.drawable.LayerDrawable android.graphics.drawable.TransitionDrawable xmlファイルを使用して、2つのピクチャを含むTransitionDrawableを定義します.
XML定義(expand_collapse.xml):
Javaで使用する:
そして呼び出すことができます
で行ないます.効果の例:
Shape Drawable
Drawableはその名の通り描くことができ、画像はもちろん描くことができますが、画像のほかに形も描くことができます.-効果は粗いですが.ShapeDrawableはDrawableの拡張ですが、結局Drawableなので、Viewの背景(setBackgroundDrawable()にすることができます.自分のビューをカスタマイズすることもできます.ShapeDrawableには独自のdraw()メソッドがあるので、Viewをカスタマイズするときは、View.onDraw()メソッドで呼び出してこのShapeDrawableを描画します.次のコードは、カスタムViewの例です.
コードは楕円形をカスタムビューとして描き、onDrawメソッドでこのDrawableを描きます.
カスタマイズされたViewが定義されると、コードで直接使用できます.上のカスタマイズされたViewの使用は次のようになります.
XMLでも定義できます.
カスタムViewの場合は、独自のプロパティをカスタマイズし、XMLでもカスタムViewを定義できます.ここでは余計なことは言わないで、後で1編だけ書きます.
Nine-patch画像
Nine-patch画像は9.pngの最後の画像で、一般的にres/drawable/ディレクトリに置かれています.コードの中でNinePatchDrawableオブジェクトです.AndroidではNine-patch画像をViewの背景にすることができます.メリットは、画像が伸びてモザイクにならないことです.Androidが持っているButtonボタンのような典型的なアプリケーションは、ボタンがどんなに大きくても滑らかに見えます.Nine-patchピクチャは、標準的なPNGピクチャに基づいて周辺に画素を1周増やした.
外輪の多いピクセルは、ピクチャがスケールされたときに、どの領域が引き伸ばされ、どの領域が動かないかを定義するために使用されます.
次の図は典型的な9である.PNGのボタン画像
ただし、1は、上図のグレーポイントで構成された領域が、画像が伸びたときにコピーされた画像を塗りつぶします.2,下の図のピンクの領域が内部のTextに入らない場合、画像が引っ張られます.
9.PNGの編集
9.PNGの使用
仮定9.PNGはres/drawable/my_として保存button_background.9.pngファイルは、この画像のXmlファイルを使用して以下のように定義されています.
その中でlayout_widthとlayout_heightはwrap_に設定されていますコンテンツが増えるにつれて、画像が自動的に
Android ,
Androidはあなたのインタフェースをカスタマイズするために絵描きAPIを提供しています.2 Dインタフェースをカスタマイズするには2つの方法があります.1、Layoutでviewを描くには、自分の画像やアニメーションを修正するだけです.2,Canvasで直接描画
Canvasはキャンバスで、ブラシをカスタマイズしてキャンバスに絵を描くことができます.
メソッド2:aでは、UIスレッドの場合、カスタムViewを作成し、invalidate()を呼び出して再描画する必要があります.onDraw()コールバックで図面をカスタマイズします.b、個別のプロセスでは、Canvasを描画するためにSurfaceViewを管理する必要があります(invalidate()を呼び出す必要はありません).
Canvas図面の使用
Canvasで絵を描くと、Canvasは本物のsurfaceを操作するインタフェースのようなものです.Canvasは様々なdrawの方法を提供し、図面を描くのに役立ちます.Canvasはその下のBitmapに描かれています.
どこでCanvasを手に入れることができますか?
もちろん、新しいCanvasを再作成することもできます.方法は次のとおりです.
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
Bitmapは必須!!Canvasのすべてのdraw描画動作は、実際の効果を反映するために特定のBitmap画像に描画する必要があります.
このときCanvasの様々な描画方法を呼び出してBitmap上に描画することができます.(Canvasの新規作成はお勧めしませんが、上記2の方法でCanvasを取得します)
CanvasクラスにはdrawBitmap(...)、drawRect(...)、drawText(...)などの一連の描画方法があります.他のクラスにもdraw()メソッドがあります.たとえば、以下のDrawableオブジェクトにはdrawメソッドがありますが、Canvasをパラメータとしてdrawメソッドに転送します.
ビューに描画
アプリケーションが高速処理を必要としない場合や、将棋ゲームなどの高いフレームレートを必要としない場合.カスタムビューを作成することも考えられます.そして、提供されるCanvas上で、ViewのonDrawメソッドで直接描画します.
Androidフレームワークは必要に応じてonDrawメソッドを呼び出すだけで、システムにonDrawメソッドを呼び出すにはinvalidate()メソッドを使用します.
onDrawメソッドでは、Canvasが様々なdrawXXXメソッドを呼び出すと、AndroidシステムはこのCanvasを使用して対応するBitmap上に描画します.
invalidate() UI 。 UI , postInvalidate().
サンプルコード:
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int x = 0; x < mXTileCount; x += 1) {
for (int y = 0; y < mYTileCount; y += 1) {
if (mTileGrid[x][y] > 0) {
canvas.drawBitmap(mTileArray[mTileGrid[x][y]], mXOffset + x * mTileSize,
mYOffset + y * mTileSize, mPaint);
}
}
}
}
このサンプルコードは/samples/スナke/.カスタマイズされたTileView.
Surface Viewで描画
Surface ViewはViewのサブクラスであり、Viewレベルで専用のペイントインタフェースを提供し、UI以外のスレッドでペイントできるメリットがあります.非UIスレッドは、Android固有の描画スケジュールに従うことなく、Surface Viewオブジェクトを保持し、その上に描画することができます.
まず、SurfaceViewのサブクラスを作成し、SurfaceHolderを実装する必要があります.Callbackインタフェース.このインタフェースには、次の方法があります.
戻りタイプ
方法
void
surfaceChanged(SurfaceHolder holder, int format, int width, int height)
void
surfaceCreated(SurfaceHolder holder)
void
surfaceDestroyed(SurfaceHolder holder)
これらのコールバックは、Surface Viewに対応するSurfaceが作成され、変更され、破棄されたときに呼び出されます.
SurfaceViewクラスでは、描画する別のスレッドクラスを定義できます.
SurfaceはSurfaceHolderによって操作されるべきであり、SurfaceViewの初期化が終了すると、
getHolder()
SurfaceHolderオブジェクトを取得し、SurfaceHolderのaddCallback(this)を呼び出すことによって、このSurfaceViewをSurfaceHolderのコールバックに追加します(urfaceViewがSurfaceHolder.Callbackインタフェースを実装しているため).
スレッドをSurfaceに描画できるようにするには、Surface Holderをスレッドに渡す必要があります.次に、SurfaceHolderのlockCanvas()からCanvasオブジェクトを取得して描画し、描画が終了したらunlockCanvasAndPost(Canvas canvas)を呼び出してCanvasの描画をSurfaceに適用することができます.
サンプルコード:
class LunarView extends SurfaceView implements SurfaceHolder.Callback {
class LunarThread extends Thread {
@Override
public void run() {
/* SurfaceHolder lockCanvas() Canvas , , unlockCanvasAndPost(Canvas canvas) Canvas Surface */
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) updatePhysics();
doDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
....
....
public LunarView(Context context, AttributeSet attrs) {
super(context, attrs);
// SurfaceHolder
SurfaceHolder holder = getHolder();
holder.addCallback(this);
// create thread only; it's started in surfaceCreated()
thread = new LunarThread(holder, context, new Handler() {
@Override
public void handleMessage(Message m) {
mStatusText.setVisibility(m.getData().getInt("viz"));
mStatusText.setText(m.getData().getString("text"));
}
});
setFocusable(true); // make sure we get key events
}
....
....
このサンプルコードは/samples/lunarLander/.カスタマイズされたLunarView.
注意:SurfaceHolderからCanvasを得るたびに、Canvasの前の状態は維持されます.あなたの描画をよりよく表示するために、Surface全体を再描画する必要があります.たとえば、drawColor()を使用してカラーまたはdrawBitmap()を塗りつぶして背景を設定し、Canvasの前の状態をクリアできます.そうでなければ、前のCanvasの内容(重ね合わせ)が表示されます.
Drawables
Drawableは私たちがよく使うリソースで、画像でもxml定義の形状でも構いません.Drawableは、BitmapDrawable、ShapeDrawable、PictureDrawable、LayerDrawableなどを含むベースクラスです.これらのクラスを継承して独自のDrawableクラスを定義することもできます.Drawableオブジェクトを定義して初期化するには、3つの方法があります.-エンジニアリングリソースで使用されるピクチャファイル-drawableディレクトリのxml、定義されたDrawableオブジェクトを使用します.-Drawableクラスを使用して作成します.
リソースピクチャから作成
画像フォーマットはPNG,JPG,GIFに限定され,アプリケーションアイコン,Logo,ゲームリソースなどに用いられることが多い.画像ファイルはres/drawable/ディレクトリに配置され、コードまたはlayoutファイルで使用できます.注意:res/drawable/ディレクトリの下のピクチャファイルは、パッケージ化時にaaptツールによって自動的に最適化される可能性があります.例えば、256色未満の真色のPNGピクチャが8-bitのPNGピクチャに変換され、メモリを節約することができます(ただし、ピクチャの品質はそれほど悪くありません).コードで画像のデータストリームを取得してBitmapを取得したい場合は、res/rawディレクトリの下に画像を置くことができます.res/rawディレクトリは最適化されません.
サンプルコード:次のコードは、ピクチャリソースを使用してImageViewを作成し、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);
}
Drawableオブジェクトを入手したい場合は、(IntのIDではなく)次のように操作できます.
Resources res = mContext.getResources();
Drawable myImage = res.getDrawable(R.drawable.my_image);
xmlファイル:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:tint="#55ff0000" android:src="@drawable/my_image"/>
注意:このリソースを使用してオブジェクトをインスタンス化しても、プロジェクト内の各リソースは1つの状態しか維持できません.たとえば、1つのピクチャを使用して、2つのDrawableオブジェクトをインスタンス化し、alphaなどのプロパティを変更します.では、この修正は別のDrawableにも影響します.同じリソースを使用する複数のインスタンスを処理したい場合は、Viewアニメーションを使用することを考慮してください.
XMLリソースファイルを使用したDrawableのカスタマイズ
Drawableがピクチャでない場合、コードを使用してDrawableリソースを初期化することに対して、XMLを使用する利点は明らかであり、ここでは後述しない.DrawableのXMLファイルはres/drawable/ディレクトリの下にあり、同じようにResourcesを通じて使用できます.getDrawable(resourceID)を使用してDrawableオブジェクトを取得します.inflate()メソッドを実装したDrawableサブクラスはすべてXMLによって定義および初期化でき、DrawableサブクラスはXMLで定義されたプロパティによってDrawableオブジェクトを作成します.
Drawableサブクラス:
AnimatedRotateDrawable
BitmapDrawable
ClipDrawable
ColorDrawable
DrawableContainer
GradientDrawable
InsetDrawable
LayerDrawable
NinePatchDrawable
PictureDrawable
RotateDrawable
ScaleDrawable
ScrollBarDrawable
ShapeDrawable
TransitionDrawableの例:TransitionDrawableは遷移効果のあるdrawableです.
継承関係:android.graphics.drawable.Drawable android.graphics.drawable.LayerDrawable android.graphics.drawable.TransitionDrawable xmlファイルを使用して、2つのピクチャを含むTransitionDrawableを定義します.
XML定義(expand_collapse.xml):
<transition xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/penguins"/>
<item android:drawable="@drawable/tulips"/>
</transition>
Javaで使用する:
Resources res = mContext.getResources();
TransitionDrawable transition = (TransitionDrawable)
res.getDrawable(R.drawable.expand_collapse);
ImageView image = (ImageView) findViewById(R.id.toggle_image);
image.setImageDrawable(transition);
そして呼び出すことができます
transition.startTransition(1000);
で行ないます.効果の例:
Shape Drawable
Drawableはその名の通り描くことができ、画像はもちろん描くことができますが、画像のほかに形も描くことができます.-効果は粗いですが.ShapeDrawableはDrawableの拡張ですが、結局Drawableなので、Viewの背景(setBackgroundDrawable()にすることができます.自分のビューをカスタマイズすることもできます.ShapeDrawableには独自のdraw()メソッドがあるので、Viewをカスタマイズするときは、View.onDraw()メソッドで呼び出してこのShapeDrawableを描画します.次のコードは、カスタム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);// bound
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
コードは楕円形をカスタムビューとして描き、onDrawメソッドでこのDrawableを描きます.
カスタマイズされたViewが定義されると、コードで直接使用できます.上のカスタマイズされたViewの使用は次のようになります.
CustomDrawableView mCustomDrawableView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCustomDrawableView = new CustomDrawableView(this);
setContentView(mCustomDrawableView);
}
XMLでも定義できます.
<com.example.shapedrawable.CustomDrawableView android:layout_width="fill_parent" android:layout_height="wrap_content" />
カスタムViewの場合は、独自のプロパティをカスタマイズし、XMLでもカスタムViewを定義できます.ここでは余計なことは言わないで、後で1編だけ書きます.
Nine-patch画像
Nine-patch画像は9.pngの最後の画像で、一般的にres/drawable/ディレクトリに置かれています.コードの中でNinePatchDrawableオブジェクトです.AndroidではNine-patch画像をViewの背景にすることができます.メリットは、画像が伸びてモザイクにならないことです.Androidが持っているButtonボタンのような典型的なアプリケーションは、ボタンがどんなに大きくても滑らかに見えます.Nine-patchピクチャは、標準的なPNGピクチャに基づいて周辺に画素を1周増やした.
外輪の多いピクセルは、ピクチャがスケールされたときに、どの領域が引き伸ばされ、どの領域が動かないかを定義するために使用されます.
: 1 。
: 1 。( )
( View 9.png , View , , , )
次の図は典型的な9である.PNGのボタン画像
ただし、1は、上図のグレーポイントで構成された領域が、画像が伸びたときにコピーされた画像を塗りつぶします.2,下の図のピンクの領域が内部のTextに入らない場合、画像が引っ張られます.
9.PNGの編集
9.PNGの使用
仮定9.PNGはres/drawable/my_として保存button_background.9.pngファイルは、この画像のXmlファイルを使用して以下のように定義されています.
<Button id="@+id/tiny" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:text="Tiny" android:textSize="8sp" android:background="@drawable/my_button_background"/>
<Button id="@+id/big" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:text="Biiiiiiig text!" android:textSize="30sp" android:background="@drawable/my_button_background"/>
その中でlayout_widthとlayout_heightはwrap_に設定されていますコンテンツが増えるにつれて、画像が自動的に