Example usage for android.view View onFinishTemporaryDetach

List of usage examples for android.view View onFinishTemporaryDetach

Introduction

In this page you can find the example usage for android.view View onFinishTemporaryDetach.

Prototype

public void onFinishTemporaryDetach() 

Source Link

Document

Called after #onStartTemporaryDetach when the container is done changing the view.

Usage

From source file:com.example.libwidgettv.bak.AbsListView.java

/**
 * Get a view and have it show the data associated with the specified
 * position. This is called when we have already discovered that the view is
 * not available for reuse in the recycle bin. The only choices left are
 * converting an old view or making a new one.
 * /* w w w . j a v  a  2  s.  c o m*/
 * @param position
 *            The position to display
 * @param isScrap
 *            Array of at least 1 boolean, the first entry will become true
 *            if the returned view was taken from the scrap heap, false if
 *            otherwise.
 * 
 * @return A view displaying the data associated with the specified position
 */
View obtainView(int position, boolean[] isScrap) {
    isScrap[0] = false;
    View scrapView;

    scrapView = mRecycler.getScrapView(position);

    View child;
    if (scrapView != null) {
        if (ViewDebug.TRACE_RECYCLER) {
            ViewDebug.trace(scrapView, ViewDebug.RecyclerTraceType.RECYCLE_FROM_SCRAP_HEAP, position, -1);
        }

        child = mAdapter.getView(position, scrapView, this);

        if (ViewDebug.TRACE_RECYCLER) {
            ViewDebug.trace(child, ViewDebug.RecyclerTraceType.BIND_VIEW, position, getChildCount());
        }

        if (child != scrapView) {
            mRecycler.addScrapView(scrapView, position);
            if (mCacheColorHint != 0) {
                child.setDrawingCacheBackgroundColor(mCacheColorHint);
            }
            if (ViewDebug.TRACE_RECYCLER) {
                ViewDebug.trace(scrapView, ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP, position, -1);
            }
        } else {
            isScrap[0] = true;
            // child.dispatchFinishTemporaryDetach();
            child.onFinishTemporaryDetach();
        }
    } else {
        child = mAdapter.getView(position, null, this);
        if (mCacheColorHint != 0) {
            child.setDrawingCacheBackgroundColor(mCacheColorHint);
        }
        if (ViewDebug.TRACE_RECYCLER) {
            ViewDebug.trace(child, ViewDebug.RecyclerTraceType.NEW_VIEW, position, getChildCount());
        }
    }

    return child;
}

From source file:com.huewu.pla.lib.internal.PLAListView.java

@SuppressWarnings("deprecation")
@Override/*from w ww .java  2  s  .  c  o m*/
protected void layoutChildren() {
    final boolean blockLayoutRequests = mBlockLayoutRequests;
    if (!blockLayoutRequests) {
        mBlockLayoutRequests = true;
    } else
        return;

    try {
        super.layoutChildren();
        invalidate();
        if (mAdapter == null) {
            resetList();
            invokeOnItemScrollListener();
            return;
        }

        final int childrenTop = mListPadding.top;
        // int childrenBottom = mBottom - mTop - mListPadding.bottom;
        final int childrenBottom = getBottom() - getTop() - mListPadding.bottom;

        final int childCount = getChildCount();
        final int index = 0;

        View oldFirst = null;
        View focusLayoutRestoreView = null;

        // Remember stuff we will need down below
        switch (mLayoutMode) {
        case LAYOUT_FORCE_TOP:
        case LAYOUT_FORCE_BOTTOM:
        case LAYOUT_SPECIFIC:
        case LAYOUT_SYNC:
            break;
        default:
            // Remember the previous first child
            oldFirst = getChildAt(0);
        }

        final boolean dataChanged = mDataChanged;
        if (dataChanged) {
            handleDataChangedPLA();
        }

        // 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() + ")]");

        // 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

        // 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));
                if (ViewDebug.TRACE_RECYCLER) {
                    ViewDebug.trace(getChildAt(i), ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP, index, 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 ViewRoot 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)) {
                // remember the specific view that had focus
                focusLayoutRestoreView = findFocus();
                if (focusLayoutRestoreView != null) {
                    // tell it we are going to mess with it
                    focusLayoutRestoreView.onStartTemporaryDetach();
                }
            }
            requestFocus();
        }

        switch (mLayoutMode) {
        case LAYOUT_SYNC:
            onLayoutSync(mSyncPosition);
            // Clear out old views
            detachAllViewsFromParent();
            fillSpecific(mSyncPosition, mSpecificTop);
            onLayoutSyncFinished(mSyncPosition);
            break;
        case LAYOUT_FORCE_BOTTOM:
            detachAllViewsFromParent();
            fillUp(mItemCount - 1, childrenBottom);
            adjustViewsUpOrDown();
            break;
        case LAYOUT_FORCE_TOP:
            detachAllViewsFromParent();
            mFirstPosition = 0;
            fillFromTop(childrenTop);
            adjustViewsUpOrDown();
            break;
        default:
            if (childCount == 0) {
                detachAllViewsFromParent();
                if (!mStackFromBottom) {
                    fillFromTop(childrenTop);
                } else {
                    fillUp(mItemCount - 1, childrenBottom);
                }
            } else {
                if (mFirstPosition < mItemCount) {
                    onLayoutSync(mFirstPosition);
                    detachAllViewsFromParent();
                    fillSpecific(mFirstPosition, oldFirst == null ? childrenTop : oldFirst.getTop());
                    onLayoutSyncFinished(mFirstPosition);
                } else {
                    onLayoutSync(0);
                    detachAllViewsFromParent();
                    fillSpecific(0, childrenTop);
                    onLayoutSyncFinished(0);
                }
            }
            break;
        }

        // Flush any cached views that did not get reused above
        recycleBin.scrapActiveViews();

        if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
            final View child = getChildAt(mMotionPosition - mFirstPosition);
            if (child != null) {
                positionSelector(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();
        }

        // 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;

        invokeOnItemScrollListener();
    } finally {
        if (!blockLayoutRequests) {
            mBlockLayoutRequests = false;
        }
    }
}

From source file:com.huewu.pla.lib.internal.PLA_ListView.java

@SuppressWarnings("deprecation")
@Override//from  w  w w .j a  v a  2 s.  c o  m
protected void layoutChildren() {
    final boolean blockLayoutRequests = mBlockLayoutRequests;
    if (!blockLayoutRequests) {
        mBlockLayoutRequests = true;
    } else {
        return;
    }

    try {
        super.layoutChildren();
        invalidate();
        if (mAdapter == null) {
            resetList();
            invokeOnItemScrollListener();
            return;
        }

        int childrenTop = mListPadding.top;
        // int childrenBottom = mBottom - mTop - mListPadding.bottom;
        int childrenBottom = getBottom() - getTop() - mListPadding.bottom;

        int childCount = getChildCount();
        int index = 0;

        View oldFirst = null;
        View focusLayoutRestoreView = null;

        // Remember stuff we will need down below
        switch (mLayoutMode) {
        case LAYOUT_FORCE_TOP:
        case LAYOUT_FORCE_BOTTOM:
        case LAYOUT_SPECIFIC:
        case LAYOUT_SYNC:
            break;
        default:
            // Remember the previous first child
            oldFirst = getChildAt(0);
        }

        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() + ")]");
        }

        // 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

        // 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));
                if (ViewDebug.TRACE_RECYCLER) {
                    ViewDebug.trace(getChildAt(i), ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP, index, 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 ViewRoot 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)) {
                // remember the specific view that had focus
                focusLayoutRestoreView = findFocus();
                if (focusLayoutRestoreView != null) {
                    // tell it we are going to mess with it
                    focusLayoutRestoreView.onStartTemporaryDetach();
                }
            }
            requestFocus();
        }

        switch (mLayoutMode) {
        case LAYOUT_SYNC:
            onLayoutSync(mSyncPosition);
            // Clear out old views
            detachAllViewsFromParent();
            fillSpecific(mSyncPosition, mSpecificTop);
            onLayoutSyncFinished(mSyncPosition);
            break;
        case LAYOUT_FORCE_BOTTOM:
            detachAllViewsFromParent();
            fillUp(mItemCount - 1, childrenBottom);
            adjustViewsUpOrDown();
            break;
        case LAYOUT_FORCE_TOP:
            detachAllViewsFromParent();
            mFirstPosition = 0;
            fillFromTop(childrenTop);
            adjustViewsUpOrDown();
            break;
        default:
            if (childCount == 0) {
                detachAllViewsFromParent();
                if (!mStackFromBottom) {
                    fillFromTop(childrenTop);
                } else {
                    fillUp(mItemCount - 1, childrenBottom);
                }
            } else {
                if (mFirstPosition < mItemCount) {
                    onLayoutSync(mFirstPosition);
                    detachAllViewsFromParent();
                    fillSpecific(mFirstPosition, oldFirst == null ? childrenTop : oldFirst.getTop());
                    onLayoutSyncFinished(mFirstPosition);
                } else {
                    onLayoutSync(0);
                    detachAllViewsFromParent();
                    fillSpecific(0, childrenTop);
                    onLayoutSyncFinished(0);
                }
            }
            break;
        }

        // Flush any cached views that did not get reused above
        recycleBin.scrapActiveViews();

        if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
            View child = getChildAt(mMotionPosition - mFirstPosition);
            if (child != null)
                positionSelector(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();
        }

        // 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;

        invokeOnItemScrollListener();
    } finally {
        if (!blockLayoutRequests) {
            mBlockLayoutRequests = false;
        }
    }
}

From source file:org.bangbang.support.v4.widget.HListView.java

@Override
    protected void layoutChildren() {
        final boolean blockLayoutRequests = mBlockLayoutRequests;
        if (!blockLayoutRequests) {
            mBlockLayoutRequests = true;
        } else {/*from w w w.  j  av a2s .co m*/
            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;
            int delta = 0;

            View sel;
            View oldSel = null;
            View oldFirst = null;
            View newSel = null;

            View focusLayoutRestoreView = null;

            // 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.");
            }

            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));
                    if (ViewDebug.TRACE_RECYCLER) {
                        ViewDebug.trace(getChildAt(i), ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP, index, 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 ViewRoot 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();
            }

            // Clear out old views
            //removeAllViewsInLayout();
            detachAllViewsFromParent();

            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, mSpecificTop);
                break;
            case LAYOUT_FORCE_BOTTOM:
                sel = fillUp(mItemCount - 1, childrenRight);
                adjustViewsUpOrDown();
                break;
            case LAYOUT_FORCE_TOP:
                mFirstPosition = 0;
                sel = fillFromTop(childrenLeft);
                adjustViewsUpOrDown();
                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 (!mStackFromBottom) {
                        final int position = lookForSelectablePosition(0, true);
                        setSelectedPositionInt(position);
                        sel = fillFromTop(childrenLeft);
                    } else {
                        final int position = lookForSelectablePosition(mItemCount - 1, false);
                        setSelectedPositionInt(position);
                        sel = fillUp(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.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(sel);
                    } else {
                        sel.setSelected(false);
                        mSelectorRect.setEmpty();
                    }
                } else {
                    positionSelector(sel);
                }
                mSelectedTop = sel.getTop();
            } 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();
                }
            }

            // 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);

            updateScrollIndicators();

            if (mItemCount > 0) {
                checkSelectionChanged();
            }

            invokeOnItemScrollListener();
        } finally {
            if (!blockLayoutRequests) {
                mBlockLayoutRequests = false;
            }
        }
    }

From source file:com.awrtechnologies.valor.valorfireplace.hlistview.widget.HListView.java

@Override
protected void layoutChildren() {
    final boolean blockLayoutRequests = mBlockLayoutRequests;
    if (!blockLayoutRequests) {
        mBlockLayoutRequests = true;//from   ww w .ja  v  a 2 s .c o  m
    } 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();
        }

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

        // Attempt to restore accessibility focus.
        // if ( accessibilityFocusLayoutRestoreNode != null ) {
        // accessibilityFocusLayoutRestoreNode.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS );
        // } else if ( accessibilityFocusLayoutRestoreView != null ) {
        // this method is marked as hidden. Shame on you google!
        // 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 ) {
        // this method is marked as hidden. Shame on you google!
        // 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.awrtechnologies.carbudgetsales.hlistview.widget.HListView.java

@Override
protected void layoutChildren() {
    final boolean blockLayoutRequests = mBlockLayoutRequests;
    if (!blockLayoutRequests) {
        mBlockLayoutRequests = true;//w  ww .  j  a va2s . c o  m
    } 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 com.awrtechnologies.carbudgetsales.adapter has changed but "
                            + "ListView did not receive a notification. Make sure the content of "
                            + "your com.awrtechnologies.carbudgetsales.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
            // com.awrtechnologies.carbudgetsales.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();
        }

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

        // Attempt to restore accessibility focus.
        // if ( accessibilityFocusLayoutRestoreNode != null ) {
        // accessibilityFocusLayoutRestoreNode.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS );
        // } else if ( accessibilityFocusLayoutRestoreView != null ) {
        // this method is marked as hidden. Shame on you google!
        // 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 ) {
        // this method is marked as hidden. Shame on you google!
        // 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.datarita.ultimatecamera.turu.views.TwoWayView.java

private void layoutChildren() {
    if (getWidth() == 0 || getHeight() == 0) {
        return;/*from www . j a  va2  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;/* ww  w  . j a v a2 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 = (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;/*from  w  w w .  ja v 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 = (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;//w  ww .  ja v  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 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;
        }
    }
}