/**
   * Refreshes the content of the parent list view while maintaining the current vertical position
   * in the list view.
   */
  private void refreshListView(ViewGroup parent, Group updatedGroup) {

    // Get position of first and last visible list items
    AbsListView parentListView = (AbsListView) parent.findViewById(android.R.id.list);
    int firstVisible = parentListView.getFirstVisiblePosition();
    int lastVisible = parentListView.getLastVisiblePosition();

    // Populate list view
    mItems.clear();
    List<Group> groups = Group.getAllSortedByDisplayOrder();
    for (Group group : groups) {
      mItems.add(group.name);
    }
    notifyDataSetChanged();

    // Handle case where item is at visible top and moved up.
    if (firstVisible >= updatedGroup.getDisplayOrder()) {
      parentListView.setSelection(updatedGroup.getDisplayOrder() - 1);
      // Handle case where item is at visible bottom and moved down.
    } else if (lastVisible < updatedGroup.getDisplayOrder()) {
      parentListView.setSelection(firstVisible + 1);
      // Handle move cases in the middle of viewable listview.
    } else {
      parentListView.setSelection(firstVisible);
    }
  }
  /** 重新获取嵌套的内容视图 */
  private void regetNestedContentView() {
    int currentItem = mDirectViewPager.getCurrentItem();
    PagerAdapter adapter = mDirectViewPager.getAdapter();
    if (adapter instanceof FragmentPagerAdapter || adapter instanceof FragmentStatePagerAdapter) {
      Fragment item = (Fragment) adapter.instantiateItem(mDirectViewPager, currentItem);
      mNestedContentView = item.getView();

      // 清空之前的
      mNestedNormalView = null;
      mNestedAbsListView = null;
      mNestedRecyclerView = null;
      mNestedScrollView = null;
      mNestedWebView = null;

      if (mNestedContentView instanceof AbsListView) {
        mNestedAbsListView = (AbsListView) mNestedContentView;
        mNestedAbsListView.setOnScrollListener(mLvOnScrollListener);

        if (!isHeaderViewCompleteInvisible()) {
          mNestedAbsListView.setSelection(0);
        }
      } else if (mNestedContentView instanceof RecyclerView) {
        mNestedRecyclerView = (RecyclerView) mNestedContentView;
        mNestedRecyclerView.removeOnScrollListener(mRvOnScrollListener);
        mNestedRecyclerView.addOnScrollListener(mRvOnScrollListener);

        if (!isHeaderViewCompleteInvisible()) {
          mNestedRecyclerView.scrollToPosition(0);
        }
      } else if (mNestedContentView instanceof ScrollView) {
        mNestedScrollView = (ScrollView) mNestedContentView;

        if (!isHeaderViewCompleteInvisible()) {
          mNestedScrollView.scrollTo(mNestedScrollView.getScrollX(), 0);
        }
      } else if (mNestedContentView instanceof WebView) {
        mNestedWebView = (WebView) mNestedContentView;

        if (!isHeaderViewCompleteInvisible()) {
          mNestedWebView.scrollTo(mNestedWebView.getScrollX(), 0);
        }
      } else {
        mNestedNormalView = mNestedContentView;
      }
    } else {
      throw new IllegalStateException(
          BGAStickyNavLayout.class.getSimpleName()
              + "的第三个子控件为ViewPager时,其adapter必须是FragmentPagerAdapter或者FragmentStatePagerAdapter");
    }
  }
  /**
   * Emulates a directional pad event based on the given flick direction.
   *
   * @param direction A flick direction constant.
   */
  private void changeFocus(int direction) {
    int keyCode = KeyEvent.KEYCODE_UNKNOWN;

    switch (direction) {
      case FlickGestureListener.FLICK_UP:
        keyCode = KeyEvent.KEYCODE_DPAD_UP;
        break;
      case FlickGestureListener.FLICK_RIGHT:
        keyCode = KeyEvent.KEYCODE_DPAD_RIGHT;
        break;
      case FlickGestureListener.FLICK_DOWN:
        keyCode = KeyEvent.KEYCODE_DPAD_DOWN;
        break;
      case FlickGestureListener.FLICK_LEFT:
        keyCode = KeyEvent.KEYCODE_DPAD_LEFT;
        break;
      default:
        // Invalid flick constant.
        return;
    }

    if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
      final int keyCodeFinal = keyCode;

      // Exit from touch mode as gracefully as possible.
      if (mSelectedView != null) {
        ViewParent parent = mSelectedView.getParent();

        mSelectedView.requestFocusFromTouch();

        // If the selected view belongs to a list, make sure it's
        // selected within the list (since it's not focusable).
        // TODO(alanv): Check whether the prior call was successful?
        if (parent instanceof AbsListView) {
          AbsListView listParent = (AbsListView) parent;
          int position = listParent.getPositionForView(mSelectedView);
          listParent.setSelection(position);
        }
      } else {
        requestFocusFromTouch();
      }

      // We have to send the key event on a separate thread, then return
      // to the main thread to synchronize the selected view with focus.
      new Thread() {
        @Override
        public void run() {
          mInstrumentation.sendKeyDownUpSync(keyCodeFinal);

          mHandler.post(
              new Runnable() {
                @Override
                public void run() {
                  View newFocusedView = findFocus();
                  setSelectedView(newFocusedView, false);
                }
              });
        }
      }.start();
    }
  }