title: how to animate listview expand and collapse
body: <p>Having a text displayed initially at screen bottom. When clicking on it, the list view below it should sliding up. Clicking on the text again the list view sliding down.</p>
  
  <p>Made it work with the snippet below except the first time clicking on the text the list does not do the animation sliding up. After that it will animate sliding up/down as expected.</p>
  
  <p>It is because in the first clicking and call of showListView(true); since the list view’s visibility was “gone”, so it has not had height. The “y” == 0 translate does not do anything. It is just the list view’s visibility change to “visible”, which push the titleRow change its position.</p>
  
  <p>But if to begin with the list view’s visibility to “visible”, the initial showListView(false); in setupListViewAdapter() does not push the list view down to initial state (outside of screen bottom) since it does not have the height until the list row are filled in from the adapter by mListView.setAdapter(mListAdapter).</p>
  
  <p>Is there better way to do sidling up/down the list view?</p>
  
  <pre><code>        &lt;TextView
                  android:id="@+id/titleRow”
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text=“title row”
          /&gt;
  
          &lt;ListView
              android:id="@+id/list_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:visibility=“gone”
              &gt;
          &lt;/ListView&gt;
  
  
  initial state list view collapsed(outside screen bottom)
  +++++++++++++++++++++++++++
  +  mTitleRow          + ^ +
  +++++ screen bottom   +++++
  
  
  listview expanded
  +++++++++++++++++++++++++++
  +  mTitleRow          + ^ +
  +++++++++++++++++++++++++++
  +                         +
  +  mListView              +
  +                         +
  +++++ screen bottom   +++++
  
  
  void setupListViewAdapter(){
          mTitleRow.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  if (mTitleRow.getTag() == STATE_COLLAPSED)                    
                  { 
                     mListView.setVisibility(View.VISIBLE);                       
                     showListView(true);
                  } else {
                     showListView(false);
                  }
              }
          });
  
      mListView.setAdapter(mListAdapter);
      showListView(false); 
  }
  
  private static final int STATE_EXPANDED = 1;
  private static final int STATE_COLLAPSED = 2;
  boolean mListInAnimation = false;
  public void showListView(final boolean show) {
      if (mListView != null &amp;&amp; !mListInAnimation) {
          mListInAnimation = true;
          mTitleRow.setTag(show ? STATE_EXPANDED : STATE_COLLAPSED);            
          int translateY = show ? 0 : (listHeight);
  
          mTitleRow.animate().translationY(translateY).setDuration(300).setListener(new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(Animator animation) {
                  mListInAnimation = false;
              }
          });
      }
  }
  </code></pre>