RecyclerViewActivity.java revision 2a1ade8a82653e53f3d5b16c7e9d0ed9cb734101
1f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell/* 2f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * Copyright (C) 2013 The Android Open Source Project 3f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * 4f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * you may not use this file except in compliance with the License. 6f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * You may obtain a copy of the License at 7f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * 8f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 9f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * 10f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * Unless required by applicable law or agreed to in writing, software 11f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * See the License for the specific language governing permissions and 14f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * limitations under the License. 15f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell */ 16f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 17f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 18f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellpackage com.example.android.supportv7.widget; 19f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 20e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyarimport com.example.android.supportv7.Cheeses; 21e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyarimport com.example.android.supportv7.widget.adapter.SimpleStringAdapter; 22e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyarimport com.example.android.supportv7.widget.decorator.DividerItemDecoration; 23e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 24f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.app.Activity; 25f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.content.Context; 26f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.os.Bundle; 27f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.support.v4.view.MenuItemCompat; 28f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.support.v7.widget.RecyclerView; 29f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.util.DisplayMetrics; 30f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.Menu; 31f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.MenuItem; 32f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.View; 33f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.ViewGroup; 34f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 35f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellpublic class RecyclerViewActivity extends Activity { 36e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 37bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell private static final String TAG = "RecyclerViewActivity"; 38bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell 39f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private RecyclerView mRecyclerView; 40f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 41f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 42f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell protected void onCreate(Bundle savedInstanceState) { 43f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell super.onCreate(savedInstanceState); 44f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 45f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final RecyclerView rv = new RecyclerView(this); 46f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell rv.setLayoutManager(new MyLayoutManager(this)); 47f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell rv.setHasFixedSize(true); 48f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell rv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 49f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell ViewGroup.LayoutParams.MATCH_PARENT)); 50e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar rv.setAdapter(new SimpleStringAdapter(this, Cheeses.sCheeseStrings) { 51e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar @Override 52e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar public SimpleStringAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 53e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar int viewType) { 54e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar final SimpleStringAdapter.ViewHolder vh = super 55e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar .onCreateViewHolder(parent, viewType); 56e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar vh.itemView.setOnClickListener(new View.OnClickListener() { 57e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar @Override 58e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar public void onClick(View v) { 59e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar final int pos = vh.getPosition(); 60e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar if (pos + 1 < getItemCount()) { 61e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar swap(pos, pos + 1); 62e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar } 63e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar } 64e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar }); 65e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar return vh; 66e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar } 67e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar }); 68e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar rv.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); 69f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell setContentView(rv); 70f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mRecyclerView = rv; 71f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 72f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 73f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 74f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public boolean onCreateOptionsMenu(Menu menu) { 75f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell super.onCreateOptionsMenu(menu); 76f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell MenuItemCompat.setShowAsAction(menu.add("Layout"), MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); 77f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return true; 78f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 79f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 80f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 81f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public boolean onOptionsItemSelected(MenuItem item) { 82f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mRecyclerView.requestLayout(); 83f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return super.onOptionsItemSelected(item); 84f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 85f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 86f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private static final int SCROLL_DISTANCE = 80; // dp 87f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 88f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell /** 89f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * A basic ListView-style LayoutManager. 90f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell */ 91f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell class MyLayoutManager extends RecyclerView.LayoutManager { 92e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 93f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private static final String TAG = "MyLayoutManager"; 94e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 95f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private int mFirstPosition; 96e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 97f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private final int mScrollDistance; 98f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 99f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public MyLayoutManager(Context c) { 100f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final DisplayMetrics dm = c.getResources().getDisplayMetrics(); 101f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mScrollDistance = (int) (SCROLL_DISTANCE * dm.density + 0.5f); 102f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 103f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 104f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 1052a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 10690e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentBottom = getHeight() - getPaddingBottom(); 10790e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View oldTopView = getChildCount() > 0 ? getChildAt(0) : null; 10890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell int oldTop = getPaddingTop(); 109549b58504ef397f4c1524ec370bbd0569027e315Adam Powell if (oldTopView != null) { 110549b58504ef397f4c1524ec370bbd0569027e315Adam Powell oldTop = oldTopView.getTop(); 111549b58504ef397f4c1524ec370bbd0569027e315Adam Powell } 112549b58504ef397f4c1524ec370bbd0569027e315Adam Powell 11351edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell detachAndScrapAttachedViews(recycler); 114f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 115549b58504ef397f4c1524ec370bbd0569027e315Adam Powell int top = oldTop; 116f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int bottom; 11790e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int left = getPaddingLeft(); 11890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int right = getWidth() - getPaddingRight(); 119f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 1202a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar final int count = state.getItemCount(); 121f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell for (int i = 0; mFirstPosition + i < count && top < parentBottom; i++, top = bottom) { 1222a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition + i); 123f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v, i); 12463c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 125bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell bottom = top + getDecoratedMeasuredHeight(v); 126bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 127f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 128f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 129f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 130f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 131f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public RecyclerView.LayoutParams generateDefaultLayoutParams() { 132f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 133f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell ViewGroup.LayoutParams.WRAP_CONTENT); 134f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 135f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 136f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 137f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public boolean canScrollVertically() { 138f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return true; 139f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 140f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 141f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 1422a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, 1432a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar RecyclerView.State state) { 14490e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell if (getChildCount() == 0) { 145f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return 0; 146f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 147f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 148f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int scrolled = 0; 14990e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int left = getPaddingLeft(); 15090e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int right = getWidth() - getPaddingRight(); 151f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (dy < 0) { 152f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell while (scrolled > dy) { 15390e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View topView = getChildAt(0); 154bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int hangingTop = Math.max(-getDecoratedTop(topView), 0); 155f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final int scrollBy = Math.min(scrolled - dy, hangingTop); 156f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell scrolled -= scrollBy; 15790e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell offsetChildrenVertical(scrollBy); 158f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (mFirstPosition > 0 && scrolled > dy) { 159f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition--; 1602a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition); 161f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v, 0); 16263c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 163bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = getDecoratedTop(topView); 164bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = bottom - getDecoratedMeasuredHeight(v); 165bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 166f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else { 167f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 168f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 169f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 170f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else if (dy > 0) { 17190e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentHeight = getHeight(); 172f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell while (scrolled < dy) { 17390e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View bottomView = getChildAt(getChildCount() - 1); 174bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int hangingBottom = 175bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell Math.max(getDecoratedBottom(bottomView) - parentHeight, 0); 176f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final int scrollBy = -Math.min(dy - scrolled, hangingBottom); 177f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell scrolled -= scrollBy; 17890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell offsetChildrenVertical(scrollBy); 17990e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell if (scrolled < dy && getItemCount() > mFirstPosition + getChildCount()) { 1802a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition + getChildCount()); 181bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = getDecoratedBottom(getChildAt(getChildCount() - 1)); 182f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v); 18363c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 184bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = top + getDecoratedMeasuredHeight(v); 185bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 186f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else { 187f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 188f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 189f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 190f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 19151edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell recycleViewsOutOfBounds(recycler); 192f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return scrolled; 193f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 194f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 195f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 196f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public View onFocusSearchFailed(View focused, int direction, 1972a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar RecyclerView.Recycler recycler, RecyclerView.State state) { 19890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int oldCount = getChildCount(); 199f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 200f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (oldCount == 0) { 201f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return null; 202f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 203f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 20490e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int left = getPaddingLeft(); 20590e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int right = getWidth() - getPaddingRight(); 206f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 207f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell View toFocus = null; 208f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int newViewsHeight = 0; 209f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (direction == View.FOCUS_UP || direction == View.FOCUS_BACKWARD) { 210f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell while (mFirstPosition > 0 && newViewsHeight < mScrollDistance) { 211f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition--; 2122a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition); 213bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = getDecoratedTop(getChildAt(0)); 214f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v, 0); 21563c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 216bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = bottom - getDecoratedMeasuredHeight(v); 217bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 218f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (v.isFocusable()) { 219f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell toFocus = v; 220f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 221f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 222f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 223f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 224f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (direction == View.FOCUS_DOWN || direction == View.FOCUS_FORWARD) { 22590e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell while (mFirstPosition + getChildCount() < getItemCount() && 226f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell newViewsHeight < mScrollDistance) { 2272a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition + getChildCount()); 228bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = getDecoratedBottom(getChildAt(getChildCount() - 1)); 229f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v); 23063c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 231bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = top + getDecoratedMeasuredHeight(v); 232bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 233f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (v.isFocusable()) { 234f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell toFocus = v; 235f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 236f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 237f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 238f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 239f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 240f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return toFocus; 241f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 242f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 24351edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell public void recycleViewsOutOfBounds(RecyclerView.Recycler recycler) { 24490e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int childCount = getChildCount(); 24590e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentWidth = getWidth(); 24690e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentHeight = getHeight(); 247f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell boolean foundFirst = false; 248f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int first = 0; 249f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int last = 0; 250f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell for (int i = 0; i < childCount; i++) { 25190e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View v = getChildAt(i); 252bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell if (v.hasFocus() || (getDecoratedRight(v) >= 0 && 253bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell getDecoratedLeft(v) <= parentWidth && 254bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell getDecoratedBottom(v) >= 0 && 255bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell getDecoratedTop(v) <= parentHeight)) { 256f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (!foundFirst) { 257f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell first = i; 258f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell foundFirst = true; 259f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 260f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell last = i; 261f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 262f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 263f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell for (int i = childCount - 1; i > last; i--) { 26451edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell removeAndRecycleViewAt(i, recycler); 265f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 26690e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell for (int i = first - 1; i >= 0; i--) { 26751edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell removeAndRecycleViewAt(i, recycler); 268f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 26990e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell if (getChildCount() == 0) { 270f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition = 0; 271f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else { 272f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition += first; 273f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 274f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 275f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 276f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell} 277