/** * 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(); } }