Android voegt eenvoudige animaties toe terwijl de zichtbaarheid wordt ingesteld (view.Gone)

Ik heb een eenvoudige lay-out ontworpen. Ik heb het ontwerp zonder animatie voltooid, maar nu wil ik animaties toevoegen wanneer de tekstweergave klikt op een gebeurtenis en ik weet niet hoe ik het moet gebruiken.
Ziet mijn xml-ontwerp er goed uit of niet?
Eventuele suggesties worden op prijs gesteld.

Mijn 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>

Mijn Java

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);
            }
        });
    }
}

Antwoord 1, autoriteit 100%

Je kunt twee dingen doen om animaties toe te voegen. Ten eerste kun je Android de lay-outwijzigingen voor je laten animeren. Op die manier zal Android elke keer dat je iets in de lay-out verandert, zoals het wijzigen van de zichtbaarheid van de weergave of de weergaveposities, automatisch vervagings-/overgangsanimaties maken. Om die set te gebruiken

android:animateLayoutChanges="true"

op het hoofdknooppunt in uw lay-out.

Uw tweede optie zou zijn om handmatig animaties toe te voegen. Hiervoor raad ik u aan de nieuwe animatie-API te gebruiken die is geïntroduceerd in Android 3.0 (Honeycomb). Ik kan je een paar voorbeelden geven:

Hiermee verdwijnt een View:

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

Hiermee vervaagt het weer:

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

Hiermee wordt een Viewmet zijn hoogte naar beneden verplaatst:

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

Hiermee keert de Viewterug naar de beginpositie nadat deze ergens anders is verplaatst:

view.animate().translationY(0);

Je kunt ook setDuration()gebruiken om de duur van de animatie in te stellen. Dit vervaagt bijvoorbeeld een Viewover een periode van 2 seconden:

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

En je kunt zoveel animaties combineren als je wilt, dit vervaagt bijvoorbeeld een Viewen verplaatst het tegelijkertijd over een periode van 0,3 seconden:

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

En je kunt ook een luisteraar aan de animatie toewijzen en reageren op allerlei gebeurtenissen. Zoals wanneer de animatie start, wanneer deze eindigt of herhaalt enz. Door de abstracte klasse AnimatorListenerAdapterte gebruiken, hoeft u niet alle callbacks van AnimatorListenertegelijk te implementeren, maar alleen die u nodig hebben. Dit maakt de code beter leesbaar. De volgende code vervaagt bijvoorbeeld een Viewverplaatst deze met zijn hoogte over een periode van 0,3 seconden (300 milliseconden) en wanneer de animatie klaar is, wordt de zichtbaarheid ingesteld op 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);
            }
        });

Antwoord 2, autoriteit 20%

De gemakkelijkste manier om veranderingen in Visibilityte animeren, is door Transition APIte gebruiken, die beschikbaar is in een ondersteuningspakket (androidx). Roep de methode TransitionManager.beginDelayedTransitionaan en verander de zichtbaarheid van de weergave. Er zijn verschillende standaardovergangen zoals 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);
}

Waarbij parentde bovenliggende ViewGroupis van de geanimeerde weergave. Resultaat:

voer hier de afbeeldingsbeschrijving in

Hier is resultaat met Slideovergang:

import androidx.transition.Slide;
Transition transition = new Slide(Gravity.BOTTOM);

voer hier de afbeeldingsbeschrijving in

Het is gemakkelijk om een ​​aangepaste overgang te schrijven als je iets anders nodig hebt. Hier is een voorbeeld met CircularRevealTransitiondie ik schreef in een ander antwoord. Het toont en verbergt weergave met CircularReveal-animatie.

Transition transition = new CircularRevealTransition();

voer hier de afbeeldingsbeschrijving in

android:animateLayoutChanges="true"optie doet hetzelfde, het gebruikt alleen AutoTransitionals overgang.


Antwoord 3, autoriteit 5%

Probeer deze regel toe te voegen aan de XML-ouderlay-out

android:animateLayoutChanges="true"

Uw lay-out ziet er zo uit

<?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>

Antwoord 4, autoriteit 3%

Controleer ditkoppeling. Waardoor animaties zoals L2R, R2L, T2B, B2T-animaties mogelijk zijn.

Deze code toont animatie van links naar rechts

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

als je het vanuit R2L wilt doen, gebruik dan

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

van boven naar beneden als

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

en omgekeerd..


Antwoord 5, autoriteit 2%

Op basis van het antwoord van @Xaver Kapeller heb ik een manier bedacht om scroll-animaties te maken wanneer nieuwe weergaven op het scherm verschijnen (en ook animatie om ze te verbergen).

Het gaat van deze staat:

  • Knop
  • Laatste knop

naar

  • Knop
  • Knop 1
  • Knop 2
  • Knop 3
  • Knop 4
  • Laatste knop

en omgekeerd.

Dus wanneer de gebruiker op de eerste knop klikt, verschijnen de elementen “Knop 1”, “Knop 2”, “Knop 3” en “Knop 4” met behulp van fade-animatie en wordt het element “Laatste knop” naar beneden verplaatst tot het einde. De hoogte van de lay-out zal ook veranderen, zodat de scrollweergave correct kan worden gebruikt.

Dit is de code om elementen met animatie weer te geven:

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;
}

en dit is de code om elementen van de animatie te verbergen:

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();
}

Let op: er is een eenvoudige hack op de methode om de animatie te verbergen. Op de animatielistener mHiddenLinearLayout moest ik de luisteraar zelf verwijderen met:

mHiddenLinearLayout.animate().setListener(null);

Dit komt omdat zodra een animatielistener aan een weergave is gekoppeld, de volgende keer dat een animatie in deze weergave wordt uitgevoerd, de luisteraar ook wordt uitgevoerd. Dit kan een bug zijn in de animatie-listener.

De broncode van het project staat op GitHub:
https://github.com/jiahaoliuliu/ViewsAnimated

Veel plezier met coderen!

Update: voor elke luisteraar die aan de weergaven is gehecht, moet deze worden verwijderd nadat de animatie is afgelopen. Dit wordt gedaan met behulp van

view.animate().setListener(null);

Antwoord 6, autoriteit 2%

Ik kon een menu op deze manier tonen/verbergen:

MenuView.java (verlengt 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);
                }
            });
}

Bron


Antwoord 7, autoriteit 2%

Gebaseerd op het antwoord van @ashakirov, hier is mijn extensie om weergave te tonen/verbergen met fade-animatie

fun View.fadeVisibility(visibility: Int, duration: Long = 400) {
    val transition: Transition = Fade()
    transition.duration = duration
    transition.addTarget(this)
    TransitionManager.beginDelayedTransition(this.parent as ViewGroup, transition)
    this.visibility = visibility
}

Voorbeeld met

view.fadeVisibility(View.VISIBLE)
view.fadeVisibility(View.GONE, 2000)

Antwoord 8

Mijn oplossingsextensie

fun View.slideVisibility(visibility: Boolean, durationTime: Long = 300) {
    val transition = Slide(Gravity.BOTTOM)
    transition.apply {
        duration = durationTime
        addTarget(this@slideVisibility)
    }
    TransitionManager.beginDelayedTransition(this.parent as ViewGroup, transition)
    this.isVisible = visibility
    }

Gebruik:

textView.slideVisibility(true)

Antwoord 9

Zoek de onderstaande code om de weergave in Circuler reveal zichtbaar te maken. Als je true verzendt, wordt deze Invisible/Gone. Als u false verzendt, wordt het zichtbaar. anyView is de weergave die u zichtbaar/verbergt, het kan elke weergave zijn (lay-outs, knoppen, enz.)

private fun toggle(flag: Boolean, anyView: View) {
    if (flag) {
        val cx = anyView.width / 2
        val cy = anyView.height / 2
        val initialRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
        val anim = ViewAnimationUtils.createCircularReveal(anyView, cx, cy, initialRadius, 0f)
        anim.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                super.onAnimationEnd(animation)
                anyView.visibility = View.INVISIBLE
            }
        })
        anim.start()
    } else {
        val cx = anyView.width / 2
        val cy = anyView.height / 2
        val finalRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()
        val anim = ViewAnimationUtils.createCircularReveal(anyView, cx, cy, 0f, finalRadius)
        anyView.visibility = View.VISIBLE
        anim.start()
    }
}

Other episodes