Skip to content

Commit 5a1d41e

Browse files
committed
PROGRESS POINT: Scrolling now works with a decelerated, non-smooth fling override :)
1 parent 26c2928 commit 5a1d41e

2 files changed

Lines changed: 26 additions & 91 deletions

File tree

AndroidFilePickerLightLibrary/src/main/java/com/maxieds/androidfilepickerlightlibrary/FileChooserRecyclerView.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,22 @@ public void setupRecyclerViewLayout() {
7676
}
7777

7878
// We want it to move when flung and be responsive, but keep a constant rate of movement:
79-
private static final int FLING_VELOCITY_DAMPENAT = 1750;
80-
//private static final int FLING_MOVE_BY = 2;
79+
private static final int FLING_VELOCITY_DAMPENAT = 850;
80+
8181

8282
@Override
8383
public boolean fling(int velocityX, int velocityY) {
84-
//Log.i(LOGTAG, "FLUNG at velY = " + velocityY);
8584
if(Math.abs(velocityY) <= FLING_VELOCITY_DAMPENAT) {
8685
return super.fling(0, velocityY);
8786
}
8887
int scaledVelocityY = FLING_VELOCITY_DAMPENAT + (int) ((velocityY - FLING_VELOCITY_DAMPENAT) * Math.exp(-Math.pow(velocityY - FLING_VELOCITY_DAMPENAT, 0.25)));
89-
//Log.i(LOGTAG, "RE-FLUNG at velY = " + scaledVelocityY);
9088
return super.fling(0, scaledVelocityY);
91-
/*int firstVisiblePos = ((LinearLayoutManager) getLayoutManager()).findFirstCompletelyVisibleItemPosition();
92-
boolean flingStatus = false;
93-
if(firstVisiblePos + FLING_MOVE_BY < getLayoutManager().getChildCount()) {
94-
getLayoutManager().smoothScrollToPosition(this, new RecyclerView.State(), firstVisiblePos + FLING_MOVE_BY);
95-
}
96-
return false;*/
9789
}
9890

99-
@Override
91+
/*@Override
10092
public void smoothScrollToPosition(int indexPos) {
10193
getLayoutManager().smoothScrollToPosition(this, new RecyclerView.State(), indexPos);
102-
}
94+
}*/
10395

10496
public interface RecyclerViewSlidingContextWindow {
10597

@@ -131,17 +123,14 @@ public LayoutManager(Context layoutCtx) {
131123
setStackFromEnd(true); // ???
132124
setSmoothScrollbarEnabled(true);
133125
localStaticInst = this;
134-
intendedNextScrollPos = 0;
135-
linearSmoothScroller = null;
136-
scrollInvokingRV = null;
137126
}
138127

139128
@Override
140129
public boolean isAutoMeasureEnabled() {
141130
return true;
142131
}
143132

144-
// intent is to speed it up for the prefetch thread smooth scrolling:
133+
/*// intent is to speed it up for the prefetch thread smooth scrolling:
145134
public static final float SCROLLER_MILLISECONDS_PER_INCH = 16.0f; // larger values slow it down, 25.0 ~ default behavior
146135
147136
private int intendedNextScrollPos;
@@ -172,7 +161,7 @@ else if(!linearSmoothScroller.isRunning()) {
172161
scrollInvokingRV.stopScroll();
173162
scrollInvokingRV.scrollToPosition(intendedNextScrollPos);
174163
return true;
175-
}
164+
}*/
176165

177166
}
178167

AndroidFilePickerLightLibrary/src/main/java/com/maxieds/androidfilepickerlightlibrary/PrefetchFilesUpdater.java

Lines changed: 20 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ This program (the AndroidFilePickerLight library) is free software written by
6363
* and post notifications to the adapter. The scroller (and its listener) know what to do by default when it can just
6464
* smooth scroll through a linear layout with items already available. What results is a nothing too fancy interface to
6565
* avoid the messy UI intensive work in the scroll handler.
66-
*
66+
*
6767
*/
6868
public class PrefetchFilesUpdater extends Thread implements FileChooserRecyclerView.RecyclerViewSlidingContextWindow {
6969

@@ -235,19 +235,6 @@ private void loadInDataAtTopEdge() {
235235

236236
protected Long doInBackground(Void... unusedArgsList) {
237237

238-
// Figure out which edge (if either) needs to get balanced first:
239-
// Basically the procedure is:
240-
// At the start, favor loading in new buffer items from the bottom.
241-
// Once things get going, we want to maintain at least semi-comparable
242-
// buffering on each side. So handle the strange corner situations where:
243-
// IF: BOT wants balance > 0, but if
244-
// TopBufferSize < BAL_BUFFER_SIZE and FirstVisible - TopBufferSize > BottomToBalance,
245-
// THEN: Offer up the loading time to pad the TOP buffer instead.
246-
// OW: If TOP and BOT both want balance > 0, defer to the edge that requires a larger
247-
// balance.
248-
// OW: If only one wants balance > 0, give that one the loading time.
249-
// OW: Break ties by loading at the BOT edge first and/or by loading where there is a smaller
250-
// buffer size currently instated.
251238
if(balanceTopCount > 0 && balanceBottomCount > 0) {
252239
if(balanceTopCount > balanceBottomCount) {
253240
loadInDataAtTopEdge();
@@ -256,31 +243,19 @@ protected Long doInBackground(Void... unusedArgsList) {
256243
loadInDataAtBottomEdge();
257244
}
258245
}
259-
else if(balanceTopCount > 0) {
260-
loadInDataAtTopEdge();
261-
}
262-
else if(topBufferSize < BalancedBufferSize && firstVisibleIndex >= topBufferSize &&
263-
firstVisibleIndex - topBufferSize > balanceBottomCount &&
264-
firstVisibleIndex - topBufferSize - balanceBottomCount < displayCtx.lastFileDataStartIndex) {
265-
balanceTopCount = firstVisibleIndex - topBufferSize - balanceBottomCount;
266-
loadInDataAtTopEdge();
267-
}
268246
else if(balanceBottomCount > 0) {
269247
loadInDataAtBottomEdge();
270248
}
249+
else if(balanceTopCount > 0) {
250+
loadInDataAtTopEdge();
251+
}
271252

272253
return Long.valueOf(0);
273254

274255
}
275256

276257
protected void onPreExecute() {
277258

278-
// Otherwise, weird behaviors arise (make sure the last balance got things
279-
// where they were supposed to be headed):
280-
FileChooserRecyclerView mainRV = displayCtx.getMainRecyclerView();
281-
FileChooserRecyclerView.LayoutManager rvLayoutManager = (FileChooserRecyclerView.LayoutManager) mainRV.getLayoutManager();
282-
rvLayoutManager.completeLastSmoothScroll();
283-
284259
balanceBottomCount = getActiveCountToBalanceBottom();
285260
balanceTopCount = getActiveCountToBalanceTop();
286261
firstVisibleIndex = getLayoutFirstVisibleItemIndex();
@@ -333,7 +308,7 @@ protected void onPostExecute(Long result) {
333308
rvAdapter.notifyItemRangeInserted(updateDataBlock.nextFileNamesList.size() - itemsAppendedCount, itemsAppendedCount);
334309
bottomBufferSize += itemsAppendedCount;
335310
rvAdapter.notifyDataSetChanged();
336-
mainRV.smoothScrollToPosition(prevFirstVisibleIndex);
311+
mainRV.scrollToPosition(prevFirstVisibleIndex);
337312

338313
}
339314
else if(updateDataType.equals(UpdateDataStruct.UpdateDataType.PREPEND_DATA_AT_TOP)) { // Prepend items to top, trim the extra from the bottom:
@@ -359,21 +334,10 @@ else if(updateDataType.equals(UpdateDataStruct.UpdateDataType.PREPEND_DATA_AT_TO
359334
rvAdapter.notifyItemRangeInserted(0, itemsAppendedCount);
360335
topBufferSize += itemsAppendedCount;
361336
rvAdapter.notifyDataSetChanged();
362-
mainRV.smoothScrollToPosition(prevFirstVisibleIndex);
337+
mainRV.scrollToPosition(prevFirstVisibleIndex);
363338

364339
}
365-
else {
366-
return;
367-
}
368-
// We have smooth scrolled. Let it have some brief time to behave itself, otherwise
369-
// kick it along down it's merry way:
370-
final FileChooserRecyclerView.LayoutManager rvLayoutManager = (FileChooserRecyclerView.LayoutManager) mainRV.getLayoutManager();
371-
mainRV.postDelayed(new Runnable() {
372-
@Override
373-
public void run() {
374-
rvLayoutManager.completeLastSmoothScroll();
375-
}
376-
}, 200);
340+
377341
}
378342

379343
}
@@ -448,37 +412,16 @@ else if(size <= 0) {
448412
BalancedBufferSize = size;
449413
}
450414

451-
/*
452-
* Note: Since we cannot load files before the zeroth index in the directory, we need to do some
453-
* accounting to make sure that we really are keeping things balanced as planned.
454-
* Similarly, we cannot load files beyond the last indexed file in the current folder.
455-
*/
456-
457415
public int getActiveCountToBalanceTop() {
458416
if(getActiveLayoutItemsCount() == 0 || getLayoutVisibleDisplaySize() >= getActiveFolderContentsSize()) {
459417
return 0;
460418
}
461-
// Handle competing cases that arise when inflating from the bottom first:
462-
int balanceChoiceCount = 0;
463-
int[] prospectiveBalanceSizes = new int[] { 0, 0 };
464-
if(topBufferSize < Math.min(Math.max(0, getActiveLayoutItemsCount() - getLayoutVisibleDisplaySize() - bottomBufferSize), BalancedBufferSize)) {
465-
// Handles the initialization case (loading the buffer the first time):
466-
prospectiveBalanceSizes[balanceChoiceCount++] =
467-
Math.min(Math.max(0, getActiveLayoutItemsCount() - getLayoutVisibleDisplaySize() - bottomBufferSize), BalancedBufferSize) - topBufferSize;
468-
}
469419
int firstVisibleItemIndex = getLayoutFirstVisibleItemIndex();
470-
int remainingFrontSpace = Math.min(getTopBufferPosition(), BalancedBufferSize);
471-
if(firstVisibleItemIndex >= getTopBufferPosition() && firstVisibleItemIndex - getTopBufferPosition() < remainingFrontSpace) {
472-
prospectiveBalanceSizes[balanceChoiceCount++] = remainingFrontSpace - 1 - firstVisibleItemIndex + getTopBufferPosition();
473-
}
474-
if(balanceChoiceCount == 0) {
475-
return 0;
476-
}
477-
else if(balanceChoiceCount == 1) {
478-
return prospectiveBalanceSizes[0];
420+
if(firstVisibleItemIndex < getTopBufferPosition()) {
421+
return getTopBufferPosition() - firstVisibleItemIndex;
479422
}
480423
else {
481-
return Math.max(prospectiveBalanceSizes[0], prospectiveBalanceSizes[1]);
424+
return 0;
482425
}
483426
}
484427

@@ -492,15 +435,18 @@ public int getActiveCountToBalanceBottom() {
492435
// If layout not initialized, or fits into single window, do not grow the padding buffer:
493436
return 0;
494437
}
495-
else if(bottomBufferSize < Math.min(Math.max(0, getActiveFolderContentsSize() - getLayoutVisibleDisplaySize() - topBufferSize), BalancedBufferSize)) {
496-
// Handles the initialization case (loading the buffer the first time):
497-
return Math.min(Math.max(0, getActiveFolderContentsSize() - getLayoutVisibleDisplaySize() - topBufferSize), BalancedBufferSize) - bottomBufferSize;
438+
int maxBottomBufferSize = Math.min(getActiveFolderContentsSize() - getLayoutVisibleDisplaySize(), BalancedBufferSize);
439+
if(getBottomBufferPosition() + 1 < maxBottomBufferSize) {
440+
return maxBottomBufferSize - 1 - getBottomBufferPosition();
498441
}
499-
int lastVisibleItemIndex = getLayoutLastVisibleItemIndex(); // avoiding a potential race condition when scrolling
500-
int itemsInFolderRemaining = Math.max(0, getActiveFolderContentsSize() - getBottomBufferPosition() - 1);
442+
// Otherwise, the bottom buffer has accumulated maximal size.
443+
// Now adjust when the scroller brings the last visible to less than this size from the last index:
444+
int lastVisibleItemIndex = getLayoutLastVisibleItemIndex();
445+
int maxAdjustedBottomBufferSize = Math.min(BalancedBufferSize,
446+
Math.max(0, getActiveFolderContentsSize() - Math.max(getLayoutVisibleDisplaySize(), lastVisibleItemIndex + 1)));
501447
if(lastVisibleItemIndex <= getBottomBufferPosition() &&
502-
getBottomBufferPosition() - lastVisibleItemIndex < Math.min(itemsInFolderRemaining, BalancedBufferSize)) {
503-
return Math.min(itemsInFolderRemaining, BalancedBufferSize) - 1 - getBottomBufferPosition() + lastVisibleItemIndex;
448+
getBottomBufferPosition() - lastVisibleItemIndex < maxAdjustedBottomBufferSize) {
449+
return maxAdjustedBottomBufferSize - getBottomBufferPosition() + lastVisibleItemIndex;
504450
}
505451
else {
506452
return 0;

0 commit comments

Comments
 (0)