Mdp11
Mdp11

Reputation: 572

Animations and visibility concatenation issues

I have to shift some text views visibility to gone and some others to visibile, and I'm trying to animate this.
Here's the code I've written:

public class SearchBookTest extends AppCompatActivity {

private final static int INTRO_VIEW = 0;
private final static int OFFLINE_VIEW = 1;
private boolean[] currentView = {true, false};
private FloatingSearchView mSearchView;
private TextView mIntroTextViewTop;
private TextView mIntroTextViewBottom;
private TextView mNoConnectionTextViewTop;
private TextView mNoConnectionTextViewBottom;
private AppCompatButton mNoConnectionButton;
private int mShortAnimationDuration;

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

    mSearchView = findViewById(R.id.floating_search_view);
    mIntroTextViewTop = findViewById(R.id.search_book_intro_top);
    mIntroTextViewBottom = findViewById(R.id.search_book_intro_bottom);
    mNoConnectionTextViewTop = findViewById(R.id.search_book_no_connection_top);
    mNoConnectionTextViewBottom = findViewById(R.id.search_book_no_connection_bottom);
    mNoConnectionButton = findViewById(R.id.search_book_no_connection_try_again);
    mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
    setupQueryChangeListener();
}

private void setupQueryChangeListener() {
    mSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() {
        @Override
        public void onSearchTextChanged(String oldQuery, String newQuery) {
            switch (newQuery.length()) {
                case 1:
                    showIntroView();
                    break;

                case 2:
                    showOfflineView();
                    break;

                default:
                    break;
            }
        }
    });
}

private void showOfflineView() {

    if (currentView[INTRO_VIEW]) {
        currentView[INTRO_VIEW] = false;
        fadeOutViews(mIntroTextViewTop, mIntroTextViewBottom, null, mNoConnectionTextViewTop, mNoConnectionTextViewBottom, mNoConnectionButton);
    }
    currentView[OFFLINE_VIEW] = true;
}


private void showIntroView() {

    if (currentView[OFFLINE_VIEW]) {
        currentView[OFFLINE_VIEW] = false;
        fadeOutViews(mNoConnectionTextViewTop, mNoConnectionTextViewBottom, mNoConnectionButton, mIntroTextViewTop, mIntroTextViewBottom, null);
    }

    currentView[INTRO_VIEW] = true;
}

private void fadeOutViews(final View vOut1, final View vOut2, final View vOut3, final View vIn1, final View vIn2, final View vIn3) {
    vOut1.animate()
            .alpha(0f)
            .setDuration(mShortAnimationDuration)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (vOut2 != null) {
                        vOut2.animate()
                                .alpha(0f)
                                .setDuration(mShortAnimationDuration)
                                .setListener(new AnimatorListenerAdapter() {
                                    @Override
                                    public void onAnimationStart(Animator animation) {
                                    }

                                    @Override
                                    public void onAnimationEnd(Animator animation) {
                                        vOut2.setVisibility(View.GONE);
                                        if (vOut3 == null)
                                            fadeInViews(vIn1, vIn2, vIn3);
                                    }
                                });
                    }

                    if (vOut3 != null) {
                        vOut3.animate()
                                .alpha(0f)
                                .setDuration(mShortAnimationDuration)
                                .setListener(new AnimatorListenerAdapter() {
                                    @Override
                                    public void onAnimationStart(Animator animation) {

                                    }

                                    @Override
                                    public void onAnimationEnd(Animator animation) {
                                        vOut3.setVisibility(View.GONE);
                                        fadeInViews(vIn1, vIn2, vIn3);
                                    }
                                });
                    }

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    vOut1.setVisibility(View.GONE);
                    if (vOut2 == null)
                        fadeInViews(vIn1, vIn2, vIn3);
                }
            });
}

private void fadeInViews(final View v1, final View v2, final View v3) {
    v1.setAlpha(0f);
    v1.setVisibility(View.VISIBLE);

    v1.animate()
            .alpha(1f)
            .setDuration(mShortAnimationDuration)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (v2 != null) {
                        v2.setAlpha(0f);
                        v2.setVisibility(View.VISIBLE);

                        v2.animate()
                                .alpha(1f)
                                .setDuration(mShortAnimationDuration)
                                .setListener(new AnimatorListenerAdapter() {
                                    @Override
                                    public void onAnimationStart(Animator animation) {
                                        if (v3 != null) {
                                            v3.setAlpha(0f);
                                            v3.setVisibility(View.VISIBLE);
                                            v3.animate()
                                                    .alpha(1f)
                                                    .setDuration(mShortAnimationDuration);
                                        }
                                    }

                                });
                    }
                }

            });
}

}

And here's the layout file:

    <?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parent_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="@color/grey"
    tools:context=".ui.searchbooks.SearchBookActivity">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="10dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/search_book_intro_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="200dp"
        android:text="@string/search_intro_top"
        android:textColor="@color/grayed_button"
        android:fontFamily="sans-serif-light"
        android:textSize="22sp"/>

    <TextView
        android:id="@+id/search_book_intro_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="8dp"
        android:text="@string/search_intro_botttom"
        android:textColor="@color/grayed_button"
        android:fontFamily="sans-serif-light"
        android:textSize="16sp"/>

    <TextView
        android:id="@+id/search_book_no_connection_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="200dp"
        android:text="@string/search_no_connection_1"
        android:textColor="@color/black"
        android:fontFamily="sans-serif-bold"
        android:textSize="18sp"
        android:visibility="gone"/>

    <TextView
        android:id="@+id/search_book_no_connection_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:text="@string/search_no_connection_2"
        android:textColor="@color/black"
        android:fontFamily="sans-serif-light"
        android:textSize="14sp"
        android:visibility="gone"/>

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/search_book_no_connection_try_again"
        android:layout_width="wrap_content"
        android:layout_height="36dp"
        android:layout_marginTop="20dp"
        android:elevation="2dp"
        android:text="@string/try_again"
        android:gravity="center"
        android:layout_gravity="center_horizontal"
        android:background="@color/colorSecondaryAccent"
        android:visibility="gone"/>


</LinearLayout>


<com.arlib.floatingsearchview.FloatingSearchView
    android:id="@+id/floating_search_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:floatingSearch_close_search_on_keyboard_dismiss="true"
    app:floatingSearch_dismissOnOutsideTouch="true"
    app:floatingSearch_leftActionMode="showHome"
    app:floatingSearch_menu="@menu/menu_search_books"
    app:floatingSearch_dimBackground="false"
    app:floatingSearch_searchBarMarginLeft="5dp"
    app:floatingSearch_searchBarMarginRight="5dp"
    app:floatingSearch_searchBarMarginTop="5dp"
    app:floatingSearch_searchHint="@string/search_books_hint"
    app:floatingSearch_showSearchKey="true"/>
</RelativeLayout>

As soon as I write the second character for the first time, the views switch up fine, making the 3 "noConnection" views animate and show fine.
Then I delete one char and the intro views show up fine again (after the no connection views disappear), but when I write a second char again, the views will mess up, making the whole intro views to show together with the no connection views (except for the button).
I identified what goes wrong, but I can't understand why it happens:
when a 2nd char is written for the 2nd time "vOut3" variable is not null, but contains the mNoConnectionButton, making it disappear and calling the fadeInView on the two intro views. I tried to log the values and vOut3 is null, but it enters in the if statement anyway!
Can somebody help me out of this mess?

Upvotes: 1

Views: 49

Answers (1)

B&#246; macht Blau
B&#246; macht Blau

Reputation: 13009

You can use the Transition framework to achieve the desired result. The following code will work for API level 19+.

Basically you call TransitionManager.beginDelayedTransition(sceneRoot, transitionSet); and immediately afterwards you set the desired state of your Views.

The sceneRoot should be a ViewGroup containing all the Views which are to be transformed. In your case I think the LinearLayout is a good choice. So I let it have an attribute android:id="@+id/sceneRoot" and declared a variable private ViewGroup sceneRoot; in the Activity and assigned the LinearLayout to it in onCreate().

For the Transition I used a TransitionSet consisting of a Fade transition as well as a ChangeBounds transition because you changed the alpha value as well as the overall layout (swapping between View.VISIBLE and View.GONE).

private void fadeOutViews(final View vOut1, final View vOut2, final View vOut3, final View vIn1, final View vIn2, final View vIn3) {
    //  if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)return;
    TransitionSet transitionSet = new TransitionSet();
    transitionSet.addTransition(new Fade());
    transitionSet.addTransition(new ChangeBounds());
    TransitionManager.beginDelayedTransition(sceneRoot, transitionSet);
    vOut1.setVisibility(View.GONE);
    if(vOut2 != null) {
        vOut2.setVisibility(View.GONE);
    }
    if(vOut3 != null) {
        vOut3.setVisibility(View.GONE);
    }
    vIn1.setVisibility(View.VISIBLE);
    if(vIn2 != null) {
        vIn2.setVisibility(View.VISIBLE);
    }
    if(vIn3 != null) {
        vIn3.setVisibility(View.VISIBLE);
    }
}

Upvotes: 1

Related Questions