2011-07-24 110 views
2

我開始研究Android SDK中的示例Finger Paint應用程序以更熟悉圖形。最近我一直在努力實現撤銷/重做,並且我嘗試過每一種嘗試都遇到過的路障。我發現了一些關於這個問題的線索,但是沒有人讓我知道這些問題。這裏是我的主2項試驗:Android工具在繪圖應用程序中取消堆棧

策略1:

保存路徑(或畫布)的堆棧和撤消清除屏幕並重繪除了最後一個每個路徑(或恢復最近的帆布) 。

這裏的問題可能很簡單,但我不能讓視圖重繪任何東西。如何繪製保存的路徑(或恢復保存的畫布)?

策略2:

保存位圖的使用getDrawingCache()每個觸摸之後的堆棧。撤消時,將最後一個位圖放回。

保存必須通過post()從runnable運行,所以它在onDraw()完成後執行(postvalid將它添加到invalidate()後的系統消息行)。問題是,當從可運行的程序運行時,getDrawingCache()總是返回繪畫的初始版本,就像在第一個版本之後看不到任何更改一樣。

爲什麼getDrawingCache()從runnable中調用時,看不到視圖的當前狀態?

我一直在與此戰鬥。謝謝。

case MotionEvent.ACTION_UP: 
touch_up(); 
invalidate(); 
Runnable r = new Runnable(){ 
    @Override 
    public void run() { 
    myView.storeView(); 
    } 
}; 
myView.post(r); 
} 

public void storeView(){ 
    historyCount++; 
    if(historyCount > historySize) historyCount = 6; //We don't want more than 6       
    history.add(Bitmap.createBitmap(myView.getDrawingCache()),historyCount); 
} 

回答

4

對於策略1,您需要定義一個表示需要渲染圖形的一部分的所有信息的數據結構。因此,例如,如果通過跟蹤用戶的觸摸位置來繪製圖形的一部分,請定義一個數據結構,該數據結構由當前顏色,圖形形狀以及由一個用戶手勢生成的座標的ArrayList組成。當您按照用戶的觸摸,繪製到屏幕上時,還會將觸摸座標附加到當前手勢的ArrayList。當觸摸結束時,將數據結構推入撤消堆棧,並等待下一個用戶手勢創建下一個結構實例並開始填充它。

如果您有各種手勢(填充,徒手畫線,直線等),您可以爲每個手勢都有單獨的結構。它們都可以從一個抽象類繼承,所以它們都可以進入堆棧。

第二種策略讓我感到恐懼難耐。我想我們必須看到你的代碼才能理解爲什麼它不能按預期工作。

+0

就內存而言,第二種策略肯定是一種壞的方法。雖然這可能很快,但你很快就會打出OutOfMemory。 –

+0

我添加了第二個策略的主要代碼,沒有太多。我認識到內存問題,我非常保守地限制了堆棧的深度。關於數據結構,路徑中是否包含所有的座標和必要的信息(除了繪畫)?我有路徑的歷史,我遇到的問題是重繪它們。 – jarvisteve

+0

您是否爲myView啓用緩存(通過調用'setDrawingCacheEnabled(true)')? –

相關問題