List of usage examples for android.view View getWindowToken
public IBinder getWindowToken()
From source file:com.datarita.ultimatecamera.turu.views.TwoWayView.java
private void layoutChildren() { if (getWidth() == 0 || getHeight() == 0) { return;//from w w w . j av a 2 s. co m } final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true; } else { return; } try { invalidate(); if (mAdapter == null) { resetState(); return; } final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight()); int childCount = getChildCount(); int index = 0; int delta = 0; View focusLayoutRestoreView = null; View selected = null; View oldSelected = null; View newSelected = null; View oldFirstChild = null; switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSelected = getChildAt(index); } break; case LAYOUT_FORCE_TOP: case LAYOUT_FORCE_BOTTOM: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSelected = getChildAt(index); } // Remember the previous first child oldFirstChild = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSelected might be null newSelected = getChildAt(index + delta); } final boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetState(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the mAdapter has changed but " + "TwoWayView did not receive a notification. Make sure the content of " + "your mAdapter is not modified from a background thread, but only " + "from the UI thread. [in TwoWayView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Reset the focus restoration View focusLayoutRestoreDirectChild = null; // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // Take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else. final View focusedChild = getFocusedChild(); if (focusedChild != null) { // We can remember the focused view to restore after relayout if the // data hasn't changed, or if the focused position is a header or footer. if (!dataChanged) { focusLayoutRestoreDirectChild = focusedChild; // Remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // Tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // FIXME: We need a way to save current accessibility focus here // so that it can be restored after we re-attach the children on each // layout round. detachAllViewsFromParent(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSelected != null) { final int newSelectedStart = (mIsVertical ? newSelected.getTop() : newSelected.getLeft()); selected = fillFromSelection(newSelectedStart, start, end); } else { selected = fillFromMiddle(start, end); } break; case LAYOUT_SYNC: selected = fillSpecific(mSyncPosition, mSpecificStart); break; case LAYOUT_FORCE_BOTTOM: selected = fillBefore(mItemCount - 1, end); adjustViewsStartOrEnd(); break; case LAYOUT_FORCE_TOP: mFirstPosition = 0; selected = fillFromOffset(start); adjustViewsStartOrEnd(); break; case LAYOUT_SPECIFIC: selected = fillSpecific(reconcileSelectedPosition(), mSpecificStart); break; case LAYOUT_MOVE_SELECTION: selected = moveSelection(oldSelected, newSelected, delta, start, end); break; default: if (childCount == 0) { final int position = lookForSelectablePosition(0); setSelectedPositionInt(position); selected = fillFromOffset(start); } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { int offset = start; if (oldSelected != null) { offset = (mIsVertical ? oldSelected.getTop() : oldSelected.getLeft()); } selected = fillSpecific(mSelectedPosition, offset); } else if (mFirstPosition < mItemCount) { int offset = start; if (oldFirstChild != null) { offset = (mIsVertical ? oldFirstChild.getTop() : oldFirstChild.getLeft()); } selected = fillSpecific(mFirstPosition, offset); } else { selected = fillSpecific(0, start); } } break; } recycleBin.scrapActiveViews(); if (selected != null) { if (mItemsCanFocus && hasFocus() && !selected.hasFocus()) { final boolean focusWasTaken = (selected == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || selected.requestFocus(); if (!focusWasTaken) { // Selected item didn't take focus, fine, but still want // to make sure something else outside of the selected view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, selected); } else { selected.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, selected); } mSelectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_DRAGGING) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) { positionSelector(mMotionPosition, child); } } else { mSelectedStart = 0; mSelectorRect.setEmpty(); } // Even if there is not selected position, we may need to restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // Tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; mDataChanged = false; } } }
From source file:com.boutline.sports.helpers.TwoWayView.java
private void layoutChildren() { if (getWidth() == 0 || getHeight() == 0) { return;//from ww w . j av a2 s . c o m } final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true; } else { return; } try { invalidate(); if (mAdapter == null) { resetState(); return; } final int start = getStartEdge(); final int end = getEndEdge(); int childCount = getChildCount(); int index = 0; int delta = 0; View focusLayoutRestoreView = null; View selected = null; View oldSelected = null; View newSelected = null; View oldFirstChild = null; switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSelected = getChildAt(index); } break; case LAYOUT_FORCE_TOP: case LAYOUT_FORCE_BOTTOM: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSelected = getChildAt(index); } // Remember the previous first child oldFirstChild = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSelected might be null newSelected = getChildAt(index + delta); } final boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetState(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "TwoWayView did not receive a notification. Make sure the content of " + "your adapter is not modified from a background thread, but only " + "from the UI thread. [in TwoWayView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Reset the focus restoration View focusLayoutRestoreDirectChild = null; // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // Take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else. final View focusedChild = getFocusedChild(); if (focusedChild != null) { // We can remember the focused view to restore after relayout if the // data hasn't changed, or if the focused position is a header or footer. if (!dataChanged) { focusLayoutRestoreDirectChild = focusedChild; // Remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // Tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // FIXME: We need a way to save current accessibility focus here // so that it can be restored after we re-attach the children on each // layout round. detachAllViewsFromParent(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSelected != null) { final int newSelectedStart = (mIsVertical ? newSelected.getTop() : newSelected.getLeft()); selected = fillFromSelection(newSelectedStart, start, end); } else { selected = fillFromMiddle(start, end); } break; case LAYOUT_SYNC: selected = fillSpecific(mSyncPosition, mSpecificStart); break; case LAYOUT_FORCE_BOTTOM: selected = fillBefore(mItemCount - 1, end); adjustViewsStartOrEnd(); break; case LAYOUT_FORCE_TOP: mFirstPosition = 0; selected = fillFromOffset(start); adjustViewsStartOrEnd(); break; case LAYOUT_SPECIFIC: selected = fillSpecific(reconcileSelectedPosition(), mSpecificStart); break; case LAYOUT_MOVE_SELECTION: selected = moveSelection(oldSelected, newSelected, delta, start, end); break; default: if (childCount == 0) { final int position = lookForSelectablePosition(0); setSelectedPositionInt(position); selected = fillFromOffset(start); } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { int offset = start; if (oldSelected != null) { offset = (mIsVertical ? oldSelected.getTop() : oldSelected.getLeft()); } selected = fillSpecific(mSelectedPosition, offset); } else if (mFirstPosition < mItemCount) { int offset = start; if (oldFirstChild != null) { offset = (mIsVertical ? oldFirstChild.getTop() : oldFirstChild.getLeft()); } selected = fillSpecific(mFirstPosition, offset); } else { selected = fillSpecific(0, start); } } break; } recycleBin.scrapActiveViews(); if (selected != null) { if (mItemsCanFocus && hasFocus() && !selected.hasFocus()) { final boolean focusWasTaken = (selected == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || selected.requestFocus(); if (!focusWasTaken) { // Selected item didn't take focus, fine, but still want // to make sure something else outside of the selected view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, selected); } else { selected.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, selected); } mSelectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_DRAGGING) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) { positionSelector(mMotionPosition, child); } } else { mSelectedStart = 0; mSelectorRect.setEmpty(); } // Even if there is not selected position, we may need to restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // Tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; mDataChanged = false; } } }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private void layoutChildren() { if (getWidth() == 0 || getHeight() == 0) { return;//w w w .ja va 2 s . c om } final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true; } else { return; } try { invalidate(); if (mAdapter == null) { resetState(); return; } final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight()); int childCount = getChildCount(); int index = 0; int delta = 0; View focusLayoutRestoreView = null; View selected = null; View oldSelected = null; View newSelected = null; View oldFirstChild = null; switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSelected = getChildAt(index); } break; case LAYOUT_FORCE_TOP: case LAYOUT_FORCE_BOTTOM: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSelected = getChildAt(index); } // Remember the previous first child oldFirstChild = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSelected might be null newSelected = getChildAt(index + delta); } final boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetState(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "TwoWayView did not receive a notification. Make sure the content of " + "your adapter is not modified from a background thread, but only " + "from the UI thread. [in TwoWayView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Reset the focus restoration View focusLayoutRestoreDirectChild = null; // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // Take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else. final View focusedChild = getFocusedChild(); if (focusedChild != null) { // We can remember the focused view to restore after relayout if the // data hasn't changed, or if the focused position is a header or footer. if (!dataChanged) { focusLayoutRestoreDirectChild = focusedChild; // Remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // Tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // FIXME: We need a way to save current accessibility focus here // so that it can be restored after we re-attach the children on each // layout round. detachAllViewsFromParent(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSelected != null) { final int newSelectedStart = (mIsVertical ? newSelected.getTop() : newSelected.getLeft()); selected = fillFromSelection(newSelectedStart, start, end); } else { selected = fillFromMiddle(start, end); } break; case LAYOUT_SYNC: selected = fillSpecific(mSyncPosition, mSpecificStart); break; case LAYOUT_FORCE_BOTTOM: selected = fillBefore(mItemCount - 1, end); adjustViewsStartOrEnd(); break; case LAYOUT_FORCE_TOP: mFirstPosition = 0; selected = fillFromOffset(start); adjustViewsStartOrEnd(); break; case LAYOUT_SPECIFIC: selected = fillSpecific(reconcileSelectedPosition(), mSpecificStart); break; case LAYOUT_MOVE_SELECTION: selected = moveSelection(oldSelected, newSelected, delta, start, end); break; default: if (childCount == 0) { final int position = lookForSelectablePosition(0); setSelectedPositionInt(position); selected = fillFromOffset(start); } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { int offset = start; if (oldSelected != null) { offset = (mIsVertical ? oldSelected.getTop() : oldSelected.getLeft()); } selected = fillSpecific(mSelectedPosition, offset); } else if (mFirstPosition < mItemCount) { int offset = start; if (oldFirstChild != null) { offset = (mIsVertical ? oldFirstChild.getTop() : oldFirstChild.getLeft()); } selected = fillSpecific(mFirstPosition, offset); } else { selected = fillSpecific(0, start); } } break; } recycleBin.scrapActiveViews(); if (selected != null) { if (mItemsCanFocus && hasFocus() && !selected.hasFocus()) { final boolean focusWasTaken = (selected == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || selected.requestFocus(); if (!focusWasTaken) { // Selected item didn't take focus, fine, but still want // to make sure something else outside of the selected view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, selected); } else { selected.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, selected); } mSelectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_DRAGGING) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) { positionSelector(mMotionPosition, child); } } else { mSelectedStart = 0; mSelectorRect.setEmpty(); } // Even if there is not selected position, we may need to restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // Tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; mDataChanged = false; } } }
From source file:com.artifex.mupdf.view.ThumbnailViews.java
private void layoutChildren() { if (getWidth() == 0 || getHeight() == 0) { return;/*from w ww . j a va2 s. c o m*/ } final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true; } else { return; } try { invalidate(); if (mAdapter == null) { resetState(); return; } final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight()); int childCount = getChildCount(); int index = 0; int delta = 0; View focusLayoutRestoreView = null; View selected = null; View oldSelected = null; View newSelected = null; View oldFirstChild = null; switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSelected = getChildAt(index); } break; case LAYOUT_FORCE_TOP: case LAYOUT_FORCE_BOTTOM: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSelected = getChildAt(index); } // Remember the previous first child oldFirstChild = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSelected might be null newSelected = getChildAt(index + delta); } final boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetState(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "TwoWayView did not receive a notification. Make sure the content of " + "your adapter is not modified from a background thread, but only " + "from the UI thread. [in TwoWayView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Reset the focus restoration View focusLayoutRestoreDirectChild = null; // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // Take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else. final View focusedChild = getFocusedChild(); if (focusedChild != null) { // We can remember the focused view to restore after relayout if // the // data hasn't changed, or if the focused position is a header // or footer. if (!dataChanged) { focusLayoutRestoreDirectChild = focusedChild; // Remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // Tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // FIXME: We need a way to save current accessibility focus here // so that it can be restored after we re-attach the children on // each // layout round. detachAllViewsFromParent(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSelected != null) { final int newSelectedStart = (mIsVertical ? newSelected.getTop() : newSelected.getLeft()); selected = fillFromSelection(newSelectedStart, start, end); } else { selected = fillFromMiddle(start, end); } break; case LAYOUT_SYNC: selected = fillSpecific(mSyncPosition, mSpecificStart); break; case LAYOUT_FORCE_BOTTOM: selected = fillBefore(mItemCount - 1, end); adjustViewsStartOrEnd(); break; case LAYOUT_FORCE_TOP: mFirstPosition = 0; selected = fillFromOffset(start); adjustViewsStartOrEnd(); break; case LAYOUT_SPECIFIC: selected = fillSpecific(reconcileSelectedPosition(), mSpecificStart); break; case LAYOUT_MOVE_SELECTION: selected = moveSelection(oldSelected, newSelected, delta, start, end); break; default: if (childCount == 0) { final int position = lookForSelectablePosition(0); setSelectedPositionInt(position); selected = fillFromOffset(start); } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { int offset = start; if (oldSelected != null) { offset = (mIsVertical ? oldSelected.getTop() : oldSelected.getLeft()); } selected = fillSpecific(mSelectedPosition, offset); } else if (mFirstPosition < mItemCount) { int offset = start; if (oldFirstChild != null) { offset = (mIsVertical ? oldFirstChild.getTop() : oldFirstChild.getLeft()); } selected = fillSpecific(mFirstPosition, offset); } else { selected = fillSpecific(0, start); } } break; } recycleBin.scrapActiveViews(); if (selected != null) { if (mItemsCanFocus && hasFocus() && !selected.hasFocus()) { final boolean focusWasTaken = (selected == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || selected.requestFocus(); if (!focusWasTaken) { // Selected item didn't take focus, fine, but still want // to make sure something else outside of the selected // view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, selected); } else { selected.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, selected); } mSelectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_DRAGGING) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) { positionSelector(mMotionPosition, child); } } else { mSelectedStart = 0; mSelectorRect.setEmpty(); } // Even if there is not selected position, we may need to // restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // Tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; mDataChanged = false; } } }
From source file:com.appunite.list.ListView.java
@Override protected void layoutChildren() { final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true;// w w w . j a v a 2s.c om } else { return; } try { super.layoutChildren(); invalidate(); if (mAdapter == null) { resetList(); invokeOnItemScrollListener(); return; } int childrenTop = mListPadding.top; int childrenBottom = getBottom() - getTop() - mListPadding.bottom; int childCount = getChildCount(); int index = 0; int delta = 0; View sel; View oldSel = null; View oldFirst = null; View newSel = null; View focusLayoutRestoreView = null; AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null; View accessibilityFocusLayoutRestoreView = null; int accessibilityFocusPosition = INVALID_POSITION; // Remember stuff we will need down below switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSel = getChildAt(index); } break; case LAYOUT_FORCE_TOP: case LAYOUT_FORCE_BOTTOM: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSel = getChildAt(index); } // Remember the previous first child oldFirst = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSel might be null newSel = getChildAt(index + delta); } boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetList(); invokeOnItemScrollListener(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "ListView did not receive a notification. Make sure the content of " + "your adapter is not modified from a background thread, but only " + "from the UI thread. [in ListView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; // reset the focus restoration View focusLayoutRestoreDirectChild = null; // Don't put header or footer views into the Recycler. Those are // already cached in mHeaderViews; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else final View focusedChild = getFocusedChild(); if (focusedChild != null) { // TODO: in some cases focusedChild.getParent() == null // we can remember the focused view to restore after relayout if the // data hasn't changed, or if the focused position is a header or footer if (!dataChanged || isDirectChildHeaderOrFooter(focusedChild)) { focusLayoutRestoreDirectChild = focusedChild; // remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // TODO We can use those accessability methods, we just remove those (j.m.) // //Remember which child, if any, had accessibility focus. // final ViewRootImpl viewRootImpl = getViewRootImpl(); // if (viewRootImpl != null) { // final View accessFocusedView = viewRootImpl.getAccessibilityFocusedHost(); // if (accessFocusedView != null) { // final View accessFocusedChild = findAccessibilityFocusedChild( // accessFocusedView); // if (accessFocusedChild != null) { // if (!dataChanged || isDirectChildHeaderOrFooter(accessFocusedChild)) { // // If the views won't be changing, try to maintain // // focus on the current view host and (if // // applicable) its virtual view. // accessibilityFocusLayoutRestoreView = accessFocusedView; // accessibilityFocusLayoutRestoreNode = viewRootImpl // .getAccessibilityFocusedVirtualView(); // } else { // // Otherwise, try to maintain focus at the same // // position. // accessibilityFocusPosition = getPositionForView(accessFocusedChild); // } // } // } // } // Clear out old views detachAllViewsFromParent(); recycleBin.removeSkippedScrap(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSel != null) { sel = fillFromSelection(newSel.getTop(), childrenTop, childrenBottom); } else { sel = fillFromMiddle(childrenTop, childrenBottom); } break; case LAYOUT_SYNC: sel = fillSpecific(mSyncPosition, mSpecificTop); break; case LAYOUT_FORCE_BOTTOM: sel = fillUp(mItemCount - 1, childrenBottom); adjustViewsUpOrDown(); break; case LAYOUT_FORCE_TOP: mFirstPosition = 0; sel = fillFromTop(childrenTop); adjustViewsUpOrDown(); break; case LAYOUT_SPECIFIC: sel = fillSpecific(reconcileSelectedPosition(), mSpecificTop); break; case LAYOUT_MOVE_SELECTION: sel = moveSelection(oldSel, newSel, delta, childrenTop, childrenBottom); break; default: if (childCount == 0) { if (!mStackFromBottom) { final int position = lookForSelectablePosition(0, true); setSelectedPositionInt(position); sel = fillFromTop(childrenTop); } else { final int position = lookForSelectablePosition(mItemCount - 1, false); setSelectedPositionInt(position); sel = fillUp(mItemCount - 1, childrenBottom); } } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { sel = fillSpecific(mSelectedPosition, oldSel == null ? childrenTop : oldSel.getTop()); } else if (mFirstPosition < mItemCount) { sel = fillSpecific(mFirstPosition, oldFirst == null ? childrenTop : oldFirst.getTop()); } else { sel = fillSpecific(0, childrenTop); } } break; } // Flush any cached views that did not get reused above recycleBin.scrapActiveViews(); if (sel != null) { // the current selected item should get focus if items // are focusable if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) { final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || sel.requestFocus(); if (!focusWasTaken) { // selected item didn't take focus, fine, but still want // to make sure something else outside of the selected view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, sel); } else { sel.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, sel); } mSelectedTop = sel.getTop(); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) positionSelector(mMotionPosition, child); } else { mSelectedTop = 0; mSelectorRect.setEmpty(); } // even if there is not selected position, we may need to restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // TODO We can use those accessability methods, we just remove those (j.m.) // // Attempt to restore accessibility focus. // if (accessibilityFocusLayoutRestoreNode != null) { // accessibilityFocusLayoutRestoreNode.performAction( // AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); // } else if (accessibilityFocusLayoutRestoreView != null) { // accessibilityFocusLayoutRestoreView.requestAccessibilityFocus(); // } else if (accessibilityFocusPosition != INVALID_POSITION) { // // Bound the position within the visible children. // final int position = MathUtils.constrain( // (accessibilityFocusPosition - mFirstPosition), 0, (getChildCount() - 1)); // final View restoreView = getChildAt(position); // if (restoreView != null) { // restoreView.requestAccessibilityFocus(); // } // } // tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; if (mPositionScrollAfterLayout != null) { post(mPositionScrollAfterLayout); mPositionScrollAfterLayout = null; } mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); updateScrollIndicators(); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; } } }
From source file:com.appunite.list.HorizontalListView.java
@Override protected void layoutChildren() { final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true;/*w w w.j a va 2 s .com*/ } else { return; } try { super.layoutChildren(); invalidate(); if (mAdapter == null) { resetList(); invokeOnItemScrollListener(); return; } int childrenLeft = mListPadding.left; int childrenRight = getRight() - getLeft() - mListPadding.right; int childCount = getChildCount(); int index = 0; int delta = 0; View sel; View oldSel = null; View oldFirst = null; View newSel = null; View focusLayoutRestoreView = null; AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null; View accessibilityFocusLayoutRestoreView = null; int accessibilityFocusPosition = INVALID_POSITION; // Remember stuff we will need down below switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSel = getChildAt(index); } break; case LAYOUT_FORCE_LEFT: case LAYOUT_FORCE_RIGHT: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSel = getChildAt(index); } // Remember the previous first child oldFirst = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSel might be null newSel = getChildAt(index + delta); } boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetList(); invokeOnItemScrollListener(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "ListView did not receive a notification. Make sure the content of " + "your adapter is not modified from a background thread, but only " + "from the UI thread. [in ListView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; // reset the focus restoration View focusLayoutRestoreDirectChild = null; // Don't put header or footer views into the Recycler. Those are // already cached in mHeaderViews; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else final View focusedChild = getFocusedChild(); if (focusedChild != null) { // TODO: in some cases focusedChild.getParent() == null // we can remember the focused view to restore after relayout if the // data hasn't changed, or if the focused position is a header or footer if (!dataChanged || isDirectChildHeaderOrFooter(focusedChild)) { focusLayoutRestoreDirectChild = focusedChild; // remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // TODO We can use those accessability methods, we just remove those (j.m.) // //Remember which child, if any, had accessibility focus. // final ViewRootImpl viewRootImpl = getViewRootImpl(); // if (viewRootImpl != null) { // final View accessFocusedView = viewRootImpl.getAccessibilityFocusedHost(); // if (accessFocusedView != null) { // final View accessFocusedChild = findAccessibilityFocusedChild( // accessFocusedView); // if (accessFocusedChild != null) { // if (!dataChanged || isDirectChildHeaderOrFooter(accessFocusedChild)) { // // If the views won't be changing, try to maintain // // focus on the current view host and (if // // applicable) its virtual view. // accessibilityFocusLayoutRestoreView = accessFocusedView; // accessibilityFocusLayoutRestoreNode = viewRootImpl // .getAccessibilityFocusedVirtualView(); // } else { // // Otherwise, try to maintain focus at the same // // position. // accessibilityFocusPosition = getPositionForView(accessFocusedChild); // } // } // } // } // Clear out old views detachAllViewsFromParent(); recycleBin.removeSkippedScrap(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSel != null) { sel = fillFromSelection(newSel.getLeft(), childrenLeft, childrenRight); } else { sel = fillFromMiddle(childrenLeft, childrenRight); } break; case LAYOUT_SYNC: sel = fillSpecific(mSyncPosition, mSpecificLeft); break; case LAYOUT_FORCE_RIGHT: sel = fillLeft(mItemCount - 1, childrenRight); adjustViewsLeftOrRight(); break; case LAYOUT_FORCE_LEFT: mFirstPosition = 0; sel = fillFromLeft(childrenLeft); adjustViewsLeftOrRight(); break; case LAYOUT_SPECIFIC: sel = fillSpecific(reconcileSelectedPosition(), mSpecificLeft); break; case LAYOUT_MOVE_SELECTION: sel = moveSelection(oldSel, newSel, delta, childrenLeft, childrenRight); break; default: if (childCount == 0) { if (!mStackFromRight) { final int position = lookForSelectablePosition(0, true); setSelectedPositionInt(position); sel = fillFromLeft(childrenLeft); } else { final int position = lookForSelectablePosition(mItemCount - 1, false); setSelectedPositionInt(position); sel = fillLeft(mItemCount - 1, childrenRight); } } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { sel = fillSpecific(mSelectedPosition, oldSel == null ? childrenLeft : oldSel.getLeft()); } else if (mFirstPosition < mItemCount) { sel = fillSpecific(mFirstPosition, oldFirst == null ? childrenLeft : oldFirst.getLeft()); } else { sel = fillSpecific(0, childrenLeft); } } break; } // Flush any cached views that did not get reused above recycleBin.scrapActiveViews(); if (sel != null) { // the current selected item should get focus if items // are focusable if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) { final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || sel.requestFocus(); if (!focusWasTaken) { // selected item didn't take focus, fine, but still want // to make sure something else outside of the selected view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, sel); } else { sel.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, sel); } mSelectedLeft = sel.getLeft(); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) positionSelector(mMotionPosition, child); } else { mSelectedLeft = 0; mSelectorRect.setEmpty(); } // even if there is not selected position, we may need to restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // TODO We can use those accessability methods, we just remove those (j.m.) // // Attempt to restore accessibility focus. // if (accessibilityFocusLayoutRestoreNode != null) { // accessibilityFocusLayoutRestoreNode.performAction( // AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); // } else if (accessibilityFocusLayoutRestoreView != null) { // accessibilityFocusLayoutRestoreView.requestAccessibilityFocus(); // } else if (accessibilityFocusPosition != INVALID_POSITION) { // // Bound the position within the visible children. // final int position = MathUtils.constrain( // (accessibilityFocusPosition - mFirstPosition), 0, (getChildCount() - 1)); // final View restoreView = getChildAt(position); // if (restoreView != null) { // restoreView.requestAccessibilityFocus(); // } // } // tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; if (mPositionScrollAfterLayout != null) { post(mPositionScrollAfterLayout); mPositionScrollAfterLayout = null; } mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); updateScrollIndicators(); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; } } }
From source file:com.artifex.mupdflib.TwoWayView.java
private void layoutChildren() { if (getWidth() == 0 || getHeight() == 0) { return;/* w ww. ja va2 s . co m*/ } final boolean blockLayoutRequests = mBlockLayoutRequests; if (!blockLayoutRequests) { mBlockLayoutRequests = true; } else { return; } try { invalidate(); if (mAdapter == null) { resetState(); return; } final int start = getStartEdge(); final int end = getEndEdge(); int childCount = getChildCount(); int index = 0; int delta = 0; View focusLayoutRestoreView = null; View selected = null; View oldSelected = null; View newSelected = null; View oldFirstChild = null; switch (mLayoutMode) { case LAYOUT_SET_SELECTION: index = mNextSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { newSelected = getChildAt(index); } break; case LAYOUT_FORCE_TOP: case LAYOUT_FORCE_BOTTOM: case LAYOUT_SPECIFIC: case LAYOUT_SYNC: break; case LAYOUT_MOVE_SELECTION: default: // Remember the previously selected view index = mSelectedPosition - mFirstPosition; if (index >= 0 && index < childCount) { oldSelected = getChildAt(index); } // Remember the previous first child oldFirstChild = getChildAt(0); if (mNextSelectedPosition >= 0) { delta = mNextSelectedPosition - mSelectedPosition; } // Caution: newSelected might be null newSelected = getChildAt(index + delta); } final boolean dataChanged = mDataChanged; if (dataChanged) { handleDataChanged(); } // Handle the empty set by removing all views that are visible // and calling it a day if (mItemCount == 0) { resetState(); return; } else if (mItemCount != mAdapter.getCount()) { throw new IllegalStateException("The content of the adapter has changed but " + "TwoWayView did not receive a notification. Make sure the content of " + "your adapter is not modified from a background thread, but only " + "from the UI thread. [in TwoWayView(" + getId() + ", " + getClass() + ") with Adapter(" + mAdapter.getClass() + ")]"); } setSelectedPositionInt(mNextSelectedPosition); // Reset the focus restoration View focusLayoutRestoreDirectChild = null; // Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition + i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); } // Take focus back to us temporarily to avoid the eventual // call to clear focus when removing the focused child below // from messing things up when ViewAncestor assigns focus back // to someone else. final View focusedChild = getFocusedChild(); if (focusedChild != null) { // We can remember the focused view to restore after relayout if the // data hasn't changed, or if the focused position is a header or footer. if (!dataChanged) { focusLayoutRestoreDirectChild = focusedChild; // Remember the specific view that had focus focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // Tell it we are going to mess with it focusLayoutRestoreView.onStartTemporaryDetach(); } } requestFocus(); } // FIXME: We need a way to save current accessibility focus here // so that it can be restored after we re-attach the children on each // layout round. detachAllViewsFromParent(); switch (mLayoutMode) { case LAYOUT_SET_SELECTION: if (newSelected != null) { final int newSelectedStart = getChildStartEdge(newSelected); selected = fillFromSelection(newSelectedStart, start, end); } else { selected = fillFromMiddle(start, end); } break; case LAYOUT_SYNC: selected = fillSpecific(mSyncPosition, mSpecificStart); break; case LAYOUT_FORCE_BOTTOM: selected = fillBefore(mItemCount - 1, end); adjustViewsStartOrEnd(); break; case LAYOUT_FORCE_TOP: mFirstPosition = 0; selected = fillFromOffset(start); adjustViewsStartOrEnd(); break; case LAYOUT_SPECIFIC: selected = fillSpecific(reconcileSelectedPosition(), mSpecificStart); break; case LAYOUT_MOVE_SELECTION: selected = moveSelection(oldSelected, newSelected, delta, start, end); break; default: if (childCount == 0) { final int position = lookForSelectablePosition(0); setSelectedPositionInt(position); selected = fillFromOffset(start); } else { if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { int offset = start; if (oldSelected != null) { offset = getChildStartEdge(oldSelected); } selected = fillSpecific(mSelectedPosition, offset); } else if (mFirstPosition < mItemCount) { int offset = start; if (oldFirstChild != null) { offset = getChildStartEdge(oldFirstChild); } selected = fillSpecific(mFirstPosition, offset); } else { selected = fillSpecific(0, start); } } break; } recycleBin.scrapActiveViews(); if (selected != null) { if (mItemsCanFocus && hasFocus() && !selected.hasFocus()) { final boolean focusWasTaken = (selected == focusLayoutRestoreDirectChild && focusLayoutRestoreView != null && focusLayoutRestoreView.requestFocus()) || selected.requestFocus(); if (!focusWasTaken) { // Selected item didn't take focus, fine, but still want // to make sure something else outside of the selected view // has focus final View focused = getFocusedChild(); if (focused != null) { focused.clearFocus(); } positionSelector(INVALID_POSITION, selected); } else { selected.setSelected(false); mSelectorRect.setEmpty(); } } else { positionSelector(INVALID_POSITION, selected); } mSelectedStart = getChildStartEdge(selected); } else { if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_DRAGGING) { View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) { positionSelector(mMotionPosition, child); } } else { mSelectedStart = 0; mSelectorRect.setEmpty(); } // Even if there is not selected position, we may need to restore // focus (i.e. something focusable in touch mode) if (hasFocus() && focusLayoutRestoreView != null) { focusLayoutRestoreView.requestFocus(); } } // Tell focus view we are done mucking with it, if it is still in // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { focusLayoutRestoreView.onFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; mDataChanged = false; mNeedSync = false; setNextSelectedPositionInt(mSelectedPosition); if (mItemCount > 0) { checkSelectionChanged(); } invokeOnItemScrollListener(); } finally { if (!blockLayoutRequests) { mBlockLayoutRequests = false; mDataChanged = false; } } }