@@ -21,6 +21,7 @@ This program (the AndroidFilePickerLight library) is free software written by
2121import android .content .res .TypedArray ;
2222import android .graphics .Canvas ;
2323import android .graphics .drawable .Drawable ;
24+ import android .util .DisplayMetrics ;
2425import android .util .Log ;
2526import android .view .MotionEvent ;
2627import android .view .View ;
@@ -35,6 +36,7 @@ This program (the AndroidFilePickerLight library) is free software written by
3536import androidx .annotation .NonNull ;
3637import androidx .core .view .ViewCompat ;
3738import androidx .recyclerview .widget .LinearLayoutManager ;
39+ import androidx .recyclerview .widget .LinearSmoothScroller ;
3840import androidx .recyclerview .widget .RecyclerView ;
3941
4042import java .lang .ref .WeakReference ;
@@ -47,7 +49,7 @@ public class DisplayFragments {
4749 private static String LOGTAG = DisplayFragments .class .getSimpleName ();
4850
4951 private static DisplayFragments localStaticInst = new DisplayFragments ();
50- private RecyclerView recyclerView = null ;
52+ private FileChooserRecyclerView recyclerView = null ;
5153
5254 private Drawable folderIconInst ;
5355 private Drawable fileIconInst ;
@@ -68,7 +70,7 @@ public static RecyclerView getMainRecyclerView() {
6870 return getInstance ().recyclerView ;
6971 }
7072
71- public void setRecyclerView (RecyclerView rview ) { recyclerView = rview ; }
73+ public void setRecyclerView (FileChooserRecyclerView rview ) { recyclerView = rview ; }
7274
7375 public static DisplayFragments getInstance () { return FileChooserActivity .getInstance ().getDisplayFragmentsInstance (); }
7476
@@ -97,16 +99,16 @@ public void setCwdFolderContext(DisplayTypes.DirectoryResultContext nextCwdCtx)
9799 public int findFileItemIndexByLayout (View layoutDisplayView ) {
98100 int fileItemIndex = 0 ;
99101 for (DisplayTypes .FileType fileItem : activeFileItemsDataList ) {
100- if (fileItem .getLayoutContainer () != null && fileItem .getLayoutContainer (). equals ( layoutDisplayView ) ) { // ??? TODO: Does this work ???
102+ if (fileItem .getLayoutContainer () != null && fileItem .getLayoutContainer () == layoutDisplayView ) { // ??? TODO: Does this work ???
101103 return fileItemIndex ;
102104 }
103105 ++fileItemIndex ;
104106 }
105107 return -1 ;
106108 }
107109
108- public static final int SCROLL_QUEUE_BUFFER_SIZE = 8 ;
109- public static final int DEFAULT_VIEWPORT_FILE_ITEMS_COUNT = 16 + SCROLL_QUEUE_BUFFER_SIZE ; // large enough to overfill the window on first load
110+ public static final int SCROLL_QUEUE_BUFFER_SIZE = 2 ;
111+ public static final int DEFAULT_VIEWPORT_FILE_ITEMS_COUNT = 16 + SCROLL_QUEUE_BUFFER_SIZE ; // set large enough to overfill the window on first load
110112 private int viewportMaxFileItemsCount = DEFAULT_VIEWPORT_FILE_ITEMS_COUNT ;
111113 public int fileItemDisplayHeight = 0 ;
112114
@@ -128,6 +130,7 @@ public void resetViewportMaxFilesCount(View parentViewContainer) {
128130 setViewportMaxFilesCount (SCROLL_QUEUE_BUFFER_SIZE + (int ) Math .floor ((double ) viewportDisplayHeight / fileItemDisplayHeight ));
129131 Log .i (LOGTAG , String .format ("DELAYED RESPONSE: VP Height = %d, FItemDisp Height = %d ====> %d (with +%d buffer extra)" ,
130132 viewportDisplayHeight , fileItemDisplayHeight , getViewportMaxFilesCount (), SCROLL_QUEUE_BUFFER_SIZE ));
133+ getMainRecyclerView ().setItemViewCacheSize (getViewportMaxFilesCount ()); // ??? TODO ???
131134 viewportCapacityMesaured = true ;
132135 }
133136 }
@@ -150,137 +153,18 @@ public static void updateFolderHistoryPaths(String nextFolderEntryPointPath, boo
150153 }
151154 }
152155
153- public void initializeRecyclerViewLayout (RecyclerView rview ) {
154-
156+ public void initializeRecyclerViewLayout (FileChooserRecyclerView rview ) {
155157 if (!recyclerViewAdapterInit ) {
158+ rview .setupRecyclerViewLayout (this );
156159 setRecyclerView (rview );
157160 fileItemBasePathsList = new ArrayList <String >();
158161 activeSelectionsList = new ArrayList <DisplayTypes .FileType >();
159162 activeFileItemsDataList = new ArrayList <DisplayTypes .FileType >();
160- rview .setHasFixedSize (false );
161- rview .setItemViewCacheSize (0 );
162- rview .setNestedScrollingEnabled (false );
163- LinearLayout .LayoutParams layoutParams = new LinearLayout .LayoutParams (
164- ViewGroup .LayoutParams .MATCH_PARENT ,
165- ViewGroup .LayoutParams .WRAP_CONTENT
166- );
167- rview .setLayoutParams (layoutParams );
168- LinearLayoutManager rvLayoutManager = new LinearLayoutManager (FileChooserActivity .getInstance ()) {
169- @ Override
170- public boolean isAutoMeasureEnabled () {
171- return true ;
172- }
173- };
174- rvLayoutManager .setOrientation (LinearLayoutManager .VERTICAL );
175- rvLayoutManager .setAutoMeasureEnabled (true );
176- rvLayoutManager .setStackFromEnd (true );
177- rview .setLayoutManager ((RecyclerView .LayoutManager ) rvLayoutManager );
178- //rview.addItemDecoration(
179- // new CustomDividerItemDecoration(R.drawable.rview_file_item_divider)
180- //);
181163 DisplayAdapters .FileListAdapter rvAdapter = new DisplayAdapters .FileListAdapter (fileItemBasePathsList , activeFileItemsDataList );
182164 rview .setAdapter (rvAdapter );
183165 resetRecyclerViewLayoutContext ();
184- resetRecyclerViewScrollListeners ();
185166 recyclerViewAdapterInit = true ;
186167 }
187-
188- }
189-
190- private void resetRecyclerViewScrollListeners () {
191- RecyclerView mainFileListRecyclerView = getMainRecyclerView ();
192- mainFileListRecyclerView .setOnScrollListener (new RecyclerView .OnScrollListener () {
193-
194- private static final int SCROLL_BY_ITEMS = SCROLL_QUEUE_BUFFER_SIZE / 2 ;
195- boolean haveProcessedInitScroll = false ;
196-
197- private boolean invokeNewDataLoader () {
198- RecyclerView mainFileListRecyclerView = getMainRecyclerView ();
199- LinearLayoutManager rvLayoutManager = (LinearLayoutManager ) mainFileListRecyclerView .getLayoutManager ();
200- BasicFileProvider fpInst = BasicFileProvider .getInstance ();
201- DisplayTypes .DirectoryResultContext cwdFolderContextLocal = getCwdFolderContext ();
202- if (cwdFolderContextLocal == null ) {
203- Log .i (LOGTAG , "invokeNewDataLoader: CWD CONTEXT IS NULL!" );
204- return false ;
205- }
206- int nextFileItemsLength = getViewportMaxFilesCount ();
207- fpInst .setFilesListLength (SCROLL_BY_ITEMS );
208- if (rvLayoutManager .findLastCompletelyVisibleItemPosition () >= nextFileItemsLength - 1 ) {
209- // Have reached the last item in the list (queue more files below to trigger scrolling):
210- Log .i (LOGTAG , "onScrollStateChanged: SCROLLING DOWN CASE" );
211- getInstance ().lastFileDataEndIndex += SCROLL_BY_ITEMS ;
212- getInstance ().lastFileDataStartIndex += SCROLL_BY_ITEMS ;
213- cwdFolderContextLocal .computeDirectoryContents (getInstance ().lastFileDataStartIndex , getInstance ().lastFileDataEndIndex , SCROLL_BY_ITEMS , 0 , SCROLL_BY_ITEMS , true );
214- displayNextDirectoryFilesList (cwdFolderContextLocal .getWorkingDirectoryContents ());
215- return true ;
216- }
217- else if (rvLayoutManager .findFirstCompletelyVisibleItemPosition () == 0 &&
218- fileItemBasePathsList .size () >= nextFileItemsLength ) {
219- // Have reached the first item in the list (queue more files above to trigger scrolling):
220- Log .i (LOGTAG , "onScrollStateChanged: SCROLLING UP CASE" );
221- if (getInstance ().lastFileDataStartIndex == 0 ) { // cannot scroll more above:
222- return false ;
223- }
224- getInstance ().lastFileDataStartIndex = Math .max (0 , getInstance ().lastFileDataStartIndex - SCROLL_BY_ITEMS );
225- getInstance ().lastFileDataEndIndex = Math .max (0 , getInstance ().lastFileDataEndIndex - SCROLL_BY_ITEMS );
226- cwdFolderContextLocal .computeDirectoryContents (getInstance ().lastFileDataStartIndex , getInstance ().lastFileDataEndIndex , 0 , SCROLL_BY_ITEMS , -SCROLL_BY_ITEMS , true );
227- displayNextDirectoryFilesList (cwdFolderContextLocal .getWorkingDirectoryContents ());
228- fpInst .setFilesListLength (getViewportMaxFilesCount ());
229- return true ;
230- }
231- return false ;
232- }
233-
234- @ Override
235- public void onScrollStateChanged (@ NonNull RecyclerView recyclerView , int nextState ) {
236- Log .i (LOGTAG , "onScrollStateChanged" );
237- DisplayTypes .DirectoryResultContext cwdFolderContextLocal = getCwdFolderContext ();
238- if (cwdFolderContextLocal == null ) {
239- Log .i (LOGTAG , "onScrollStateChanged: CWD CONTEXT IS NULL!" );
240- return ;
241- }
242- BasicFileProvider fpInst = BasicFileProvider .getInstance ();
243- int prevFileItemsLength = getInstance ().viewportMaxFileItemsCount ;
244- if (!getInstance ().viewportCapacityMesaured && getInstance ().getMainRecyclerView ().getLayoutManager ().getChildCount () != 0 ) {
245- fileItemDisplayHeight = getMainRecyclerView ().getLayoutManager ().getChildAt (0 ).getMeasuredHeight ();
246- if (fileItemDisplayHeight > 0 ) {
247- getInstance ().resetViewportMaxFilesCount (FileChooserActivity .getInstance ().findViewById (R .id .mainRecyclerViewContainer ));
248- }
249- }
250- int indexingByNewSizeDiff = getInstance ().viewportMaxFileItemsCount - prevFileItemsLength ;
251- // First, we need to to adjust the working list by any differences in size
252- // caused by reshaping the viewportsize. This needs to be done as soon as possible
253- // to prevent odd behaviors when we wait until we should actually perform the
254- // scrolling operation.
255- if (indexingByNewSizeDiff != 0 ) {
256- Log .i (LOGTAG , "Renormalizing the display size to viewport filling count" );
257- int initTrimFromBackCount = indexingByNewSizeDiff < 0 ? -indexingByNewSizeDiff : 0 ;
258- fpInst .setFilesListLength (Math .abs (indexingByNewSizeDiff ));
259- cwdFolderContextLocal .computeDirectoryContents (
260- getInstance ().lastFileDataStartIndex ,
261- Math .min (getInstance ().lastFileDataStartIndex , getInstance ().lastFileDataEndIndex + indexingByNewSizeDiff ),
262- 0 , initTrimFromBackCount , Math .abs (indexingByNewSizeDiff ), true
263- );
264- displayNextDirectoryFilesList (cwdFolderContextLocal .getWorkingDirectoryContents ());
265- }
266- // Check a corner case to ensure smoother scrolling:
267- if (nextState == RecyclerView .SCROLL_STATE_SETTLING ) {
268- getMainRecyclerView ().stopScroll ();
269- //getMainRecyclerView().stopNestedScroll(ViewCompat.TYPE_TOUCH);
270- }
271- invokeNewDataLoader ();
272- }
273- @ Override
274- public void onScrolled (@ NonNull RecyclerView recyclerView , int deltaX , int deltaY ) {
275- /*if(haveProcessedInitScroll) {
276- invokeNewDataLoader();
277- }
278- else {
279- haveProcessedInitScroll = true;
280- }*/
281- super .onScrolled (recyclerView , deltaX , deltaY );
282- }
283- });
284168 }
285169
286170 public void resetRecyclerViewLayoutContext () {
@@ -349,85 +233,20 @@ public void displayNextDirectoryFilesList(List<DisplayTypes.FileType> workingDir
349233 if (mainFileListRecyclerView == null ) {
350234 return ;
351235 }
236+
352237 activeSelectionsList .clear ();
353238 activeFileItemsDataList .clear ();
354239 fileItemBasePathsList .clear ();
355- LinearLayoutManager rvLayoutManager = (LinearLayoutManager ) mainFileListRecyclerView .getLayoutManager ();
356- //rvLayoutManager.removeAllViews();
357- DisplayAdapters .FileListAdapter rvAdapter = (DisplayAdapters .FileListAdapter ) mainFileListRecyclerView .getAdapter ();
358240
359241 final List <DisplayTypes .FileType > filteredFileContents = workingDirContentsList ;
360242 for (int fidx = 0 ; fidx < filteredFileContents .size (); fidx ++) {
361243 DisplayTypes .FileType fileItem = filteredFileContents .get (fidx );
362244 fileItemBasePathsList .add (fileItem .getBaseName ());
363245 activeFileItemsDataList .add (fileItem );
364246 }
365- //getMainRecyclerView().setAdapter(new DisplayAdapters.FileListAdapter(fileItemBasePathsList, activeFileItemsDataList));
366- //rvAdapter.notifyDataSetChanged();
247+ DisplayAdapters .FileListAdapter rvAdapter = (DisplayAdapters .FileListAdapter ) mainFileListRecyclerView .getAdapter ();
367248 rvAdapter .reloadDataSets (fileItemBasePathsList , activeFileItemsDataList );
368- /*mainFileListRecyclerView.post(new Runnable() {
369- public void run() {
370- ((DisplayAdapters.FileListAdapter) mainFileListRecyclerView.getAdapter()).reloadDataSets(fileItemBasePathsList, activeFileItemsDataList);
371- }
372- });*/
373-
374- }
375-
376- public static class CustomDividerItemDecoration extends RecyclerView .ItemDecoration {
377-
378- private static final int [] DIVIDER_DEFAULT_ATTRS = new int []{
379- android .R .attr .listDivider ,
380- android .R .attr .verticalDivider ,
381- android .R .attr .horizontalDivider
382- };
383- private Drawable listingsDivider ;
384-
385- public static final int LIST_DIVIDER_STYLE_INDEX = 0 ;
386- public static final int DEFAULT_DIVIDER_STYLE_INDEX = 1 ;
387-
388- public CustomDividerItemDecoration (Context ctx , int dividerTypeIndex , boolean dividerTypeIsVertical ) {
389- final TypedArray styledDefaultAttributes = ctx .obtainStyledAttributes (DIVIDER_DEFAULT_ATTRS );
390- if (dividerTypeIndex != LIST_DIVIDER_STYLE_INDEX ) {
391- dividerTypeIndex = DEFAULT_DIVIDER_STYLE_INDEX + (dividerTypeIsVertical ? 0 : 1 );
392- }
393- listingsDivider = styledDefaultAttributes .getDrawable (dividerTypeIndex );
394- styledDefaultAttributes .recycle ();
395- }
396249
397- public CustomDividerItemDecoration (int resId ) {
398- listingsDivider = GradientDrawableFactory .getDrawableFromResource (resId );
399- }
400-
401- public static void setMarginAdjustments (int leftAdjust , int topAdjust , int rightAdjust , int bottomAdjust ) {
402- MARGIN_RIGHT_ADJUST = rightAdjust ;
403- MARGIN_LEFT_ADJUST = leftAdjust ;
404- MARGIN_TOP_ADJUST = topAdjust ;
405- MARGIN_BOTTOM_ADJUST = bottomAdjust ;
406- }
407-
408- private static int MARGIN_RIGHT_ADJUST = 35 ;
409- private static int MARGIN_LEFT_ADJUST = 35 ;
410- private static int MARGIN_TOP_ADJUST = 0 ;
411- private static int MARGIN_BOTTOM_ADJUST = 0 ;
412-
413- @ Override
414- public void onDraw (Canvas displayCanvas , RecyclerView parentContainerView , RecyclerView .State rvState ) {
415-
416- int leftMargin = parentContainerView .getPaddingLeft () + MARGIN_LEFT_ADJUST ;
417- int rightMargin = parentContainerView .getWidth () - parentContainerView .getPaddingRight () - MARGIN_RIGHT_ADJUST ;
418-
419- for (int i = 0 ; i < parentContainerView .getChildCount (); i ++) {
420-
421- View childView = parentContainerView .getChildAt (i );
422- RecyclerView .LayoutParams params = (RecyclerView .LayoutParams ) childView .getLayoutParams ();
423- int topMargin = childView .getBottom () + params .bottomMargin + MARGIN_TOP_ADJUST ;
424- int bottomMargin = topMargin + listingsDivider .getIntrinsicHeight () + MARGIN_BOTTOM_ADJUST ;
425- listingsDivider .setBounds (leftMargin , topMargin , rightMargin , bottomMargin );
426- listingsDivider .draw (displayCanvas );
427-
428- }
429-
430- }
431250 }
432251
433252 public static class FileListItemFragment {
0 commit comments