title: Scroll listview to selected position
body: <p>The screen snapshot below illustrates a listview that shows five items, each of them is made up of two parts: A and B. The listview initially displays these five items, hiding part B of each by default. The user should be able to click on part A to show or hide the respective part B. If the user taps on fifth item, I want to animate the shifting up the whole listview above 5 (including part A) in order to make room for part B of the fifth item. Or if you want to display part B of the fourth item, after clicking on fourth item I would like to shift down item 5 to make room for part B of item 4. Bottom line, if we click on an item, we want to shift the position of the listview to ensure that we have room for the newly exposed part B. </p>
  
  <p>I know that <code>listview.setSelection(3)</code> will scroll the positioned item to the top of the list. And I am also familiar with <code>listview.smoothScrollToPosition(8)</code>, but this method requires api 8, but our project is using version 7.</p>
  
  <p>I have made some progress with the above animation, but am having trouble ensuring that the listview item stays (or scrolls) to the correct position. As I expand and shrink a particular item, how do I control the position of the broader listview?</p>
  
  <p><img src="https://i.stack.imgur.com/plV9c.jpg" alt="Example screen snapshots with part B hidden and then shown"></p>
  
  <hr>
  
  <p>Here is the code:</p>
  
  <pre><code>/**
   * 类SubCategoryAdapter.java的实现描述：TODO 类实现描述
   * @author xianyi.chengxy 2012-8-17 下午7:39:47
   */
  public class SubCategoryAdapter extends BaseListAdapter&lt;IndustryNavigationData&gt; {
      private Context mContext ;
      private LayoutInflater mInflater ;
      private ListView mListView ;
  
      static String defaultName = "subCategory.png" ;
  
      private int mPreVisiPosition = -1 ;
      private int mVisiPosition = -1 ;
  
      public SubCategoryAdapter( Context context , int visiPosition, ListView  listView ){
          super(context) ;
          this.mContext = context.getApplicationContext()  ;
          this.mInflater = LayoutInflater.from(mContext) ;
          this.mVisiPosition = visiPosition ;
          this.mListView = listView ;
      }
      public void setVisiPosition(int visiPosition){
          this.mVisiPosition = visiPosition ;
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          if( convertView == null ){
              convertView = mInflater.inflate(R.layout.v2_subcategory_listitem, null) ;
              NoScrollGridView gridView = (NoScrollGridView) convertView.findViewById(R.id.subCategory_groupView_gridView) ;
              gridView.setNumColumns(5) ;
  
              final BaseListAdapter&lt;IndustryNavigationData&gt; listAdapter = new SubCategoryGridViewAdapter(mContext) ;
              gridView.setAdapter(listAdapter) ;
              gridView.setTag(listAdapter) ;
  
              ViewHold viewHold = new ViewHold() ;
              viewHold.gridLayout = (LinearLayout) convertView.findViewById(R.id.subCategory_groupView_gridViewLayout) ;
              viewHold.imageView = (ImageView_) convertView.findViewById(R.id.subCategory_groupView_imageview) ;
              viewHold.name = (TextView) convertView.findViewById(R.id.subCategory_groupView_name) ;
              viewHold.childsName = (TextView) convertView.findViewById(R.id.subCategory_groupView_childs) ;
              viewHold.gridView = gridView ;
              // TO search
              viewHold.gridView.setOnItemClickListener(new OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView&lt;?&gt; parent, View view,
                                          int position, long id) {
                      UILogUtils.saveAndAppendLogType(LogTypeCode.APP_DRESSCATEGORY_BROWSER_TWO);
                      MyOfferRequest request = new MyOfferRequest();
                      IndustryNavigationData item = listAdapter.getItem(position);
                      if (IndustryNavigationDataType.LEFT_CATEGORY.equals(item
                                                                          .getType())) {
                          request.setCategoryId(item.getId());
                          request.setCategoryName(item.getName());
                      } else if (IndustryNavigationDataType.LEFT_KEYWORD
                                 .equals(item.getType())) {
                          request.setCategoryId(item.getId());
                          request.setKeywords(item.getName());
                      }
                      ActivityUtil.gotoSearchOfferList(request, mContext, true);
                  }
              });
  
              viewHold.groupLayout = convertView.findViewById(R.id.subCategory_groupLayout) ;
              viewHold.groupLayout.setOnClickListener(clickListener) ;
              convertView.setTag(viewHold) ;
          }
  
          ViewHold viewHold = (ViewHold) convertView.getTag() ;
          viewHold.position = position ;
          IndustryNavigationData item = group.get(position) ;
          viewHold.groupLayout.setTag(viewHold) ;
  
          String url = item.getImageUrl() ;
          if( url != null ){
              viewHold.imageView.setImageResource(item.getImageUrl(), 110, 110, R.drawable.default_image) ;
          }
  
          viewHold.name.setText( item.getName() );
          StringBuffer sb = new StringBuffer() ;
          List&lt;IndustryNavigationData&gt; childs = item.getChildren() ;
          if( (childs!=null) &amp;&amp; (childs.size()!=0) ){
              for( IndustryNavigationData itemChild : item.getChildren() ){
                  sb.append(itemChild.getName()).append("/") ;
              }
              sb.deleteCharAt(sb.length()-1) ;
              viewHold.childsName.setText(sb.toString()) ;
          }else{
              viewHold.childsName.setText("") ;
          }
  
          BaseListAdapter&lt;IndustryNavigationData&gt; gridViewAdapter = (BaseListAdapter&lt;IndustryNavigationData&gt;) viewHold.gridView.getTag() ;
          gridViewAdapter.setList(item.getChildren()) ;
          if( (this.mVisiPosition==position) &amp;&amp; (item.getChildren()!=null) &amp;&amp; (item.getChildren().size()!=0) ){
              scrollView(viewHold, item, ExpandCollapseAnimation.EXPAND);
              viewHold.gridLayout.setVisibility(View.VISIBLE) ;
          }else{
              if( position == this.mPreVisiPosition ){
                  //    viewHold.gridLayout.setVisibility(View.GONE) ;
                  mPreVisiPosition = -1 ;
                  scrollView(viewHold, item, ExpandCollapseAnimation.COLLAPSE);
              }else{
                  viewHold.gridLayout.setVisibility(View.GONE) ;
              }
          }
  
          return convertView;
      }
      private class ViewHold{
          public int position ;
          public View groupLayout ;
          public LinearLayout gridLayout ;
          public ImageView_ imageView ;
          public TextView name ;
          public TextView childsName ;
          public NoScrollGridView gridView ;
      }
  
      OnClickListener clickListener = new OnClickListener() {
          @Override
          public void onClick(View v) {
              UILogUtils.saveAndAppendLogType(LogTypeCode.APP_DRESSCATEGORY_BROWSER_ONE);
              ViewHold hold = (ViewHold) v.getTag() ;
              if( (mVisiPosition!=hold.position) ||  (hold.gridLayout.getVisibility()!=View.VISIBLE) ){
                  mPreVisiPosition = mVisiPosition ;
                  mVisiPosition = hold.position ;
                  notifyDataSetChanged() ;
                  //    scrollView(hold, getItem(mVisiPosition), ExpandCollapseAnimation.EXPAND) ;
                  //    mListView.setSelection(mVisiPosition-1) ;
              }else{
                  mPreVisiPosition = mVisiPosition ;
                  mVisiPosition = -1 ;
                  notifyDataSetChanged() ;
                  //    notifyDataSetChanged() ;
              }
          }
      };
  
      /**
       * @param viewHold
       * @param item
       */
      private void scrollView(ViewHold viewHold, IndustryNavigationData item, int scrollType) {
          int childSize = item.getChildren().size() ;
          int row = childSize / 5 ;
          row = childSize%5==0? row:row+1 ;
          LayoutParams lp = viewHold.gridLayout.getLayoutParams() ;
          int heightDip = 37+(row-1)*13 ;
          int heightPx = DisplayUtil.dipToPixel(heightDip)+row*98 ;
          int time = heightPx*2 ;
          lp.height = heightPx ;
          viewHold.gridLayout.setLayoutParams(lp) ;
          viewHold.gridLayout.startAnimation(new ExpandCollapseAnimation(viewHold.gridLayout, time, scrollType, mListView, viewHold.position));
      }
  
  }
  </code></pre>