LayoutTransition: Animate Просмотр рядом с расширяющимся представлением

Я воссоздал свою проблему до очень простого представления. У меня есть 3 TextViews. 2 из них находятся в отдельном LinearLayout, третий находится на том же уровне, что и LinearLayout. Я переключаю видимость test1 и test2, и я хотел бы, чтобы они исчезали (что работает). Кроме того, я хочу, чтобы test3 скользнул в его новое место (имеющее место test1 и test2). Я не могу этого сделать. test3 просто привязывает к ней новую точку.

Как я могу добиться этого?

Мой код:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click" />

    <LinearLayout android:animateLayoutChanges="true"
        android:id="@+id/child1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/test1"
            android:layout_width="match_parent" android:visibility="gone"
            android:layout_height="wrap_content"
            android:text="TEST1" />

        <TextView
            android:id="@+id/test2"
            android:layout_width="match_parent" android:visibility="gone"
            android:layout_height="wrap_content"
            android:text="TEST2" />
    </LinearLayout>

    <TextView
        android:id="@+id/test3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TEST3" />

</LinearLayout>

И в моей деятельности:

public class LayoutAnimations extends Activity {
    private boolean toggle = true;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_animations);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (toggle) {
                    findViewById(R.id.test1).setVisibility(View.VISIBLE);
                    findViewById(R.id.test2).setVisibility(View.VISIBLE);
                } else {
                    findViewById(R.id.test1).setVisibility(View.GONE);
                    findViewById(R.id.test2).setVisibility(View.GONE);
                }
                toggle = !toggle;
            }
        });

    }

}

Изменить: у меня на самом деле есть еще один TextView рядом с test1 и test2, который должен быть видимым во все времена, поэтому я не могу просто скрыть сам LinearLayout.

Ответ 1

Я решил это, используя другой вопрос. См. этот ответ

Цитирование:

Я считаю, что самый простой подход заключается в расширении класса Animation и переопределении applyTransformation() для изменения высоты представления следующим образом:

import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;

public class MyCustomAnimation extends Animation {

    public final static int COLLAPSE = 1;
    public final static int EXPAND = 0;

    private View mView;
    private int mEndHeight;
    private int mType;
    private LinearLayout.LayoutParams mLayoutParams;

    public MyCustomAnimation(View view, int duration, int type) {

        setDuration(duration);
        mView = view;
        mEndHeight = mView.getHeight();
        mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams());
        mType = type;
        if(mType == EXPAND) {
            mLayoutParams.height = 0;
        } else {
            mLayoutParams.height = LayoutParams.WRAP_CONTENT;
        }
        view.setVisibility(View.VISIBLE);
    }

    public int getHeight(){
        return mView.getHeight();
    }

    public void setHeight(int height){
        mEndHeight = height;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {

        super.applyTransformation(interpolatedTime, t);
        if (interpolatedTime < 1.0f) {
            if(mType == EXPAND) {
                mLayoutParams.height =  (int)(mEndHeight * interpolatedTime);
            } else {
                mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime));
            }
            mView.requestLayout();
        } else {
            if(mType == EXPAND) {
                mLayoutParams.height = LayoutParams.WRAP_CONTENT;
                mView.requestLayout();
            }else{
                mView.setVisibility(View.GONE);
            }
        }
    }
}

Чтобы использовать его, установите onclick() следующим образом:

int height;

@Override
public void onClick(View v) {
    if(view2.getVisibility() == View.VISIBLE){
        MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyAnimation.COLLAPSE);
        height = a.getHeight();
        view2.startAnimation(a);
    }else{
        MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyAnimation.EXPAND);
        a.setHeight(height);
        view2.startAnimation(a);
    }
}

С уважением.

Ответ 2

Я хотел, чтобы то же самое происходило в моем приложении. Для этого:

  • Создайте подходящую анимацию в Res/anim. Я использовал слайд из левого вида анимации. Вы можете google другие, если вы не удовлетворены этим.

    slide_out_left.xml

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromXDelta="0"
        android:toXDelta="-50%p" />
    
    <alpha
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
    

  • Приложите анимацию, определенную выше, с целью, которую вы хотите оживить, (в вашем случае child1, содержащий text1 и text2)

    Animation outAnimation;
    LinearLayout a1 = (LinearLayout)findViewById(R.id.child1); 
    
    outAnimation = (Animation) AnimationUtils.loadAnimation (getApplicationContext(), R.anim.slide_out_left);
    
    a1.setAnimation(outAnimation);
    outAnimation.setAnimationListener(new  AnimationListener() {
    
        @Override
        public void onAnimationEnd(Animation arg0) {
        a1.setVisibility(View.GONE);                            
        }
        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub                          
        }
    
        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub
        }                 
    });
    a1.startAnimation(outAnimation);
    

ПРИМЕЧАНИЕ. Я добавил анимацию с child1 вместо text3, потому что, когда child1 медленно выскользнет, ​​она автоматически даст иллюзию, что текст3 скользит.

Ответ 3

использовать эту анимацию XML slide_in_left.XML

<translate
    android:duration="500"
    android:fromXDelta="-100%"
    android:fromYDelta="0%"
    android:toXDelta="0%"
    android:toYDelta="0%" />
</set>

и slid_in_right.XML

<translate
    android:duration="500"
    android:fromXDelta="100%"
    android:fromYDelta="0%"
    android:toXDelta="0%"
    android:toYDelta="0%" />
</set>

используйте эту анимацию Анимированная слайд-лекция, слайд-шоу;

и инициализировать эту анимацию

public void AnimationInitialization() {

    slideinleft= AnimationUtils
            .loadAnimation(this, R.anim.slide_in_left);


    slideinright= AnimationUtils.loadAnimation(this,
            R.anim.slide_in_right);

}

и вызовите эту функцию 2 для изменения visibilty

public void showMenu() {

    linearlayout_first.clearAnimation();

    linearlayout_first.startAnimation(slideinleft);

    linearlayout_first.setVisibility(View.VISIBLE);

}

public void hideMenu() {

    linearlayout_second.clearAnimation();
    linearlayout_second.startAnimation(slideinright);


    linearlayout_second.setVisibility(View.GONE);
}

вы можете изменить макет по своему усмотрению. также изменяются в Xdelta и Ydelta анимации XML..

Ответ 4

Документация немного запутанна. Для android:animateLayoutChanges он говорит

... Когда для этого флага установлено значение true, в контейнере ViewGroup будет установлен объект LayoutTransition по умолчанию, и по умолчанию будут выполняться анимации по умолчанию.

а документация setLayoutTransition метода класса ViewGroup говорит:

По умолчанию объект перехода имеет значение null (так что изменения макета не являются анимированный).

Вы должны попробовать установить LayoutTransition на макет.

Вот пример, который делает это. http://www.java2s.com/Code/Android/UI/UseLayoutTransitiontoautomatetransitionanimationsasitemsarehiddenorshowninacontainer.htm