2013-07-19 31 views
10

我有一個簡單的佈局:奇怪View.getHitRect()行爲

​​3210

,並在我的活動,我改變了y位置後打印按鈕的命中RECT:

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

public void animate(View view) { 
    printHitRect(); 
    findViewById(R.id.button1).setY(50); 
    printHitRect(); 
} 
private void printHitRect() { 
    Rect rect = new Rect(); 
    findViewById(R.id.button1).getHitRect(rect); 
    Log.d(">>button1 hit rect", rect.flattenToString()); 
} 
} 

預期的輸出

button1的命中RECT:0 0 116 72

button1的擊中RECT:0 50 116 122

實際輸出

button1的擊中RECT: 0 0 116 72

Button1的命中RECT:-58 14 58 86

有人能解釋這個輸出,我是不是做錯了什麼或者是一個錯誤嗎?基本上我在我的自定義ViewGroup中使用這個getHitRect()來檢測哪個孩子用戶已經觸摸。有沒有更好的方法讓孩子在某個特定點上,可能是getChildAt(x, y)這樣的功能?

而不是setY(),我試過setTranslateY()。我也使用NineOldAndroid庫以及內置的動畫框架。如果我使用findViewById(R.id.button1).animate().y(50)而不是setY(),則可以看到相同的行爲。

UPDATE:

最後我用的是現在工作nineoldandroid庫寫入工具方法:

private static void getHitRect(View v, Rect rect) { 
    rect.left = (int) com.nineoldandroids.view.ViewHelper.getX(v); 
    rect.top = (int) com.nineoldandroids.view.ViewHelper.getY(v); 
    rect.right = rect.left + v.getWidth(); 
    rect.bottom = rect.top + v.getHeight(); 
} 

回答

8

getHitRect()有一個bug,並且不會正確地應用轉換。我們在內部修復了這個錯誤,並且修復程序將在下一個公開發布的Android中提供。

+8

因爲這個答案在2013年7月19日提出,我假設你指到Android 4.3作爲「下一個版本」。這是否意味着方法,getHitRect()在它之前的版本上不可靠? – Saket

+0

@Saket我會說這是一個公平的假設,因爲我在這裏有一個電話卡在4.1.2(Xperia S)上,並且我得到的y座標沒有太大意義,即底部和頂部 - 無賴因爲該矩形函數會爲我節省很多痛苦... – AgentKnopf

+0

@Zainodis查看OP的更新。該方法應該工作得很好:) – Saket

2

可以得到擊中RECT通過這種方式:

public Rect getHitRect(View child){ 
    Rect frame = new Rect(); 
    frame.left = child.getLeft(); 
    frame.right = child.getRight(); 
    frame.top = child.getTop(); 
    frame.bottom = child.getBottom(); 
    return frame; 
} 
+0

這不起作用child.getLeft()返回錯誤的值,提問者使用nineoldandroid寫的解決方案的工作 – 2cupsOfTech

1

這裏是一個不依賴於NineOldAndroids的解決方案。

如果按照NineOldAndroids代碼路徑的代碼路徑你最終在這裏交的蜂窩設備:Github

private static void getHitRect(View v, Rect rect) { 
    rect.left = (int) (v.getLeft() + v.getTranslationX()); 
    rect.top = (int) (v.getTop() + v.getTranslationY()); 
    rect.right = rect.left + v.getWidth(); 
    rect.bottom = rect.top + v.getHeight(); 
} 
+0

好的解決方案,我只需要添加小的校準'rect.top - = dividerValue/2; rect.bottom + = dividerValue/2;'當在listview中的項目之間使用更寬的分隔符時,有很多錯過的觸摸檢測。 – LadyWoodi