Androidの中でスムーズにキャンバスをスクロール
-
21-09-2019 - |
質問
私は、Androidに新たなんだ。
私は、ビューのOnDraw(キャンバスキャンバス)メソッド内のキャンバス上にビットマップ、線や図形を描画しています。私は、ユーザのドラッグに応じてスムーズスクロールを実装する方法についてのヘルプを探しています。私は検索が、これで私を助けるために任意のチュートリアルを発見していない。
キャンバスのための参照は、キャンバスがビットマップ(と言う、bmpBufferと呼ばれる)から構成されている場合は、キャンバスに描かれたものもbmpBuffer上に描画されていることを言っているようです。おそらく一度に数ピクセル分シフトキャンバスに戻ってそれをコピー...スクロールを実装するためにbmpBufferを使用することは可能でしょうか?私は戻って数ピクセル分シフトキャンバスにbmpBufferを描画するためにCanvas.drawBitmapを使用する場合でも、bmpBufferが破損している可能性がないのだろうか?おそらく、それゆえ、私はbmpBuffer2にbmpBufferをコピーする必要があり、その後戻ってキャンバスにbmpBuffer2を描きます。
より簡単なアプローチは、線を描画することで、形状は、等ストレートバッファビットマップには、次に、これまでのところ、私は様々な方法見ることができるようにキャンバス上に(ずらして)、そのバッファを描くけれども:drawLine()は、行うdrawShape()などでは、唯一のキャンバスに...ビットマップを描画するために使用できません。
私は2つのキャンバスを持ってもらえますか?一つは、バッファのビットマップから構成等、線、図形をプロットするために単に使用されると、バッファビットマップビューで表示するための他のキャンバスに描画されることになるでしょうか?
私はどんなアドバイスを歓迎する必要があります!
ここ(および他のウェブサイトで)同様の質問に対する回答は、「ブリッティング」を参照してください。私は、概念を理解しますがAndroidのドキュメントの「ブリット」または「ビットブリット」については何も見つけることができません。 Canvas.drawBitmapとBitmap.Copy Androidの同等物はありますか?
解決
私は、あまりにもこの問題を抱えていた。
私はこのように描画ます:
Canvas BigCanvas = new Canvas();
Bitmap BigBitmap = new Bitmap(width,height);
int ScrollPosX , ScrollPosY // (calculate these with the onScrollEvent handler)
void onCreate()
{
BigCanvas.SetBitmap(BigBitmap);
}
onDraw(Canvas TargetCanvas)
{
// do drawing stuff
// ie. BigCanvas.Draw.... line/bitmap/anything
//draw to the screen with the scrolloffset
//drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
TargetCanvas.DrawBitmap(BigBitmap(new Rect(ScrollPosX,ScrollPosY,ScrollPosX + BigBitmap.getWidth(),ScrollPosY + BigBitmap.getHeight(),new Rect(0,0,ScreenWidth,ScreenHeight),null);
}
は滑らかあなたは(すなわち、第1スクロールポイントと10日)にスクロールした後、いくつかのポイントを取る方法のいくつかの並べ替えをする必要があると思いスクロールするため、それを徐々に作るループごとにその数によるものと、スクロールを引きます遅く(ScrollAmount - ターン - フリクション)。
私は、これはいくつかのより多くの洞察力を与える願っています。
他のヒント
私は答えを見つけたようです。私は新しいdoDrawing()メソッドで(onDraw()に以前あった)描画コードの大部分を入れています。この方法は、(完全な描画を保持するのに十分な大きさ)画面よりも大きな新しいビットマップを作成することによって開始します。その後、詳細な描画を行う上の第二のキャンバスを作成します:
BufferBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
Canvas BufferCanvas = new Canvas(BufferBitmap);
doDrawing()メソッドの残りはBufferCanvasの詳細図で巻き取られる。
次のように全体onDraw()メソッドは、現在読み出し
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(BufferBitmap, (float) -posX, (float) -posY, null);
}
位置変数、POSXとPOSYは、アプリケーションののonCreate()メソッドで0に初期化されます。アプリケーションはPOSXと花束をインクリメントするOnScroll通知に返さdistanceXとdistanceY引数をOnGestureListenerを実装し、使用します。
これはおよそすべてのことは、スムーズスクロールを実装するために必要だと思われます。それとも私が何かを過剰に探しています!
ヴィクトルへの返信の継続...
実際には、状況はより複雑です。 doDrawingプロセスは、(私の遅い古いHTCヒーロー電話で2-3秒を取って)かなり遅いので、私はそれが起こっていた利用者に助言するために、その理由を示すためにトーストメッセージをポップアップ表示することが望ましいことが判明しました。これを行うには明白な方法は、わずか2行を含む新しいメソッドを作成することでした。
public void redrawBuffer(String strReason) {
Toaster.Toast(strReason, "Short");`
doDrawing();
}
、代わりにdoDrawing()の私のプログラムでは、他の場所からこのメソッドを呼び出すます。
は、しかし、私はトースターはどちらか登場していないか、それを読み取ることができなかったほど簡単にアップ点滅しないことがわかりました。私の問題を回避するには、トーストを表示してdoDrawing()を呼び出すの間で200ミリ秒間スリープ状態にプログラムを強制的にハンドラをチェックする時間を使用することでした。これは少し私はこれを感じて再描画の開始を遅らせるが、ユーザーは何が起こっているか知っているので、プログラムの使いやすさの面で支払う価値価格です。 reDrawBufferは()今読みます:
public void redrawBuffer(String strReason) {
Toaster.Toast(strReason, "Short");
mTimeCheckHandler.sleep(200);
}`
と(私のViewクラス内でネストされた)ハンドラコードがあります:
private timeCheckHandler mTimeCheckHandler = new timeCheckHandler();
class timeCheckHandler extends Handler {
@Override
public void handleMessage(Message msg) {
doDrawing();
}
public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
}`
の活動を再開させるための必要はありません! 「アンドロイド:configChanges」(彼の1月17日10「答え」とパーprepbggの1月27日10回答)むしろビットマップをリサイクルし、活動が再読み込み持つのオーバーヘッドを被るよりも、あなたが置くことによってロードされたアプリケーションを避けることができます属性は、以下に示します、アプリのためのAndroidManifest.xmlファイルの「活動」要素インチこのアプリは、向きの変更を処理するシステムに指示し、それはアプリを再起動する必要はありません。
<activity android:name=".ANote"
android:label="@string/app_name"
android:configChanges="orientation|screenLayout">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
この方法はorienationが変更されたときに通知を取得するために使用することができます:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
prt("onConfigurationChanged: "+newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
prt(" PORTRAIT");
} else {
prt(" LANDSCAPE");
}
} // end of onConfigurationChanged
prepbgg:。私はcanvas.drawBitmapがビットマップに描画するが、キャンバスにオンビットマップを描画していないため、コードが動作するとは思わない。
私が間違っているなら、私を修正してください!