2012-08-15 45 views
0

給定一個有多個小部件的活動,我想在拖動操作過程中提供一些額外的視覺反饋。我有拖動部分工作,默認陰影。另外,由於每個小部件處理onDrag,我想在小部件區域外繪製一個位圖指示器。我想出瞭如何繪製小部件的區域,但是(如預期的那樣)它將任何超出邊界的東西剪掉。在拖動過程中,在小部件區域外繪製

我的第一個想法是使用SurfaceView。看來,我必須根據父母創建一個。作爲一個新手,這對我來說有很多工作要弄清楚,所以我希望有人能夠首先驗證這種方法。

另一個想法是直接在父級的畫布上繪製(如果我能弄清楚如何獲取畫布)。我認爲這樣做的缺點是必須「清除」標記需要移動時所畫的內容。可能會導致過度重繪?

還有其他方法嗎?我是否會像父母的畫布一樣,在SurfaceView中使用相同的「擦除」問題?

回答

0

我認爲可以遞歸地使用getParent,直到找到代表要繪製空間的父代。我沒有嘗試這個,因爲它變得非常依賴於您使用的佈局。如果您更改佈局,則可能需要更改代碼。

取而代之的是,在佈局的頂層,我選擇了FrameLayout,並將所需的佈局作爲其子元素。作爲第二個孩子,我提出了一個具有透明背景的「空白」視圖。 FrameLayout將在彼此之上顯示所有的孩子。所以我的「空白」視圖顯示在我想要的佈局之上。例如:

​​

該代碼非常直接,除了位置計算。爲了獨立佈局,我發現最好將所有東西都轉換成屏幕座標;否則getTop(),getLeft()將返回相對於直接父級的值,這可能與您計劃繪製的空間不同。以下是我在啓動繪圖的小部件中所做的操作。首先,你需要這個在你的活動:

private ActivityView mActivityView ; 

@Override 
public void onCreate (Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 

    // get "activity" view - this covers the whole activity space 
    mActivityView = (ActivityView)findViewById (R.id.activity_view); 

    // find the widget and give it the activity view 
    MyWidget widget = (MyWidget)findViewById (R.id.my_widget); 
    widget.setActivityView (mActivityView); 
} 

你還需要這在widget - 發起繪圖的一個:

public void setActivityView (ActivityView v) 
{ 
    mActivityView = v; 
} 

public void drawThing (float touchX, float touchY) 
// touchX, touchY - location where user is touching, relative to "this" widget. 
{ 
    int[] locScreen = new int[2]; // x,y 
    getLocationOnScreen (locScreen); 
    int xScreen = locScreen[0] + touchX; 
    int yScreen = locScreen[1] + touchY; 
    mActivityView.drawThing (xScreen, yScreen); 
} 

最後,你需要做的在ActivityView中繪圖

private int mXThing; 
private int mYThing; 

@Override 
protected void onDraw (Canvas canvas) 
{ 
    super.onDraw (canvas); 
    ... draw the "thing" using mXThing, mYThing ... 
} 

void drawThing (int xScreen, int yScreen) 
{ 
    // convert to view coords. 
    int[] loc = new int[2]; // x,y 
    getLocationOnScreen (loc); 
    mXThing = xScreen - loc[0]; 
    mYThing = yScreen - loc[1]; 
    invalidate(); 
} 

我想有其他方法可以做到這一點,也許更好。如果有人有任何建議,請隨時發表評論。