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.