private void attachAdapter() {
    if (getHeight() == 0) {
      // try again!
      setAdapter(mAdapter);
      return;
    }

    final int itemCount = mAdapter.getCount();
    int itemGroup = mAdapter.getItemsCountPerGroup();
    if (itemGroup < 3) {
      itemGroup = 3;
    }

    final float height = getHeight();

    final int itemHeight = (int) (height / itemGroup);
    int additionHeight = (int) (height - itemHeight * itemGroup);

    int itemPosition = 0;
    final int totalItems = itemCount + 2;

    for (int i = 0; i < totalItems; i++) {

      if (i == 0 || i == totalItems - 1) {
        TextView tv = (i == 0 ? mStartBlankView : mEndBlankView);
        mItemLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        mItemLayoutParams.height = (--additionHeight >= 0) ? itemHeight + 1 : itemHeight;
        tv.setLayoutParams(mItemLayoutParams);
        mItemsContainer.addView(tv);
      } else {
        View convertView = null;
        boolean isCached = true;
        if (itemPosition < mCachedSubViewList.size()) {
          convertView = mCachedSubViewList.get(itemPosition);
        } else {
          isCached = false;
        }

        View view = mAdapter.getView(itemPosition, convertView, this);
        view.setId(mAdapter.getItemId(itemPosition));
        mItemLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        mItemLayoutParams.height = (--additionHeight >= 0) ? itemHeight + 1 : itemHeight;
        view.setLayoutParams(mItemLayoutParams);
        mItemsContainer.addView(view);

        if (!isCached) {
          mCachedSubViewList.add(itemPosition, view);
        } else {
          if (view != convertView) {
            mCachedSubViewList.remove(itemPosition);
            mCachedSubViewList.add(itemPosition, view);
          }
        }
        itemPosition++;
      }
    }
  }
  private void initItemViewsScrollYArr() {
    if (mAdapter == null || mAdapter.getCount() < 1) {
      return;
    }
    if (mItemViewsScrollYArr == null) {
      int maxY = getMaxScrollY();

      final int itemsCount = mAdapter.getCount();
      mItemViewsScrollYArr = new int[itemsCount];
      mItemViewsScrollYArr[0] = 0;
      mItemViewsScrollYArr[itemsCount - 1] = maxY;

      for (int i = 0; i < itemsCount - 2; i++) {
        mItemViewsScrollYArr[i + 1] = (int) (1f * (i + 1) * maxY / (itemsCount - 1));
      }
    }
  }
 /**
  * Sets the currently selected item.
  *
  * @param position
  */
 public void setSelection(final int position) {
   if (mAdapter == null || mAdapter.getCount() < 1) {
     throw new NullPointerException("Currently no items!");
   }
   if (position < 0 || position >= mAdapter.getCount()) {
     throw new IllegalArgumentException("Position out of index");
   }
   if (mContentScrollView.getHeight() == 0) {
     mContentScrollView.postDelayed(
         new Runnable() {
           @Override
           public void run() {
             setNextSelectedPositionInt(position);
           }
         },
         1);
   } else {
     setNextSelectedPositionInt(position);
   }
 }
  private void setNextSelectedPositionInt(int position) {
    if (mContentScrollView.getHeight() == 0) {
      setSelection(position);
      return;
    }

    mSelectedPosition = position;

    initItemViewsScrollYArr();
    mContentScrollView.scrollTo(
        mContentScrollView.getScrollX(), mItemViewsScrollYArr[mSelectedPosition]);
    if (mOnItemSelectedListener != null) {
      mOnItemSelectedListener.onItemSelected(
          this,
          mCachedSubViewList.get(mSelectedPosition),
          mSelectedPosition,
          mAdapter.getItemId(mSelectedPosition));
    }
  }
  /**
   * Sets the data behind this VerticalScrollAutoSelector.
   *
   * @param adapter
   */
  public void setAdapter(AutoSelectorAdapter adapter) {
    mAdapter = adapter;
    mSelectedPosition = -1;
    mItemViewsScrollYArr = null;
    mItemsContainer.removeAllViews();
    if (mAdapter == null || mAdapter.getCount() <= 0) {
      return;
    }

    if (getHeight() == 0) {
      // Waiting for component initialization finished
      postDelayed(
          new Thread() {
            @Override
            public void run() {
              attachAdapter();
            }
          },
          1);
    } else {
      attachAdapter();
    }
  }
 /**
  * Get the selected item.
  *
  * @return
  */
 public Object getSelectedItem() {
   if (mAdapter == null || mSelectedPosition < 0) return null;
   return mAdapter.getItem(mSelectedPosition);
 }