在Android的流畅滚动画布
-
21-09-2019 - |
题
我新的机器人。
我绘制位图,线条和形状到我的视图的的OnDraw(帆布帆布)方法内的画布。我寻求帮助,如何响应用户拖拽实现平滑滚动。我已经搜查,但没有发现任何教程,以帮助我。
有画布参考似乎是说,如果一个帆布由位图构造(称为bmpBuffer,说),然后在画布上绘制什么也被拉上bmpBuffer。是否有可能使用bmpBuffer来实现滚动...也许复制回它在同一时间几个像素移位画布?但是,如果使用Canvas.drawBitmap画bmpBuffer回到画布几个像素移位,不会bmpBuffer被破坏?也许,因此,我应该复制bmpBuffer到bmpBuffer2然后绘制bmpBuffer2回画布。
一个更简单的方法是绘制线条,形状等直到缓冲区位图然后绘制该缓冲液(有移位)到Canvas但到目前为止我可以看到的各种方法:的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);
}
平滑滚动你需要做某种方法是滚动(即第一滚动点和10日)后,需要几个点,通过减去这个数字的和滚动在每个循环,使得它逐渐慢(ScrollAmount - 打开 - 摩擦)。
我希望这给出了一些更深入的了解。
其他提示
我似乎已经找到了答案。我已经把绘图代码的体积(这是以前在的onDraw())是一个新doDrawing()方法。该方法通过创建一个新的位图比屏幕(大到足以容纳一个完整的图纸)放大开始。然后,它创建在其上做详细的图纸的第二画布:
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,在0在应用程序的onCreate()方法初始化。的应用程序实现OnGestureListener和使用在OnScroll通知递增POSX和POSY返回distanceX和distanceY参数。
这似乎是所有的,以实现平滑滚动需要真实。还是我在看的东西!?
回复延续到维克托...
在事实上,情况更为复杂。因为doDrawing过程是相当慢(我的慢的老的HTC Hero手机服用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);
}
}`
没有必要的活动重新启动! (每prepbgg的10年1月27日答复他10年1月17日“答案”),而不是回收的位图和承担具有活性重载的开销,你可以避免通过将加载的应用程序的Android版本:configChanges“如下图所示的属性,在该应用的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不画成位图,但画上的位图画布
纠正我,如果我错了!