Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange View.getHitRect() behaviour

I have a simple layout:

<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>

and in my Activity I am printing hit rect of button after changing its ylocation:

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

EXPECTED OUTPUT

button1 hit rect: 0 0 116 72

button1 hit rect: 0 50 116 122

ACTUAL OUTPUT

button1 hit rect: 0 0 116 72

button1 hit rect: -58 14 58 86

Can someone explain this output, am I doing something wrong or is it a bug? Basically I am using this getHitRect() in my custom ViewGroup to detect which child user has touched. Is there a better way to get the child at a particular point, may be a function like getChildAt(x, y)?

Instead of setY(), I have tried setTranslateY(). I also have used NineOldAndroid library as well as built in animation framework. Same behaviour can be seen if I use findViewById(R.id.button1).animate().y(50) instead of setY().

UPDATE:

I ended up writing utility method using nineoldandroid library that is working now:

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();
}
like image 828
M-WaJeEh Avatar asked Jul 19 '13 15:07

M-WaJeEh


1 Answers

getHitRect() had a bug and would not apply transforms properly. We fixed this bug internally and the fix will be made available in the next public release of Android.

like image 117
Romain Guy Avatar answered Oct 05 '22 02:10

Romain Guy