Entonces, estaba buscando la respuesta a esto para mi proyecto Xamarin, pero supongo que también debería aplicarse a Java. La realización que tuve fue que LinearLayout siendo animado SIEMPRE tenía la misma posición (digamos, estaba en x = 100, y == 100) y tus animaciones deberían ser RELATIVAS a esta posición. El ObjectAnimator era definitivamente el camino a seguir, y aquí está mi solución:
En primer lugar, un diseño simple con un poco de texto en la parte superior y una LinearLayout debajo de lo que es el objetivo de la animación ....
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:p1="http://schemas.android.com/apk/res/android"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:id="@+id/frameLayout1">
<TextView
p1:text="Some text at the top"
p1:textAppearance="?android:attr/textAppearanceLarge"
p1:id="@+id/txtSomeTextAtTheTop"
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:layout_gravity="center_horizontal" />
<LinearLayout
p1:orientation="vertical"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:id="@+id/linMySlider"
p1:layout_gravity="center_horizontal|bottom">
<LinearLayout
p1:orientation="horizontal"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="@+id/linAlwaysDisplay"
p1:layout_marginBottom="10px">
<TextView
p1:text="ALWAYS ON DISPLAY"
p1:textAppearance="?android:attr/textAppearanceLarge"
p1:id="@+id/txtAlwaysDisplay"
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:layout_gravity="center_horizontal" />
</LinearLayout>
<LinearLayout
p1:orientation="horizontal"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="@+id/linToHideLineOne">
<TextView
p1:text="To Hide Line One"
p1:textAppearance="?android:attr/textAppearanceLarge"
p1:id="@+id/txtHideLineOne"
p1:layout_width="wrap_content"
p1:layout_height="wrap_content"
p1:layout_gravity="center_horizontal" />
</LinearLayout>
<LinearLayout
p1:orientation="horizontal"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="wrap_content"
p1:id="@+id/linHideLineTwo">
<TextView
p1:text="To Hide Line Two"
p1:textAppearance="?android:attr/textAppearanceLarge"
p1:id="@+id/txtHideLineTwo"
p1:layout_width="wrap_content"
p1:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
Mi actividad y, a continuación, se parecía a lo siguiente:
using System;
using Android.App;
using Android.OS;
using Android.Views;
using Android.Widget;
using Android.Animation;
using Android.Views.Animations;
using Android.Util;
namespace MyNamespace
{
[Activity(Label = "testActivity")]
public class testActivity : Activity
{
public static string TAG = "M:testActivity";
//by default we want the slider to be closed, which is why
// _sliderOpen has been set to true and we animate it into position when
//the window gets first focus
private bool _sliderOpen = true;
private ViewGroup _linMySlider;
private LinearLayout _linAlwaysDisplays;
private int _distanceToTravel;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.testLayout);
_linMySlider = FindViewById<ViewGroup>(Resource.Id.linMySlider);
_linAlwaysDisplays = FindViewById<LinearLayout>(Resource.Id.linAlwaysDisplay);
TextView alwaysDisplayText = FindViewById<TextView>(Resource.Id.txtAlwaysDisplay);
alwaysDisplayText.Click += AlwaysDisplayText_Click;
}
private void AlwaysDisplayText_Click(object sender, EventArgs e)
{
DoAnimation(500);
}
public override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
if (hasFocus)
{
if (_sliderOpen)
{
//we store this one time as it remains constant throught our sliding animations
_distanceToTravel = _linMySlider.Height - _linAlwaysDisplays.Height;
DoAnimation(1);
}
}
}
private void DoAnimation(long duration)
{
ObjectAnimator slideMe = null;
try
{
switch (_sliderOpen)
{
case true:
slideMe = ObjectAnimator.OfFloat(_linMySlider, "translationY", 0, _distanceToTravel);
_sliderOpen = false;
break;
case false:
slideMe = ObjectAnimator.OfFloat(_linMySlider, "translationY", _distanceToTravel, 0);
_sliderOpen = true;
break;
}
slideMe.SetInterpolator(new OvershootInterpolator());
slideMe.SetDuration(duration);
slideMe.Start();
}
catch (Exception e)
{
Log.Error(TAG, "DoAnimation: Exception - " + e.Message);
}
}
}
}
El punto más importante a destacar es que la _distanceToTravel (en este caso la traducción en el eje Y) es relativa a la propiedad superior de la LinearLayout estamos animación. Supongamos que cada uno de los LinearLayouts que contienen el texto (SIEMPRE EN LA PANTALLA, Para Ocultar la Línea Uno, Para Ocultar la Línea Dos) tiene una altura de 20 (lo que hace que la altura total sea 60). El control deslizante, por ejemplo, tiene una propiedad Superior de 2100. Como se encuentra en la parte inferior, para ocultar las dos líneas, significa que tenemos que mover LinealLayout linMySlider 40 veces para ocultar las dos líneas, dejando solo la primera visible. Si piensas que LinearLayout es SIEMPRE 2100, entonces tiene sentido que en el deslizamiento hacia abajo le agreguemos 40 (bueno, no nosotros, el Animator lo hace por nosotros), evidente en la primera línea OfFloat, donde la posición inicial Y es 0 (es decir, 0 en relación con 2100, por lo que es igual a 2100) y su posición Y final es _distanceToTravel (que es 40, pero de nuevo relativa, por lo que equivale, de hecho, a 2140). En la dirección opuesta comenzamos con _distanceToTravel para Y (de nuevo 40, pero de hecho 2140) y terminamos en 0 (lo has adivinado 0 lejos de 2100 y, por lo tanto, 2100).
Espero que todo esto tenga sentido, me tomó un poco de tiempo para que el centavo caiga, pero funciona muy bien sin parpadeo y sin reinicio a la posición original (que siempre tuvo jajaja). Esperemos que lo mismo se aplique al código de Java como lo hace en este ejemplo de C#.
Esto funcionó para mí, muchas gracias. –
Mi placer, Nick. – Soham
¡Gracias, esto funciona como se describe, se desperdicia tiempo antes de encontrar su publicación! – radhoo