0

So I have looked into how to animate fade and drop down/slide up animations of Views using this thread, however it didn't quite work as expected. To begin with, here is the code I use for the animating:

public void toggleAdvancedVisibility(View text) { //text is a clickable textview thats acts as a toggle
    int dur = 1000;
    final View advView = findViewById(R.id.enc_advanced);
    if(advView.getVisibility() == View.GONE && animationDone) {
        advView.setVisibility(View.VISIBLE);
        advView.setAlpha(0.0f);

        //animate fade + drop down
        advView.animate()
                .setDuration(dur)
                .translationY(advView.getHeight())
                .alpha(1.0f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        animationDone = true;
                    }
                });
        animationDone=false;
    }
    else if(advView.getVisibility() == View.VISIBLE && animationDone) {
        //animate fade + slide up
        advView.animate()
                .setDuration(dur)
                .translationY(0)
                .alpha(0.0f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        advView.setVisibility(View.GONE);
                        animationDone = true;
                    }
                });
        animationDone = false;
    }
}

As I said, while there was animation, it didn't act anywhere near as expected.

Problem #1 The view is almost pushed out of visibility. I believe that this is due to the line .translationY(advView.getHeight()) as if I set the location of the view before the animation to advView.setTranslationY(-advView.getHeight()) and then animate .translationY(0) it goes to where it is supposed to.

The obvious problem with this is that while the view is animating, the view "collides" with the view above it before it is done. So how do I properly get this to slide down/up without running into the view above it?

Problem #2 The animation doesn't exactly "push" the view down, which is what I expected. What I mean by this is that the view being animated also has a view below it. I expected the view below it to be pushed down with the animated view. While I haven't tried it yet, I assume this can be simulated by setting the same animation to the view below it, but is there another way of doing it?

I am very new to this animation stuff and manipulating Views like this so any help is appreciated.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Soggy_Toast
  • 57
  • 1
  • 9
  • use `android.support.design.widget.BaseTransientBottomBar` as a base class or (if you need different behavior) see its sources to get to know how it is done – pskink Oct 19 '17 at 06:26
  • @pskink Do you have a specific link or source that I could use? I am reading the documentation and I believe I understand to a degree what I am supposed to do, but not certain. I also can't find any good examples of it being used. – Soggy_Toast Oct 19 '17 at 06:40
  • ask uncle google for `BaseTransientBottomBar.java` – pskink Oct 19 '17 at 06:43
  • @pskink I did, all I found was source code and information relating to `SnackBar`s, which I know nothing about. None of it helps me in figuring out how to implement it – Soggy_Toast Oct 19 '17 at 06:56
  • so if you have the source of `android.support.design.widget.Snackbar` you have all of it - `Snackbar` extends `BaseTransientBottomBar` – pskink Oct 19 '17 at 06:57
  • @pskink I am still unsure how to apply this or what it does exactly. Especially in the xml layout file. – Soggy_Toast Oct 19 '17 at 07:09
  • so do you want to change the behavior of `Snackbar` or just use it as it is? – pskink Oct 19 '17 at 07:10
  • @pskink I don't see how `Snackbar` is relevant. From my understanding `Snackbar` is just displaying text at the top of the screen for brief information, similar to `Toast`, which isn't what I am trying to do. – Soggy_Toast Oct 19 '17 at 07:15
  • yes, `Snackbar` is doing `"drop down/slide up animations of Views"`, more preciously it is done by `BaseTransientBottomBar` – pskink Oct 19 '17 at 07:17
  • Ok, so I get `Snackbar` has similar behavior to what I want, but I still don't understand how to use `BaseTransientBottomBar`, as it doesn't even have a public constructor and I have no idea how I would add it to what I already have. – Soggy_Toast Oct 19 '17 at 07:22
  • @pskink Ok, I get that, what I don't get is how I'm supposed to apply it to my situation. – Soggy_Toast Oct 19 '17 at 20:54

1 Answers1

0

I made you a short example and I see it pushes down the rest of the view. xml:

<LinearLayout 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.teststuff.MainActivity"
android:orientation="vertical">

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/b1"
    android:text="show"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tv1"
    android:text="Hello World!"
    android:visibility="gone"/>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!!!!"/>

and here is the .java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv1 = (TextView) findViewById(R.id.tv1);
    tv2 = (TextView) findViewById(R.id.tv2);
    b1 = (Button) findViewById(R.id.b1);

    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (tv1.isShown()){
                tv1.startAnimation(slideInAnimation(view));
                tv1.setVisibility(View.GONE);
            }
            else {
                tv1.startAnimation(slideOutAnimation(view));
                tv1.setVisibility(View.VISIBLE);
            }
        }
    });


}

private TranslateAnimation slideOutAnimation(View view){
    TranslateAnimation animate = new TranslateAnimation(0,0,-view.getHeight(),0);
    animate.setDuration(500);
    animate.setFillAfter(false);
    return animate;
}
private TranslateAnimation slideInAnimation(View view){
    TranslateAnimation animate = new TranslateAnimation(0,0,0,-view.getHeight());
    animate.setDuration(500);
    animate.setFillAfter(true);
    return animate;
}

It works fine for me.

Laur89
  • 105
  • 7