Android додає прості анімації під час налаштування (view.Gone)


237

Я створив простий макет. Я закінчив дизайн без анімації, але тепер я хочу додати анімацію, коли подія натискання тексту переглядає, і я не знаю, як її використовувати. Чи добре виглядав мій xml дизайн чи ні? Будь-які пропозиції будуть вдячні.

Мій XML

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16" >

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#00DDA0"
    android:layout_weight="3" >
</LinearLayout>
 <TextView
        android:id="@+id/Information1"
        android:layout_width="match_parent"
        android:layout_height="1dp" 
        android:text="Child Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>

 <LinearLayout
     android:id="@+id/layout1"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="8.5"
     android:background="#BBBBBB"
     android:orientation="vertical" >

     <TextView
         android:id="@+id/textView1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
 </LinearLayout>

  <TextView
        android:id="@+id/Information2"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Parent Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
  <LinearLayout 
          android:id="@+id/layout2"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
   <TextView
        android:id="@+id/Information3"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Siblings" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
   <LinearLayout 
          android:id="@+id/layout3"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView3"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
    <TextView
        android:id="@+id/Information4"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Teacher Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
    <LinearLayout 
          android:id="@+id/layout4"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView4"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
     <TextView
        android:id="@+id/Information5"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Grade Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
     <LinearLayout 
          android:id="@+id/layout5"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
      <TextView
        android:id="@+id/Information6"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Health Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
      <LinearLayout 
          android:id="@+id/layout6"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
    <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" 
         android:layout_weight="8.5" />
      </LinearLayout>

</LinearLayout>

Моя ява

public class Certify_Info extends Activity {

    private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
    private static LinearLayout l1,l2,l3,l4,l5,l6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_certify__info);

        tv1=(TextView) findViewById(R.id.Information1);
        tv2=(TextView) findViewById(R.id.Information2);
        tv3=(TextView) findViewById(R.id.Information3);
        tv4=(TextView) findViewById(R.id.Information4);
        tv5=(TextView) findViewById(R.id.Information5);
        tv6=(TextView) findViewById(R.id.Information6); 

        l1=(LinearLayout) findViewById(R.id.layout1);
        l2=(LinearLayout) findViewById(R.id.layout2);
        l3=(LinearLayout) findViewById(R.id.layout3);
        l4=(LinearLayout) findViewById(R.id.layout4);
        l5=(LinearLayout) findViewById(R.id.layout5);
        l6=(LinearLayout) findViewById(R.id.layout6); 

        l2.setVisibility(View.GONE);
        l3.setVisibility(View.GONE); 
        l4.setVisibility(View.GONE); 
        l5.setVisibility(View.GONE);
        l6.setVisibility(View.GONE);

        tv1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l1.setVisibility(View.VISIBLE);
            }
        });
        tv2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l2.setVisibility(View.VISIBLE);
            }
        });
        tv3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l3.setVisibility(View.VISIBLE);

            }
        });
        tv4.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l4.setVisibility(View.VISIBLE); 
            }
        });
        tv5.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l6.setVisibility(View.GONE);
                l5.setVisibility(View.VISIBLE); 
            }
        });
        tv6.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.VISIBLE);
            }
        });

    }
}

Відповіді:


706

Ви можете зробити дві речі, щоб додати анімацію, спочатку ви можете дозволити вам змінити макет андроїдного андроїда для вас. Таким чином, кожен раз, коли ви щось зміните в макеті, як-от зміна видимості перегляду чи перегляду позицій андроїд, автоматично створюватимуть анімацію зникання / переходу. Щоб використовувати цей набір

android:animateLayoutChanges="true"

на кореневому вузлі у вашому макеті.

Вашим другим варіантом буде ручне додавання анімації. Для цього я пропоную вам використовувати новий анімаційний API, представлений в Android 3.0 (Honeycomb). Я можу навести кілька прикладів:

Це згасає View:

view.animate().alpha(0.0f);

Це зникає назад у:

view.animate().alpha(1.0f);

Це рухається Viewвниз на його висоту:

view.animate().translationY(view.getHeight());

Це повертає Viewпочаткове положення після того, як воно було переміщено кудись інше:

view.animate().translationY(0);

Ви також setDuration()можете встановити тривалість анімації. Наприклад, це згасає Viewпротягом 2 секунд:

view.animate().alpha(0.0f).setDuration(2000);

І ви можете комбінувати скільки завгодно мультиплікацій, наприклад, це вимикає і одночасно Viewпереміщує його вниз протягом 0,3 секунд:

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300);

Ви також можете призначити слухача анімації та реагувати на всілякі події. Як і коли починається анімація, коли вона закінчується або повторюється і т. Д. Використовуючи абстрактний клас, AnimatorListenerAdapterвам не доведеться реалізовувати AnimatorListenerвідразу всі зворотні виклики, а лише ті, що вам потрібні. Це робить код більш читабельним. Наприклад, наступний код згасає, Viewрухає його вниз на висоту протягом 0,3 секунд (300 мілісекунд), і коли анімація виконана, її видимість встановлюється View.GONE.

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300)
        .setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                view.setVisibility(View.GONE);
            }
        });

6
@Natix Я б не назвав це надлишковим викликом. Не вносьте в поверхневі зміни нічого поганого.
— Xaver Kapeller

5
Це добре, але зворотне працює не правильно, чому? view.setVisibility (View.VISIBLE); З альфа (1.0f), з'являться зі 100 підкладками зверху ...
— доставлять

15
Потрібно очистити анімацію перед встановленою видимістю >> view.clearAnimation(); view.setVisibility(View.GONE);інакше макет залишиться непомітним і не зникне.
— Ефтехарі

2
@Eftekhari Вони зовсім не є ресурсомісткими. І якщо у вас є сучасна версія Android, але ви все ще відчуваєте відставання, ніж у вас, напевно, старіший телефон з низькою пам’яттю або поганий графічний чіп. І я не кажу про нову бібліотеку. Аніматори - рідні. Вони є частиною Android Framework. Вони були випущені 5 років тому, і сьогодні 97,9% всіх пристроїв підтримують їх. Немає ніяких причин не використовувати Animators або принаймні, ViewCompat.animate()що є частиною бібліотеки підтримки та використовує Animators на новіших версіях та Перегляд анімацій на Android 3.0 та нижче.
— Xaver Kapeller

1
Але коли 97,9% усіх пристроїв є Android 4.0 і вище, не залишається багато корисного шафу ViewCompat.animate().
— Xaver Kapeller

70

Найпростіший спосіб анімувати Visibilityзміни - це використання, Transition APIяке доступне у пакеті підтримки (androidx). Просто викличте TransitionManager.beginDelayedTransitionметод, а потім змініть видимість подання. Є кілька переходів по замовчуванням , як Fade, Slide.

import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;

private void toggle() {
    Transition transition = new Fade();
    transition.setDuration(600);
    transition.addTarget(R.id.image);

    TransitionManager.beginDelayedTransition(parent, transition);
    image.setVisibility(show ? View.VISIBLE : View.GONE);
}

Де parentє батько ViewGroupанімованого перегляду. Результат:

введіть тут опис зображення

Ось результат з Slideпереходом:

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

введіть тут опис зображення

Написати користувацький перехід легко, якщо вам потрібно щось інше. Ось приклад, з CircularRevealTransitionяким я писав в іншій відповіді . Він показує і приховує перегляд за допомогою анімації CircularReveal.

Transition transition = new CircularRevealTransition();

введіть тут опис зображення

android:animateLayoutChanges="true"варіант робить те ж саме, він просто використовує AutoTransition як перехід.


@TouhidulIslam ні. Цей клас доступний в androidx-пакеті. Все сумісно назад
— ашакіров

2
Що з розширенням / згортанням групи перегляду?
— TheRealChx101

Ви можете зробити кілька beginDelayedTransitionс?
— Jeongbebs

26

Перевірте це посилання. Що дозволить анімації, такі як анімація L2R, R2L, T2B, B2T.

Цей код показує анімацію зліва направо

TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);

якщо ви хочете зробити це з R2L, тоді використовуйте

TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);

зверху вниз як

TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());

і навпаки ..


8
Це витісняє вид з початкового положення.
— Рельм

24

Спробуйте додати цей рядок до батьківського макета xml

 android:animateLayoutChanges="true"

Ваш макет буде виглядати приблизно так

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16">

    .......other code here

    </LinearLayout>

це працювало для мене. У моїй установці використовується макет обмежень у вигляді подання кореня. Коли перегляд встановлено на View.VISIBLE, анімація відображається
— EdgeDev

дуже просте і елегантне рішення
— Naveed Ahmad

11

На основі відповіді @Xaver Kapeller я придумав спосіб створення анімації прокрутки, коли на екрані з’являються нові види (а також анімація, щоб їх приховати).

Це йде з цього стану:

  • Кнопка
  • Остання кнопка

до

  • Кнопка
  • Кнопка 1
  • Кнопка 2
  • Кнопка 3
  • Кнопка 4
  • Остання кнопка

і навпаки.

Отже, коли користувач натисне на першу кнопку, елементи "Кнопка 1", "Кнопка 2", "Кнопка 3" та "Кнопка 4" з'являться з використанням анімації зникати, і елемент "Остання кнопка" буде рухатися вниз до кінця. Також буде змінюватися висота макета, що дозволить правильно використовувати подання прокрутки.

Це код для відображення елементів з анімацією:

private void showElements() {
    // Precondition
    if (areElementsVisible()) {
        Log.w(TAG, "The view is already visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    // the alpha as 0.0. Otherwise the animation won't be shown
    mHiddenLinearLayout.setVisibility(View.VISIBLE);
    mHiddenLinearLayout.setAlpha(0.0f);
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    updateShowElementsButton();
                    mHiddenLinearLayout.animate().setListener(null);
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(mHiddenLinearLayoutHeight);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}

і це код для приховування елементів анімації:

private void hideElements() {
    // Precondition
    if (!areElementsVisible()) {
        Log.w(TAG, "The view is already non-visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.v(TAG, "Animation ended. Set the view as gone");
                    super.onAnimationEnd(animation);
                    mHiddenLinearLayout.setVisibility(View.GONE);
                    // Hack: Remove the listener. So it won't be executed when
                    // any other animation on this view is executed
                    mHiddenLinearLayout.animate().setListener(null);
                    updateShowElementsButton();
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(0);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight();
}

Зауважте, що на метод приховання анімації є простий хак. На слухачі анімації mHiddenLinearLayout мені довелося видалити самого слухача, використовуючи:

mHiddenLinearLayout.animate().setListener(null);

Це відбувається тому, що раз, коли слухач анімації буде приєднаний до перегляду, наступного разу, коли будь-яка анімація буде виконана в цьому режимі, і слухач буде виконаний. Це може бути помилка в слухачі анімації.

Вихідний код проекту знаходиться на GitHub: https://github.com/jiahaoliuliu/ViewsAnimated

Щасливого кодування!

Оновлення : будь-який слухач, приєднаний до переглядів, його слід видалити після закінчення анімації. Це робиться за допомогою

view.animate().setListener(null);

Ця найкраща відповідь
— Naveen Kumar M

1
view.animate().setListener(null);Заява врятувало мій день. Це, безумовно, здається помилкою.
— Міхал Вікіан

@MichalVician Рада!
— jiahao

8

Я зміг показати / приховати меню таким чином:

MenuView.java (розширює FrameLayout)

private final int ANIMATION_DURATION = 500;

public void showMenu()
{
    setVisibility(View.VISIBLE);
    animate()
            .alpha(1f)
            .setDuration(ANIMATION_DURATION)
            .setListener(null);
}

private void hideMenu()
{
    animate()
            .alpha(0f)
            .setDuration(ANIMATION_DURATION)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(View.GONE);
                }
            });
}

Джерело

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.