Comportamiento extraño de View.getHitRect ()

Tengo un diseño sencillo:

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

Y en mi Actividad estoy imprimiendo golpear rect de botón después de cambiar su ubicació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()); } } 

RENDIMIENTO ESPERADO

Button1 hit rect: 0 0 116 72

Botón1 hit rect: 0 50 116 122

SALIDA REAL

Button1 hit rect: 0 0 116 72

Botón1 hit rect: -58 14 58 86

¿Puede alguien explicar esta salida, estoy haciendo algo mal o es un error? Básicamente estoy usando este getHitRect() en mi ViewGroup personalizado para detectar qué niño ha tocado. ¿Hay una mejor manera de conseguir que el niño en un punto en particular, puede ser una función como getChildAt(x, y) ?

En lugar de setY() , he intentado setTranslateY() . También he utilizado la biblioteca de NineOldAndroid así como construido en el marco de la animación. El mismo comportamiento se puede ver si uso findViewById(R.id.button1).animate().y(50) lugar de setY() .

ACTUALIZAR:

Terminé escribiendo método de utilidad usando nineoldandroid biblioteca que está trabajando ahora:

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

getHitRect() tenía un error y no aplicaría correctamente las transformaciones. Hemos solucionado este error internamente y la corrección estará disponible en la próxima versión pública de Android.

Usted puede conseguir el rect de esta manera:

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

Aquí hay una solución que no depende de NineOldAndroids.

Si sigue la ruta del código para NineOldAndroids ruta de código que finalmente llegar aquí en los dispositivos de nido de abeja de post: 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(); } 
  • Android - Animar el diálogo emergente con efecto de rebote
  • Animación de carga de línea Android
  • Animación individual - vistas múltiples
  • Cómo hacer que el efecto de cambio de página en Android?
  • IOS como sobre el efecto de desplazamiento en Android
  • Usando la lista de animación de android
  • CardView muestra artefactos cuando RotationY> 60
  • Cómo agregar animación a una vista de texto en android
  • Animar zoom en el centro de una imagen en Android con xml
  • Android 2.3: Crecer / reducir el error de animación?
  • Ampliar la animación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.