List of usage examples for android.view View requestFocus
public final boolean requestFocus()
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; } } }