2013-07-19 26 views
10

Tôi có một bố cục đơn giản:Strange View.getHitRect() hành vi

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

<Button 
    android:id="@+id/button1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Button" /> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:onClick="animate" 
    android:text="animate" /> 

</LinearLayout> 

và Hoạt động của tôi Tôi in hit rect nút sau khi thay đổi vị trí của nó y:

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()); 
} 
} 

DỰ KIẾN OUTPUT

button1 hit rect: 0 0 116 72

button1 nhấn rect: 0 50 116 122

OUTPUT THỰC TẾ

button1 nhấn rect: 0 0 116 72

button1 hit rect: -58 14 58 86

Ai đó có thể giải thích kết quả này, tôi làm điều gì sai hoặc nó là một lỗi? Về cơ bản tôi đang sử dụng số getHitRect() trong tuỳ chỉnh ViewGroup để phát hiện người dùng con nào đã chạm vào. Có cách nào tốt hơn để có được đứa trẻ tại một điểm cụ thể, có thể là một chức năng như getChildAt(x, y)?

Thay vì setY(), tôi đã thử setTranslateY(). Tôi cũng đã sử dụng thư viện NineOldAndroid cũng như được xây dựng trong khung hoạt hình. Có thể thấy hành vi tương tự nếu tôi sử dụng findViewById(R.id.button1).animate().y(50) thay vì setY().

UPDATE:

tôi đã kết thúc bằng văn bản phương pháp hữu ích sử dụng thư viện nineoldandroid rằng đang làm việc tại:

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(); 
} 

Trả lời

8

getHitRect() đã có một lỗi và sẽ không áp dụng biến đổi đúng cách. Chúng tôi đã khắc phục lỗi này trong nội bộ và bản sửa lỗi sẽ được cung cấp trong bản phát hành công khai tiếp theo của Android.

+8

Kể từ khi câu trả lời này được thực hiện vào ngày 19 tháng 7 năm 2013, tôi giả định rằng bạn đã được đề cập đến Android 4.3 là "bản phát hành tiếp theo". Điều này có nghĩa là phương thức, getHitRect() không đáng tin cậy trên các phiên bản trước đó không? – Saket

+0

@ Saket Tôi muốn nói đó là một giả định hợp lý vì tôi có điện thoại ở đây bị kẹt trên 4.1.2 (Xperia S) và tọa độ y tôi nhận được không có ý nghĩa nhiều, tức là dưới cùng và trên cùng - bummer vì hàm rect đó đã cứu tôi rất nhiều đau đớn ... – AgentKnopf

+0

@Zainodis Xem cập nhật của OP. Phương pháp đó sẽ hoạt động tốt :) – Saket

2

Bạn có thể có được hit rect bằng cách này:

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

điều này không hoạt động như child.getLeft() trả về giá trị sai, giải pháp người hỏi đã viết bằng cách sử dụng tác phẩm chínoldandroid – 2cupsOfTech

1

Đây là một giải pháp mà không phụ thuộc vào NineOldAndroids.

Nếu bạn đi theo con đường mã cho đường dẫn mã NineOldAndroids bạn cuối cùng nhận được ở đây trên các thiết bị tổ ong bài: 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

Giải pháp tốt, tôi chỉ cần thêm hiệu chuẩn nhỏ 'rect.top - = dividerValue/2; rect.bottom + = dividerValue/2; 'như khi sử dụng dải phân cách rộng hơn giữa các mục trong chế độ xem danh sách, đã có rất nhiều lần phát hiện bị nhỡ. – LadyWoodi