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 20f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.app.Activity; 21f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.content.Context; 22f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.os.Bundle; 237febb12feeade9937fc0bd1a8e5967251c4aad24Aurimas Liutikasimport android.support.v7.widget.DividerItemDecoration; 24f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.support.v7.widget.RecyclerView; 25f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.util.DisplayMetrics; 26f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.Menu; 27f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.MenuItem; 28f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.View; 29f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellimport android.view.ViewGroup; 30f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 317febb12feeade9937fc0bd1a8e5967251c4aad24Aurimas Liutikasimport com.example.android.supportv7.Cheeses; 327febb12feeade9937fc0bd1a8e5967251c4aad24Aurimas Liutikasimport com.example.android.supportv7.widget.adapter.SimpleStringAdapter; 337febb12feeade9937fc0bd1a8e5967251c4aad24Aurimas Liutikas 34f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powellpublic class RecyclerViewActivity extends Activity { 35e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 36bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell private static final String TAG = "RecyclerViewActivity"; 37bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell 38f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private RecyclerView mRecyclerView; 39f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 40f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 41f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell protected void onCreate(Bundle savedInstanceState) { 42f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell super.onCreate(savedInstanceState); 43f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 44f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final RecyclerView rv = new RecyclerView(this); 45f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell rv.setLayoutManager(new MyLayoutManager(this)); 46f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell rv.setHasFixedSize(true); 47f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell rv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 48f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell ViewGroup.LayoutParams.MATCH_PARENT)); 49e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar rv.setAdapter(new SimpleStringAdapter(this, Cheeses.sCheeseStrings) { 50e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar @Override 51e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar public SimpleStringAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 52e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar int viewType) { 53e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar final SimpleStringAdapter.ViewHolder vh = super 54e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar .onCreateViewHolder(parent, viewType); 55e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar vh.itemView.setOnClickListener(new View.OnClickListener() { 56e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar @Override 57e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar public void onClick(View v) { 584fa1fe35a2e2f6aa8973bbb698f5191b7acc8d95Yigit Boyar final int pos = vh.getAdapterPosition(); 594fa1fe35a2e2f6aa8973bbb698f5191b7acc8d95Yigit Boyar if (pos == RecyclerView.NO_POSITION) { 604fa1fe35a2e2f6aa8973bbb698f5191b7acc8d95Yigit Boyar return; 614fa1fe35a2e2f6aa8973bbb698f5191b7acc8d95Yigit Boyar } 62e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar if (pos + 1 < getItemCount()) { 63e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar swap(pos, pos + 1); 64e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar } 65e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar } 66e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar }); 67e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar return vh; 68e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar } 69e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar }); 707febb12feeade9937fc0bd1a8e5967251c4aad24Aurimas Liutikas rv.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); 71f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell setContentView(rv); 72f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mRecyclerView = rv; 73f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 74f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 75f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 76f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public boolean onCreateOptionsMenu(Menu menu) { 77f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell super.onCreateOptionsMenu(menu); 78458543f38db49fdcb1764f007ded33820964c3feAurimas Liutikas menu.add("Layout").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 79f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return true; 80f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 81f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 82f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 83f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public boolean onOptionsItemSelected(MenuItem item) { 84f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mRecyclerView.requestLayout(); 85f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return super.onOptionsItemSelected(item); 86f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 87f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 88f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private static final int SCROLL_DISTANCE = 80; // dp 89f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 90f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell /** 91f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell * A basic ListView-style LayoutManager. 92f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell */ 93f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell class MyLayoutManager extends RecyclerView.LayoutManager { 94e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 95f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private static final String TAG = "MyLayoutManager"; 96e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 97f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private int mFirstPosition; 98e9f9a04c426e7423db0cd58ec8d2dc3ff2238a30Yigit Boyar 99f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell private final int mScrollDistance; 100f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 101f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public MyLayoutManager(Context c) { 102f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final DisplayMetrics dm = c.getResources().getDisplayMetrics(); 103f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mScrollDistance = (int) (SCROLL_DISTANCE * dm.density + 0.5f); 104f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 105f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 106f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 1072a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 10890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentBottom = getHeight() - getPaddingBottom(); 10990e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View oldTopView = getChildCount() > 0 ? getChildAt(0) : null; 11090e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell int oldTop = getPaddingTop(); 111549b58504ef397f4c1524ec370bbd0569027e315Adam Powell if (oldTopView != null) { 112549b58504ef397f4c1524ec370bbd0569027e315Adam Powell oldTop = oldTopView.getTop(); 113549b58504ef397f4c1524ec370bbd0569027e315Adam Powell } 114549b58504ef397f4c1524ec370bbd0569027e315Adam Powell 11551edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell detachAndScrapAttachedViews(recycler); 116f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 117549b58504ef397f4c1524ec370bbd0569027e315Adam Powell int top = oldTop; 118f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int bottom; 11990e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int left = getPaddingLeft(); 12090e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int right = getWidth() - getPaddingRight(); 121f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 1222a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar final int count = state.getItemCount(); 123f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell for (int i = 0; mFirstPosition + i < count && top < parentBottom; i++, top = bottom) { 1242a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition + i); 125f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v, i); 12663c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 127bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell bottom = top + getDecoratedMeasuredHeight(v); 128bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 129f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 130f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 131f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 132f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 133f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public RecyclerView.LayoutParams generateDefaultLayoutParams() { 134f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 135f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell ViewGroup.LayoutParams.WRAP_CONTENT); 136f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 137f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 138f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 139f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public boolean canScrollVertically() { 140f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return true; 141f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 142f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 143f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 1442a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, 1452a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar RecyclerView.State state) { 14690e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell if (getChildCount() == 0) { 147f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return 0; 148f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 149f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 150f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int scrolled = 0; 15190e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int left = getPaddingLeft(); 15290e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int right = getWidth() - getPaddingRight(); 153f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (dy < 0) { 154f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell while (scrolled > dy) { 15590e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View topView = getChildAt(0); 156bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int hangingTop = Math.max(-getDecoratedTop(topView), 0); 157f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final int scrollBy = Math.min(scrolled - dy, hangingTop); 158f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell scrolled -= scrollBy; 15990e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell offsetChildrenVertical(scrollBy); 160f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (mFirstPosition > 0 && scrolled > dy) { 161f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition--; 1622a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition); 163f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v, 0); 16463c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 165bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = getDecoratedTop(topView); 166bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = bottom - getDecoratedMeasuredHeight(v); 167bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 168f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else { 169f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 170f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 171f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 172f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else if (dy > 0) { 17390e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentHeight = getHeight(); 174f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell while (scrolled < dy) { 17590e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View bottomView = getChildAt(getChildCount() - 1); 176bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int hangingBottom = 177bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell Math.max(getDecoratedBottom(bottomView) - parentHeight, 0); 178f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell final int scrollBy = -Math.min(dy - scrolled, hangingBottom); 179f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell scrolled -= scrollBy; 18090e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell offsetChildrenVertical(scrollBy); 1818b38db9f287670f670f631a0ec4b95882cdd0705Yigit Boyar if (scrolled < dy && state.getItemCount() > mFirstPosition + getChildCount()) { 1822a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition + getChildCount()); 183bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = getDecoratedBottom(getChildAt(getChildCount() - 1)); 184f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v); 18563c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 186bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = top + getDecoratedMeasuredHeight(v); 187bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 188f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else { 189f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 190f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 191f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 192f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 19351edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell recycleViewsOutOfBounds(recycler); 194f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return scrolled; 195f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 196f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 197f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell @Override 198f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell public View onFocusSearchFailed(View focused, int direction, 1992a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar RecyclerView.Recycler recycler, RecyclerView.State state) { 20090e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int oldCount = getChildCount(); 201f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 202f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (oldCount == 0) { 203f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return null; 204f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 205f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 20690e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int left = getPaddingLeft(); 20790e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int right = getWidth() - getPaddingRight(); 208f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 209f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell View toFocus = null; 210f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int newViewsHeight = 0; 211f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (direction == View.FOCUS_UP || direction == View.FOCUS_BACKWARD) { 212f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell while (mFirstPosition > 0 && newViewsHeight < mScrollDistance) { 213f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition--; 2142a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition); 215bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = getDecoratedTop(getChildAt(0)); 216f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v, 0); 21763c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 218bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = bottom - getDecoratedMeasuredHeight(v); 219bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 220f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (v.isFocusable()) { 221f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell toFocus = v; 222f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 223f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 224f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 225f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 226f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (direction == View.FOCUS_DOWN || direction == View.FOCUS_FORWARD) { 2278b38db9f287670f670f631a0ec4b95882cdd0705Yigit Boyar while (mFirstPosition + getChildCount() < state.getItemCount() && 228f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell newViewsHeight < mScrollDistance) { 2292a1ade8a82653e53f3d5b16c7e9d0ed9cb734101Yigit Boyar View v = recycler.getViewForPosition(mFirstPosition + getChildCount()); 230bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int top = getDecoratedBottom(getChildAt(getChildCount() - 1)); 231f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell addView(v); 23263c8ab9435d707a23e2045af3be410ea7deed895Adam Powell measureChildWithMargins(v, 0, 0); 233bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell final int bottom = top + getDecoratedMeasuredHeight(v); 234bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell layoutDecorated(v, left, top, right, bottom); 235f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (v.isFocusable()) { 236f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell toFocus = v; 237f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell break; 238f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 239f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 240f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 241f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 242f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell return toFocus; 243f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 244f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell 24551edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell public void recycleViewsOutOfBounds(RecyclerView.Recycler recycler) { 24690e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int childCount = getChildCount(); 24790e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentWidth = getWidth(); 24890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final int parentHeight = getHeight(); 249f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell boolean foundFirst = false; 250f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int first = 0; 251f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell int last = 0; 252f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell for (int i = 0; i < childCount; i++) { 25390e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell final View v = getChildAt(i); 254bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell if (v.hasFocus() || (getDecoratedRight(v) >= 0 && 255bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell getDecoratedLeft(v) <= parentWidth && 256bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell getDecoratedBottom(v) >= 0 && 257bfda82df45c6f37f5773917d6f7c918fa3530d49Adam Powell getDecoratedTop(v) <= parentHeight)) { 258f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell if (!foundFirst) { 259f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell first = i; 260f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell foundFirst = true; 261f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 262f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell last = i; 263f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 264f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 265f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell for (int i = childCount - 1; i > last; i--) { 26651edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell removeAndRecycleViewAt(i, recycler); 267f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 26890e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell for (int i = first - 1; i >= 0; i--) { 26951edefe34ae8f6a1a1d08f9596360286a0f2d238Adam Powell removeAndRecycleViewAt(i, recycler); 270f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 27190e0922d7d57ad748b919dfe21c63f03987227e7Adam Powell if (getChildCount() == 0) { 272f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition = 0; 273f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } else { 274f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell mFirstPosition += first; 275f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 276f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 277f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell } 278f6c36bb9b61083b25397a6cff82ddbb102cacfbdAdam Powell} 279