Показать и скрыть вид с помощью анимации слайдов вверх/вниз
У меня есть LinearLayout
, который я хочу показать или скрыть с помощью Animation
, который подталкивает макет вверх или вниз, когда я изменяю его видимость.
Я видел несколько образцов, но ни один из них не соответствовал моим потребностям.
Я создал два xml файла для анимации, но я не знаю, как их запускать, когда я изменяю видимость LinearLayout
.
Ответы
Ответ 1
С новым API анимации, который был представлен в Android 3.0 (Honeycomb), очень просто создать такие анимации.
Скользящий a View
вниз на расстояние:
view.animate().translationY(distance);
Затем вы можете вернуться в исходное положение View
следующим образом:
view.animate().translationY(0);
Вы также можете легко комбинировать несколько анимаций. Следующая анимация будет скользить по View
вниз по ее высоте и постепенно исчезать:
// Prepare the View for the animation
view.setVisibility(View.VISIBLE);
view.setAlpha(0.0f);
// Start the animation
view.animate()
.translationY(view.getHeight())
.alpha(1.0f)
.setListener(null);
Затем вы можете вытереть View
назад и вернуть его обратно в исходное положение. Мы также устанавливаем AnimatorListener
, поэтому после завершения анимации мы можем установить видимость View
на GONE
:
view.animate()
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});
Ответ 2
У меня были проблемы с пониманием применения принятого ответа. Мне нужно немного больше контекста. Теперь, когда я понял это, вот полный пример:
![enter image description here]()
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button myButton;
View myView;
boolean isUp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = findViewById(R.id.my_view);
myButton = findViewById(R.id.my_button);
// initialize as invisible (could also do in xml)
myView.setVisibility(View.INVISIBLE);
myButton.setText("Slide up");
isUp = false;
}
// slide the view from below itself to the current position
public void slideUp(View view){
view.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
view.getHeight(), // fromYDelta
0); // toYDelta
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
}
// slide the view from its current position to below itself
public void slideDown(View view){
TranslateAnimation animate = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
0, // fromYDelta
view.getHeight()); // toYDelta
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
}
public void onSlideViewButtonClick(View view) {
if (isUp) {
slideDown(myView);
myButton.setText("Slide up");
} else {
slideUp(myView);
myButton.setText("Slide down");
}
isUp = !isUp;
}
}
activity_mail.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.slideview.MainActivity">
<Button
android:id="@+id/my_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:onClick="onSlideViewButtonClick"
android:layout_width="150dp"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/my_view"
android:background="#a6e1aa"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="200dp">
</LinearLayout>
</RelativeLayout>
Заметки
- Спасибо этой статье за указание мне в правильном направлении. Это было более полезно, чем другие ответы на этой странице.
- Если вы хотите начать с просмотра на экране, не инициализируйте его как
INVISIBLE
. - Поскольку мы полностью анимируем его за пределы экрана, нет необходимости возвращать его в состояние "
INVISIBLE
. Если вы не полностью анимируете за пределами экрана, вы можете добавить альфа-анимацию и установить видимость с помощью AnimatorListenerAdapter
. - Документы по анимации собственности
Ответ 3
Самое простое решение: установите android:animateLayoutChanges="true"
на контейнер с вашими представлениями.
Чтобы включить его в какой-то контекст: если у вас есть макет, как показано ниже, все изменения видимости в представлениях в этом контейнере будут анимированы автоматически.
<LinearLayout android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
>
<Views_which_change_visibility>
</LinearLayout>
Подробнее об этом можно узнать на Анимация изменений макета - Разработчик Android
Ответ 4
Вы можете запустить правильный Animation
, когда видимость LinearLayout
изменится, создав новый подкласс LinearLayout
и переопределив setVisibility()
, чтобы запустить Animations
. Рассмотрим что-то вроде этого:
public class SimpleViewAnimator extends LinearLayout
{
private Animation inAnimation;
private Animation outAnimation;
public SimpleViewAnimator(Context context)
{
super(context);
}
public void setInAnimation(Animation inAnimation)
{
this.inAnimation = inAnimation;
}
public void setOutAnimation(Animation outAnimation)
{
this.outAnimation = outAnimation;
}
@Override
public void setVisibility(int visibility)
{
if (getVisibility() != visibility)
{
if (visibility == VISIBLE)
{
if (inAnimation != null) startAnimation(inAnimation);
}
else if ((visibility == INVISIBLE) || (visibility == GONE))
{
if (outAnimation != null) startAnimation(outAnimation);
}
}
super.setVisibility(visibility);
}
}
Ответ 5
if (filter_section.getVisibility() == View.GONE) {
filter_section.animate()
.translationY(filter_section.getHeight()).alpha(1.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
filter_section.setVisibility(View.VISIBLE);
filter_section.setAlpha(0.0f);
}
});
} else {
filter_section.animate()
.translationY(0).alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
filter_section.setVisibility(View.GONE);
}
});
}
Ответ 6
Котлин
Основываясь на ответе Suragch, вот элегантный способ использования расширения View:
fun View.slideUp(duration: Int = 500) {
visibility = View.VISIBLE
val animate = TranslateAnimation(0f, 0f, this.height.toFloat(), 0f)
animate.duration = duration.toLong()
animate.fillAfter = true
this.startAnimation(animate)
}
fun View.slideDown(duration: Int = 500) {
visibility = View.VISIBLE
val animate = TranslateAnimation(0f, 0f, 0f, this.height.toFloat())
animate.duration = duration.toLong()
animate.fillAfter = true
this.startAnimation(animate)
}
И тогда, где бы вы ни хотели его использовать, вам просто нужно myView.slideUp()
или myView.slideDown()
Ответ 7
Теперь анимация изменения видимости должна быть сделана через Transition API
, который доступен в пакете поддержки (androidx). Просто вызовите метод TransitionManager.beginDelayedTransition с переходом Слайд, затем измените видимость представления.
![enter image description here]()
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
private void toggle() {
View redLayout = findViewById(R.id.redLayout);
ViewGroup parent = findViewById(R.id.parent);
Transition transition = new Slide(Gravity.BOTTOM);
transition.setDuration(600);
transition.addTarget(R.id.redLayout);
TransitionManager.beginDelayedTransition(parent, transition);
redLayout.setVisibility(show ? View.VISIBLE : View.GONE);
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="play" />
<LinearLayout
android:id="@+id/redLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#5f00"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Проверьте этот ответ с помощью других стандартных и пользовательских примеров перехода.
Ответ 8
вы можете перемещать вверх и вниз любой вид или макет, используя следующий код в приложении для Android.
boolean isClicked=false;
LinearLayout mLayoutTab = (LinearLayout)findViewById(R.id.linearlayout);
if(isClicked){
isClicked = false;
mLayoutTab.animate()
.translationYBy(120)
.translationY(0)
.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}else{
isClicked = true;
mLayoutTab.animate()
.translationYBy(0)
.translationY(120)
.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
}
Ответ 9
Используйте этот класс:
public class ExpandCollapseExtention {
public static void expand(View view) {
view.setVisibility(View.VISIBLE);
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);
ValueAnimator mAnimator = slideAnimator(view, 0, view.getMeasuredHeight());
mAnimator.start();
}
public static void collapse(final View view) {
int finalHeight = view.getHeight();
ValueAnimator mAnimator = slideAnimator(view, finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationEnd(Animator animator) {
view.setVisibility(View.GONE);
}
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mAnimator.start();
}
private static ValueAnimator slideAnimator(final View v, int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
layoutParams.height = value;
v.setLayoutParams(layoutParams);
}
});
return animator;
}
}
Ответ 10
У меня был угловой футляр, в котором высота моего представления была zero
, поэтому...
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;
public final class AnimationUtils {
public static void slideDown(final View view) {
view.animate()
.translationY(view.getHeight())
.alpha(0.f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// superfluous restoration
view.setVisibility(View.GONE);
view.setAlpha(1.f);
view.setTranslationY(0.f);
}
});
}
public static void slideUp(final View view) {
view.setVisibility(View.VISIBLE);
view.setAlpha(0.f);
if (view.getHeight() > 0) {
slideUpNow(view);
} else {
// wait till height is measured
view.post(new Runnable() {
@Override
public void run() {
slideUpNow(view);
}
});
}
}
private static void slideUpNow(final View view) {
view.setTranslationY(view.getHeight());
view.animate()
.translationY(0)
.alpha(1.f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setVisibility(View.VISIBLE);
view.setAlpha(1.f);
}
});
}
}
Ответ 11
Вот мое решение. Просто получите ссылку на ваш взгляд и вызовите этот метод:
public static void animateViewFromBottomToTop(final View view){
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
final int TRANSLATION_Y = view.getHeight();
view.setTranslationY(TRANSLATION_Y);
view.setVisibility(View.GONE);
view.animate()
.translationYBy(-TRANSLATION_Y)
.setDuration(500)
.setStartDelay(200)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(final Animator animation) {
view.setVisibility(View.VISIBLE);
}
})
.start();
}
});
}
Не нужно ничего делать =)
Ответ 12
Сурачь ответь в котлин. Это сработало для меня.
class MainActivity : AppCompatActivity() {
var isUp: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var myView: View = findViewById(R.id.my_view)
var myButton: Button = findViewById(R.id.my_button)
//Initialize as invisible
myView.visibility = View.INVISIBLE
myButton.setText("Slide up")
isUp = false
}
fun View.slideUp(duration: Int = 500){
visibility = View.VISIBLE
val animate = TranslateAnimation(0f, 0f, this.height.toFloat(), 0f)
animate.duration = duration.toLong()
animate.fillAfter = true
this.startAnimation(animate)
}
fun View.slideDown(duration: Int = 500) {
visibility = View.VISIBLE
val animate = TranslateAnimation(0f, 0f, 0f, this.height.toFloat())
animate.duration = duration.toLong()
animate.fillAfter = true
this.startAnimation(animate)
}
fun onSlideViewButtonClick(view: View){
if(isUp){
my_view.slideDown()
my_button.setText("Slide Up")
}
else{
my_view.slideUp()
my_button.setText("Slide Down")
}
isUp = !isUp
}
}
Ответ 13
Вы можете использовать простые три строки кода, чтобы показать анимацию...
//getting the hiding view by animation
mbinding.butn.setOnClickListener {
val SlideOutLeft = AnimationUtils.loadAnimation(this, R.anim.slide_out_left)
simplelayout.visibility = View.INVISIBLE
simplelayout.startAnimation(SlideOutLeft)
val SlideInRight = AnimationUtils.loadAnimation(applicationContext, R.anim.slide_in_right)
animation1.visibility = View.VISIBLE
animation1.startAnimation(SlideInRight)
}
//again unhide the view animation
mbinding.buttn.setOnClickListener {
val SlideInLeft=AnimationUtils.loadAnimation(this,R.anim.slide_in_left)
//set the layout
simplelayout.visibility=View.VISIBLE
simplelayout.startAnimation(SlideInLeft)
val SlideOutRight=AnimationUtils.loadAnimation(this,R.anim.slide_out_right)
animation1.visibility=View.INVISIBLE
animation1.startAnimation(SlideOutRight)
}