Example usage for android.view View requestFocus

List of usage examples for android.view View requestFocus

Introduction

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

Prototype

public final boolean requestFocus() 

Source Link

Document

Call this to try to give focus to a specific view or to one of its descendants.

Usage

From source file:ayushi.view.fragment.ProductDetailsFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.frag_product_detail, container, false);

    mToolbar = (Toolbar) rootView.findViewById(R.id.htab_toolbar);
    if (mToolbar != null) {
        ((ECartHomeActivity) getActivity()).setSupportActionBar(mToolbar);
    }/*from  www.j a  v a2  s  .c  om*/

    if (mToolbar != null) {
        ((ECartHomeActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mToolbar.setNavigationIcon(R.drawable.ic_drawer);

    }

    mToolbar.setTitleTextColor(Color.WHITE);

    mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((ECartHomeActivity) getActivity()).getmDrawerLayout().openDrawer(GravityCompat.START);
        }
    });

    ((ECartHomeActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    similarProductsPager = (ClickableViewPager) rootView.findViewById(R.id.similar_products_pager);

    topSellingPager = (ClickableViewPager) rootView.findViewById(R.id.top_selleing_pager);

    itemSellPrice = ((TextView) rootView.findViewById(R.id.category_discount));

    quanitity = ((TextView) rootView.findViewById(R.id.iteam_amount));

    itemName = ((TextView) rootView.findViewById(R.id.product_name));

    itemdescription = ((TextView) rootView.findViewById(R.id.product_description));

    itemImage = (ImageView) rootView.findViewById(R.id.product_image);

    fillProductData();

    rootView.findViewById(R.id.add_item).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (isFromCart) {

                //Update Quantity on shopping List
                GlobaDataHolder.getGlobaDataHolder().getShoppingList().get(productListNumber)
                        .setQuantity(String.valueOf(

                                Integer.valueOf(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                                        .get(productListNumber).getQuantity()) + 1));

                //Update Ui
                quanitity.setText(GlobaDataHolder.getGlobaDataHolder().getShoppingList().get(productListNumber)
                        .getQuantity());

                Utils.vibrate(getActivity());

                //Update checkout amount on screen
                ((ECartHomeActivity) getActivity()).updateCheckOutAmount(
                        BigDecimal.valueOf(Long.valueOf(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                                .get(productListNumber).getSellMRP())),
                        true);

            } else {

                // current object
                Product tempObj = GlobaDataHolder.getGlobaDataHolder().getProductMap().get(subcategoryKey)
                        .get(productListNumber);

                // if current object is lready in shopping list
                if (GlobaDataHolder.getGlobaDataHolder().getShoppingList().contains(tempObj)) {

                    // get position of current item in shopping list
                    int indexOfTempInShopingList = GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                            .indexOf(tempObj);

                    // increase quantity of current item in shopping
                    // list
                    if (Integer.parseInt(tempObj.getQuantity()) == 0) {

                        ((ECartHomeActivity) getContext()).updateItemCount(true);

                    }

                    // update quanity in shopping list
                    GlobaDataHolder.getGlobaDataHolder().getShoppingList().get(indexOfTempInShopingList)
                            .setQuantity(String.valueOf(Integer.valueOf(tempObj.getQuantity()) + 1));

                    // update checkout amount
                    ((ECartHomeActivity) getContext())
                            .updateCheckOutAmount(
                                    BigDecimal.valueOf(
                                            Long.valueOf(GlobaDataHolder.getGlobaDataHolder().getProductMap()
                                                    .get(subcategoryKey).get(productListNumber).getSellMRP())),
                                    true);

                    // update current item quanitity
                    quanitity.setText(tempObj.getQuantity());

                } else {

                    ((ECartHomeActivity) getContext()).updateItemCount(true);

                    tempObj.setQuantity(String.valueOf(1));

                    quanitity.setText(tempObj.getQuantity());

                    GlobaDataHolder.getGlobaDataHolder().getShoppingList().add(tempObj);

                    ((ECartHomeActivity) getContext())
                            .updateCheckOutAmount(
                                    BigDecimal.valueOf(
                                            Long.valueOf(GlobaDataHolder.getGlobaDataHolder().getProductMap()
                                                    .get(subcategoryKey).get(productListNumber).getSellMRP())),
                                    true);

                }

                Utils.vibrate(getContext());

            }
        }

    });

    rootView.findViewById(R.id.remove_item).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            if (isFromCart)

            {

                if (Integer.valueOf(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                        .get(productListNumber).getQuantity()) > 2) {

                    GlobaDataHolder.getGlobaDataHolder().getShoppingList().get(productListNumber)
                            .setQuantity(String.valueOf(

                                    Integer.valueOf(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                                            .get(productListNumber).getQuantity()) - 1));

                    quanitity.setText(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                            .get(productListNumber).getQuantity());

                    ((ECartHomeActivity) getActivity()).updateCheckOutAmount(
                            BigDecimal.valueOf(Long.valueOf(GlobaDataHolder.getGlobaDataHolder()
                                    .getShoppingList().get(productListNumber).getSellMRP())),
                            false);

                    Utils.vibrate(getActivity());
                }

                else if (Integer.valueOf(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                        .get(productListNumber).getQuantity()) == 1) {
                    ((ECartHomeActivity) getActivity()).updateItemCount(false);

                    ((ECartHomeActivity) getActivity()).updateCheckOutAmount(
                            BigDecimal.valueOf(Long.valueOf(GlobaDataHolder.getGlobaDataHolder()
                                    .getShoppingList().get(productListNumber).getSellMRP())),
                            false);

                    GlobaDataHolder.getGlobaDataHolder().getShoppingList().remove(productListNumber);

                    if (Integer.valueOf(((ECartHomeActivity) getActivity()).getItemCount()) == 0) {

                        MyCartFragment.updateMyCartFragment(false);

                    }

                    Utils.vibrate(getActivity());

                }

            }

            else {

                Product tempObj = GlobaDataHolder.getGlobaDataHolder().getProductMap().get(subcategoryKey)
                        .get(productListNumber);

                if (GlobaDataHolder.getGlobaDataHolder().getShoppingList().contains(tempObj)) {

                    int indexOfTempInShopingList = GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                            .indexOf(tempObj);

                    if (Integer.valueOf(tempObj.getQuantity()) != 0) {

                        GlobaDataHolder.getGlobaDataHolder().getShoppingList().get(indexOfTempInShopingList)
                                .setQuantity(String.valueOf(Integer.valueOf(tempObj.getQuantity()) - 1));

                        ((ECartHomeActivity) getContext()).updateCheckOutAmount(
                                BigDecimal.valueOf(
                                        Long.valueOf(GlobaDataHolder.getGlobaDataHolder().getProductMap()
                                                .get(subcategoryKey).get(productListNumber).getSellMRP())),
                                false);

                        quanitity.setText(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                                .get(indexOfTempInShopingList).getQuantity());

                        Utils.vibrate(getContext());

                        if (Integer.valueOf(GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                                .get(indexOfTempInShopingList).getQuantity()) == 0) {

                            GlobaDataHolder.getGlobaDataHolder().getShoppingList()
                                    .remove(indexOfTempInShopingList);

                            ((ECartHomeActivity) getContext()).updateItemCount(false);

                        }

                    }

                } else {

                }

            }

        }

    });

    rootView.setFocusableInTouchMode(true);
    rootView.requestFocus();
    rootView.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {

                if (isFromCart) {

                    Utils.switchContent(R.id.frag_container, Utils.SHOPPING_LIST_TAG,
                            ((ECartHomeActivity) (getActivity())), AnimationType.SLIDE_UP);
                } else {

                    Utils.switchContent(R.id.frag_container, Utils.PRODUCT_OVERVIEW_FRAGMENT_TAG,
                            ((ECartHomeActivity) (getActivity())), AnimationType.SLIDE_RIGHT);
                }

            }
            return true;
        }
    });

    if (isFromCart) {

        similarProductsPager.setVisibility(View.GONE);

        topSellingPager.setVisibility(View.GONE);

    } else {
        showRecomondation();
    }

    return rootView;
}

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

@Override
    protected void layoutChildren() {
        final boolean blockLayoutRequests = mBlockLayoutRequests;
        if (!blockLayoutRequests) {
            mBlockLayoutRequests = true;
        } else {/*  w  ww  .  ja va 2s  .c  o 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:se.oort.clockify.widget.sgv.StaggeredGridView.java

/**
 * Measure and layout all currently visible children.
 *
 * @param queryAdapter true to requery the adapter for view data
 *//*from w w w .  j a va  2s  .c  o m*/
final void layoutChildren(boolean queryAdapter) {
    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();
    final int itemMargin = mItemMargin;
    final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1));
    final int colWidth = availableWidth / mColCount;
    // The availableWidth may not be divisible by mColCount. Keep the
    // remainder. It will be added to the width of the last view in the row.
    final int remainder = availableWidth % mColCount;

    boolean viewsRemovedInLayout = false;

    // If we're animating out stale views, then we want to defer recycling of views.
    final boolean deferRecyclingForAnimation = mAnimationOutMode != SgvAnimationHelper.AnimationOut.NONE;

    if (!deferRecyclingForAnimation) {
        final int childCount = getChildCount();
        // If the latest data set has fewer data items than mFirstPosition, don't keep any
        // views on screen, and just let the layout logic below retrieve appropriate views
        // from the recycler.
        final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition;

        if (childCount > viewsToKeepOnScreen) {
            // If there are more views laid out than the number of data items remaining to be
            // laid out, recycle the extraneous views.
            recycleViewsInRange(viewsToKeepOnScreen, childCount - 1);
            viewsRemovedInLayout = true;
        }
    } else {
        mViewsToAnimateOut.clear();
    }

    for (int i = 0; i < getChildCount(); i++) {
        final int position = mFirstPosition + i;
        View child = getChildAt(i);

        final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()];
        if (deferRecyclingForAnimation
                && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) {
            // For the remainder of views on screen, they should not be on screen, so we can
            // skip layout.  Add them to the list of views to animate out.
            // We should only get in this position if deferRecyclingForAnimation = true,
            // otherwise, we should've recycled all views before getting into this layout loop.
            mViewsToAnimateOut.add(child);
            continue;
        }

        LayoutParams lp = null;
        int col = -1;

        if (child != null) {
            lp = (LayoutParams) child.getLayoutParams();
            col = lp.column;
        }

        final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested();
        if (queryAdapter) {
            View newView = null;
            if (deferRecyclingForAnimation) {
                // If we are deferring recycling for animation, then we don't want to pass the
                // current child in to obtainView for re-use.  obtainView() in this case should
                // try to find the view belonging to this item on screen, or populate a fresh
                // one from the recycler.
                newView = obtainView(position);
            } else {
                newView = obtainView(position, child);
            }

            // Update layout params since they may have changed
            lp = (LayoutParams) newView.getLayoutParams();

            if (newView != child) {
                if (child != null && !deferRecyclingForAnimation) {
                    mRecycler.addScrap(child);
                    removeViewInLayout(child);
                    viewsRemovedInLayout = true;
                }

                // If this view is already in the layout hierarchy, we can just detach it
                // from the parent and re-attach it at the correct index.  If the view has
                // already been removed from the layout hierarchy, getParent() == null.
                if (newView.getParent() == this) {
                    detachViewFromParent(newView);
                    attachViewToParent(newView, i, lp);
                } else {
                    addViewInLayout(newView, i, lp);
                }
            }

            child = newView;

            // Since the data has changed, we need to make sure the next child is in the
            // right column. We choose the next column down (vs. next column up) because we
            // are filling from the top of the screen downwards as we iterate through
            // visible children. (We take span into account below.)
            lp.column = getNextColumnDown();
            col = lp.column;
        }

        setReorderingArea(lp);

        final int span = Math.min(mColCount, lp.span);

        // Given the span, check if there's enough space to put this view at this column.
        // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}.
        if (span > 1) {
            if (mIsRtlLayout) {
                // For RTL layout, if the current column index is less than the span of the
                // child, then we know that there is not enough room remaining to lay this
                // child out (e.g., if col == 0, but span == 2, then laying this child down
                // at column = col would put us out of bound into a negative column index.).
                // For this scenario, reset the index back to the right-most column, and lay
                // out the child at this position where we can ensure that we can display as
                // much of the child as possible.
                if (col + 1 < span) {
                    col = mColCount - 1;
                }
            } else {
                if (mColCount - col < span) {
                    // If not, reset the col to 0.
                    col = 0;
                }
            }

            lp.column = col;
        }

        int widthSize = (colWidth * span + itemMargin * (span - 1));
        // If it is rtl, we layout the view from col to col - span +
        // 1. If it reaches the most left column, i.e. we added the
        // additional width. So the check it span == col +1
        if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) {
            widthSize += remainder;
        }
        if (needsLayout) {
            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);

            final int heightSpec;
            if (lp.height == LayoutParams.WRAP_CONTENT) {
                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            } else {
                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
            }

            child.measure(widthSpec, heightSpec);
        }

        // Place the top of this child beneath the last by finding the lowest coordinate across
        // the columns that this child will span.  For LTR layout, we scan across from left to
        // right, and for RTL layout, we scan from right to left.
        // TODO:  Consolidate this logic with getNextRecordDown() in the future, as that method
        // already calculates the margins for us.  This will keep the implementation consistent
        // with fillUp() and fillDown().
        int childTop = mItemBottoms[col] + mItemMargin;
        if (span > 1) {
            int lowest = childTop;
            for (int spanIndex = 0; spanIndex < span; spanIndex++) {
                final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
                final int bottom = mItemBottoms[index] + mItemMargin;
                if (bottom > lowest) {
                    lowest = bottom;
                }
            }

            childTop = lowest;
        }

        final int childHeight = child.getMeasuredHeight();
        final int childBottom = childTop + childHeight;
        int childLeft = 0;
        int childRight = 0;
        if (mIsRtlLayout) {
            childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin);
            childLeft = childRight - child.getMeasuredWidth();
        } else {
            childLeft = paddingLeft + col * (colWidth + itemMargin);
            childRight = childLeft + child.getMeasuredWidth();
        }

        child.layout(childLeft, childTop, childRight, childBottom);
        if (lp.id == mFocusedChildIdToScrollIntoView) {
            child.requestFocus();
        }

        for (int spanIndex = 0; spanIndex < span; spanIndex++) {
            final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
            mItemBottoms[index] = childBottom;
        }

        // Whether or not LayoutRecords may have already existed for the view at this position
        // on screen, we'll update it after we lay out to ensure that the LayoutRecord
        // has the most updated information about the view at this position.  We can be assured
        // that all views before those on screen (views with adapter position < mFirstPosition)
        // have the correct LayoutRecords because calculateLayoutStartOffsets() would have
        // set them appropriately.
        LayoutRecord rec = mLayoutRecords.get(position);
        if (rec == null) {
            rec = new LayoutRecord();
            mLayoutRecords.put(position, rec);
        }

        rec.column = lp.column;
        rec.height = childHeight;
        rec.id = lp.id;
        rec.span = span;
    }

    // It appears that removeViewInLayout() does not invalidate.  So if we make use of this
    // method during layout, we should invalidate explicitly.
    if (viewsRemovedInLayout || deferRecyclingForAnimation) {
        invalidate();
    }
}

From source file:app.umitems.greenclock.widget.sgv.StaggeredGridView.java

/**
 * Measure and layout all currently visible children.
 *
 * @param queryAdapter true to requery the adapter for view data
 *///from w w w . j  a va 2 s  .  c o m
final void layoutChildren(boolean queryAdapter) {
    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();
    final int itemMargin = mItemMargin;
    final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1));
    final int colWidth = availableWidth / mColCount;
    // The availableWidth may not be divisible by mColCount. Keep the
    // remainder. It will be added to the width of the last view in the row.
    final int remainder = availableWidth % mColCount;

    boolean viewsRemovedInLayout = false;

    // If we're animating out stale views, then we want to defer recycling of views.
    final boolean deferRecyclingForAnimation = mAnimationOutMode != AnimationOut.NONE;

    if (!deferRecyclingForAnimation) {
        final int childCount = getChildCount();
        // If the latest data set has fewer data items than mFirstPosition, don't keep any
        // views on screen, and just let the layout logic below retrieve appropriate views
        // from the recycler.
        final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition;

        if (childCount > viewsToKeepOnScreen) {
            // If there are more views laid out than the number of data items remaining to be
            // laid out, recycle the extraneous views.
            recycleViewsInRange(viewsToKeepOnScreen, childCount - 1);
            viewsRemovedInLayout = true;
        }
    } else {
        mViewsToAnimateOut.clear();
    }

    for (int i = 0; i < getChildCount(); i++) {
        final int position = mFirstPosition + i;
        View child = getChildAt(i);

        final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()];
        if (deferRecyclingForAnimation
                && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) {
            // For the remainder of views on screen, they should not be on screen, so we can
            // skip layout.  Add them to the list of views to animate out.
            // We should only get in this position if deferRecyclingForAnimation = true,
            // otherwise, we should've recycled all views before getting into this layout loop.
            mViewsToAnimateOut.add(child);
            continue;
        }

        LayoutParams lp = null;
        int col = -1;

        if (child != null) {
            lp = (LayoutParams) child.getLayoutParams();
            col = lp.column;
        }

        final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested();
        if (queryAdapter) {
            View newView = null;
            if (deferRecyclingForAnimation) {
                // If we are deferring recycling for animation, then we don't want to pass the
                // current child in to obtainView for re-use.  obtainView() in this case should
                // try to find the view belonging to this item on screen, or populate a fresh
                // one from the recycler.
                newView = obtainView(position);
            } else {
                newView = obtainView(position, child);
            }

            // Update layout params since they may have changed
            lp = (LayoutParams) newView.getLayoutParams();

            if (newView != child) {
                if (child != null && !deferRecyclingForAnimation) {
                    mRecycler.addScrap(child);
                    removeViewInLayout(child);
                    viewsRemovedInLayout = true;
                }

                // If this view is already in the layout hierarchy, we can just detach it
                // from the parent and re-attach it at the correct index.  If the view has
                // already been removed from the layout hierarchy, getParent() == null.
                if (newView.getParent() == this) {
                    detachViewFromParent(newView);
                    attachViewToParent(newView, i, lp);
                } else {
                    addViewInLayout(newView, i, lp);
                }
            }

            child = newView;

            // Since the data has changed, we need to make sure the next child is in the
            // right column. We choose the next column down (vs. next column up) because we
            // are filling from the top of the screen downwards as we iterate through
            // visible children. (We take span into account below.)
            lp.column = getNextColumnDown();
            col = lp.column;
        }

        setReorderingArea(lp);

        final int span = Math.min(mColCount, lp.span);

        // Given the span, check if there's enough space to put this view at this column.
        // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}.
        if (span > 1) {
            if (mIsRtlLayout) {
                // For RTL layout, if the current column index is less than the span of the
                // child, then we know that there is not enough room remaining to lay this
                // child out (e.g., if col == 0, but span == 2, then laying this child down
                // at column = col would put us out of bound into a negative column index.).
                // For this scenario, reset the index back to the right-most column, and lay
                // out the child at this position where we can ensure that we can display as
                // much of the child as possible.
                if (col + 1 < span) {
                    col = mColCount - 1;
                }
            } else {
                if (mColCount - col < span) {
                    // If not, reset the col to 0.
                    col = 0;
                }
            }

            lp.column = col;
        }

        int widthSize = (colWidth * span + itemMargin * (span - 1));
        // If it is rtl, we layout the view from col to col - span +
        // 1. If it reaches the most left column, i.e. we added the
        // additional width. So the check it span == col +1
        if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) {
            widthSize += remainder;
        }
        if (needsLayout) {
            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);

            final int heightSpec;
            if (lp.height == LayoutParams.WRAP_CONTENT) {
                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            } else {
                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
            }

            child.measure(widthSpec, heightSpec);
        }

        // Place the top of this child beneath the last by finding the lowest coordinate across
        // the columns that this child will span.  For LTR layout, we scan across from left to
        // right, and for RTL layout, we scan from right to left.
        // TODO:  Consolidate this logic with getNextRecordDown() in the future, as that method
        // already calculates the margins for us.  This will keep the implementation consistent
        // with fillUp() and fillDown().
        int childTop = mItemBottoms[col] + mItemMargin;
        if (span > 1) {
            int lowest = childTop;
            for (int spanIndex = 0; spanIndex < span; spanIndex++) {
                final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
                final int bottom = mItemBottoms[index] + mItemMargin;
                if (bottom > lowest) {
                    lowest = bottom;
                }
            }

            childTop = lowest;
        }

        final int childHeight = child.getMeasuredHeight();
        final int childBottom = childTop + childHeight;
        int childLeft = 0;
        int childRight = 0;
        if (mIsRtlLayout) {
            childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin);
            childLeft = childRight - child.getMeasuredWidth();
        } else {
            childLeft = paddingLeft + col * (colWidth + itemMargin);
            childRight = childLeft + child.getMeasuredWidth();
        }

        /*    Log.v(TAG, "[layoutChildren] height: " + childHeight
            + " top: " + childTop + " bottom: " + childBottom
            + " left: " + childLeft
            + " column: " + col
            + " position: " + position
            + " id: " + lp.id);
        */
        child.layout(childLeft, childTop, childRight, childBottom);
        if (lp.id == mFocusedChildIdToScrollIntoView) {
            child.requestFocus();
        }

        for (int spanIndex = 0; spanIndex < span; spanIndex++) {
            final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
            mItemBottoms[index] = childBottom;
        }

        // Whether or not LayoutRecords may have already existed for the view at this position
        // on screen, we'll update it after we lay out to ensure that the LayoutRecord
        // has the most updated information about the view at this position.  We can be assured
        // that all views before those on screen (views with adapter position < mFirstPosition)
        // have the correct LayoutRecords because calculateLayoutStartOffsets() would have
        // set them appropriately.
        LayoutRecord rec = mLayoutRecords.get(position);
        if (rec == null) {
            rec = new LayoutRecord();
            mLayoutRecords.put(position, rec);
        }

        rec.column = lp.column;
        rec.height = childHeight;
        rec.id = lp.id;
        rec.span = span;
    }

    // It appears that removeViewInLayout() does not invalidate.  So if we make use of this
    // method during layout, we should invalidate explicitly.
    if (viewsRemovedInLayout || deferRecyclingForAnimation) {
        invalidate();
    }
}

From source file:com.deepak.myclock.widget.sgv.StaggeredGridView.java

/**
 * Measure and layout all currently visible children.
 *
 * @param queryAdapter true to requery the adapter for view data
 *///  w  w  w  .  j  a va  2s  .com
final void layoutChildren(boolean queryAdapter) {
    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();
    final int itemMargin = mItemMargin;
    final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1));
    final int colWidth = availableWidth / mColCount;
    // The availableWidth may not be divisible by mColCount. Keep the
    // remainder. It will be added to the width of the last view in the row.
    final int remainder = availableWidth % mColCount;

    boolean viewsRemovedInLayout = false;

    // If we're animating out stale views, then we want to defer recycling of views.
    final boolean deferRecyclingForAnimation = mAnimationOutMode != SgvAnimationHelper.AnimationOut.NONE;

    if (!deferRecyclingForAnimation) {
        final int childCount = getChildCount();
        // If the latest data set has fewer data items than mFirstPosition, don't keep any
        // views on screen, and just let the layout logic below retrieve appropriate views
        // from the recycler.
        final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition;

        if (childCount > viewsToKeepOnScreen) {
            // If there are more views laid out than the number of data items remaining to be
            // laid out, recycle the extraneous views.
            recycleViewsInRange(viewsToKeepOnScreen, childCount - 1);
            viewsRemovedInLayout = true;
        }
    } else {
        mViewsToAnimateOut.clear();
    }

    for (int i = 0; i < getChildCount(); i++) {
        final int position = mFirstPosition + i;
        View child = getChildAt(i);

        final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()];
        if (deferRecyclingForAnimation
                && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) {
            // For the remainder of views on screen, they should not be on screen, so we can
            // skip layout.  Add them to the list of views to animate out.
            // We should only get in this position if deferRecyclingForAnimation = true,
            // otherwise, we should've recycled all views before getting into this layout loop.
            mViewsToAnimateOut.add(child);
            continue;
        }

        LayoutParams lp = null;
        int col = -1;

        if (child != null) {
            lp = (LayoutParams) child.getLayoutParams();
            col = lp.column;
        }

        final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested();
        if (queryAdapter) {
            View newView = null;
            if (deferRecyclingForAnimation) {
                // If we are deferring recycling for animation, then we don't want to pass the
                // current child in to obtainView for re-use.  obtainView() in this case should
                // try to find the view belonging to this item on screen, or populate a fresh
                // one from the recycler.
                newView = obtainView(position);
            } else {
                newView = obtainView(position, child);
            }

            // Update layout params since they may have changed
            lp = (LayoutParams) newView.getLayoutParams();

            if (newView != child) {
                if (child != null && !deferRecyclingForAnimation) {
                    mRecycler.addScrap(child);
                    removeViewInLayout(child);
                    viewsRemovedInLayout = true;
                }

                // If this view is already in the layout hierarchy, we can just detach it
                // from the parent and re-attach it at the correct index.  If the view has
                // already been removed from the layout hierarchy, getParent() == null.
                if (newView.getParent() == this) {
                    detachViewFromParent(newView);
                    attachViewToParent(newView, i, lp);
                } else {
                    addViewInLayout(newView, i, lp);
                }
            }

            child = newView;

            // Since the data has changed, we need to make sure the next child is in the
            // right column. We choose the next column down (vs. next column up) because we
            // are filling from the top of the screen downwards as we iterate through
            // visible children. (We take span into account below.)
            lp.column = getNextColumnDown();
            col = lp.column;
        }

        setReorderingArea(lp);

        final int span = Math.min(mColCount, lp.span);

        // Given the span, check if there's enough space to put this view at this column.
        // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}.
        if (span > 1) {
            if (mIsRtlLayout) {
                // For RTL layout, if the current column index is less than the span of the
                // child, then we know that there is not enough room remaining to lay this
                // child out (e.g., if col == 0, but span == 2, then laying this child down
                // at column = col would put us out of bound into a negative column index.).
                // For this scenario, reset the index back to the right-most column, and lay
                // out the child at this position where we can ensure that we can display as
                // much of the child as possible.
                if (col + 1 < span) {
                    col = mColCount - 1;
                }
            } else {
                if (mColCount - col < span) {
                    // If not, reset the col to 0.
                    col = 0;
                }
            }

            lp.column = col;
        }

        int widthSize = (colWidth * span + itemMargin * (span - 1));
        // If it is rtl, we layout the view from col to col - span +
        // 1. If it reaches the most left column, i.e. we added the
        // additional width. So the check it span == col +1
        if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) {
            widthSize += remainder;
        }
        if (needsLayout) {
            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);

            final int heightSpec;
            if (lp.height == LayoutParams.WRAP_CONTENT) {
                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            } else {
                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
            }

            child.measure(widthSpec, heightSpec);
        }

        // Place the top of this child beneath the last by finding the lowest coordinate across
        // the columns that this child will span.  For LTR layout, we scan across from left to
        // right, and for RTL layout, we scan from right to left.
        // TODO:  Consolidate this logic with getNextRecordDown() in the future, as that method
        // already calculates the margins for us.  This will keep the implementation consistent
        // with fillUp() and fillDown().
        int childTop = mItemBottoms[col] + mItemMargin;
        if (span > 1) {
            int lowest = childTop;
            for (int spanIndex = 0; spanIndex < span; spanIndex++) {
                final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
                final int bottom = mItemBottoms[index] + mItemMargin;
                if (bottom > lowest) {
                    lowest = bottom;
                }
            }

            childTop = lowest;
        }

        final int childHeight = child.getMeasuredHeight();
        final int childBottom = childTop + childHeight;
        int childLeft = 0;
        int childRight = 0;
        if (mIsRtlLayout) {
            childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin);
            childLeft = childRight - child.getMeasuredWidth();
        } else {
            childLeft = paddingLeft + col * (colWidth + itemMargin);
            childRight = childLeft + child.getMeasuredWidth();
        }

        /*    Log.v(TAG, "[layoutChildren] height: " + childHeight
            + " top: " + childTop + " bottom: " + childBottom
            + " left: " + childLeft
            + " column: " + col
            + " position: " + position
            + " id: " + lp.id);
        */
        child.layout(childLeft, childTop, childRight, childBottom);
        if (lp.id == mFocusedChildIdToScrollIntoView) {
            child.requestFocus();
        }

        for (int spanIndex = 0; spanIndex < span; spanIndex++) {
            final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
            mItemBottoms[index] = childBottom;
        }

        // Whether or not LayoutRecords may have already existed for the view at this position
        // on screen, we'll update it after we lay out to ensure that the LayoutRecord
        // has the most updated information about the view at this position.  We can be assured
        // that all views before those on screen (views with adapter position < mFirstPosition)
        // have the correct LayoutRecords because calculateLayoutStartOffsets() would have
        // set them appropriately.
        LayoutRecord rec = mLayoutRecords.get(position);
        if (rec == null) {
            rec = new LayoutRecord();
            mLayoutRecords.put(position, rec);
        }

        rec.column = lp.column;
        rec.height = childHeight;
        rec.id = lp.id;
        rec.span = span;
    }

    // It appears that removeViewInLayout() does not invalidate.  So if we make use of this
    // method during layout, we should invalidate explicitly.
    if (viewsRemovedInLayout || deferRecyclingForAnimation) {
        invalidate();
    }
}

From source file:cn.ismartv.tvrecyclerview.widget.RecyclerView.java

private void recoverFocusFromState() {
    if (!mPreserveFocusAfterLayout || mAdapter == null || !hasFocus()) {
        return;//from   ww w.  j  a  v a 2s. com
    }
    // only recover focus if RV itself has the focus or the focused view is hidden
    if (!isFocused()) {
        final View focusedChild = getFocusedChild();
        if (focusedChild == null || !mChildHelper.isHidden(focusedChild)) {
            return;
        }
    }
    ViewHolder focusTarget = null;
    if (mState.mFocusedItemPosition != NO_POSITION) {
        focusTarget = findViewHolderForAdapterPosition(mState.mFocusedItemPosition);
    }
    if (focusTarget == null && mState.mFocusedItemId != NO_ID && mAdapter.hasStableIds()) {
        focusTarget = findViewHolderForItemId(mState.mFocusedItemId);
    }
    if (focusTarget == null || focusTarget.itemView.hasFocus() || !focusTarget.itemView.hasFocusable()) {
        return;
    }
    // looks like the focused item has been replaced with another view that represents the
    // same item in the adapter. Request focus on that.
    View viewToFocus = focusTarget.itemView;
    if (mState.mFocusedSubChildId != NO_ID) {
        View child = focusTarget.itemView.findViewById(mState.mFocusedSubChildId);
        if (child != null && child.isFocusable()) {
            viewToFocus = child;
        }
    }
    viewToFocus.requestFocus();
}

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

@Override
protected void layoutChildren() {
    final boolean blockLayoutRequests = mBlockLayoutRequests;
    if (!blockLayoutRequests) {
        mBlockLayoutRequests = true;/*from  w  w  w. j  a  v a  2  s  .c  om*/
    } 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 w w . ja  va2  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 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.appunite.list.ListView.java

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

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