Skip to content

Commit a79a7ed

Browse files
committed
Preliminary implementation of custom theming properties (needs testing)
1 parent 156bbf7 commit a79a7ed

17 files changed

Lines changed: 1032 additions & 242 deletions

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,4 +686,14 @@ public String[] getPropertiesOfCurrentRow(MatrixCursor mcResult, boolean cursorT
686686
}
687687
}
688688

689+
/* TODO: Later functionality for the local BasicFileProvider: */
690+
public StringBuilder readFileContentsAsString() {
691+
return null;
692+
}
693+
694+
/* TODO: Later functionality for the local BasicFileProvider: */
695+
public byte[] readFileContentsAsBytesArray() {
696+
return null;
697+
}
698+
689699
}

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

Lines changed: 497 additions & 32 deletions
Large diffs are not rendered by default.

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

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,6 @@ public class DisplayFragments {
3939
private static DisplayFragments localStaticInst = new DisplayFragments();
4040
private FileChooserRecyclerView recyclerView = null;
4141

42-
private Drawable folderIconInst;
43-
private Drawable fileIconInst;
44-
private Drawable hiddenFileIconInst;
45-
46-
public FileFilter.FileFilterBase localFilesListFilter;
47-
public FileFilter.FileItemsSortFunc localFilesListSortFunc;
48-
4942
public DisplayFragments() {
5043
folderIconInst = DisplayUtils.getDrawableFromResource(R.drawable.folder_icon32);
5144
fileIconInst = DisplayUtils.getDrawableFromResource(R.drawable.generic_file_icon32);
@@ -54,6 +47,27 @@ public DisplayFragments() {
5447
localFilesListSortFunc = null;
5548
}
5649

50+
public FileFilter.FileFilterBase localFilesListFilter;
51+
public FileFilter.FileItemsSortFunc localFilesListSortFunc;
52+
53+
private Drawable folderIconInst;
54+
private Drawable fileIconInst;
55+
private Drawable hiddenFileIconInst;
56+
private CustomThemeBuilder.FileItemLayoutStylizer fileItemLayoutStylizer;
57+
58+
public boolean setFileItemLayoutStylizer(CustomThemeBuilder.FileItemLayoutStylizer layoutStylizer, boolean freeOtherSpace) {
59+
if(layoutStylizer == null) {
60+
return false;
61+
}
62+
fileItemLayoutStylizer = layoutStylizer;
63+
if(freeOtherSpace) {
64+
folderIconInst = fileIconInst = hiddenFileIconInst = null;
65+
}
66+
return true;
67+
}
68+
69+
public CustomThemeBuilder.FileItemLayoutStylizer getFileItemLayoutStylizer() { return fileItemLayoutStylizer; }
70+
5771
public static FileChooserRecyclerView getMainRecyclerView() {
5872
return getInstance().recyclerView;
5973
}
@@ -98,7 +112,6 @@ private void setViewportMaxFilesCount(int viewportFilesCap) {
98112

99113
public boolean resetViewportMaxFilesCount(View parentViewContainer) {
100114
if(!viewportCapacityMesaured) {
101-
102115
int viewportDisplayHeight = parentViewContainer.getMeasuredHeight();
103116
if(fileItemDisplayHeight == 0 || viewportDisplayHeight == 0) {
104117
return false;
@@ -110,13 +123,14 @@ public boolean resetViewportMaxFilesCount(View parentViewContainer) {
110123
getMainRecyclerView().setDrawingCacheEnabled(true);
111124
getMainRecyclerView().setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
112125
viewportCapacityMesaured = true;
113-
114126
}
115127
return true;
116128
}
117129

118-
public void initializeRecyclerViewLayout(FileChooserRecyclerView rview) {
130+
public void initializeRecyclerViewLayout(FileChooserRecyclerView rview, FileChooserBuilder fpConfig) {
119131
if(!recyclerViewAdapterInit) {
132+
viewportMaxFileItemsCount = fpConfig.getRecyclerViewStartBufferSize();
133+
FileChooserRecyclerView.setFlingVelocityDampenAtThreshold(fpConfig.getRecyclerViewLayoutFlingDampenThreshold());
120134
rview.setupRecyclerViewLayout();
121135
setRecyclerView(rview);
122136
fileItemBasePathsList = new ArrayList<String>();
@@ -133,9 +147,9 @@ public void resetRecyclerViewLayoutContext() {
133147
activeSelectionsList.clear();
134148
activeFileItemsDataList.clear();
135149
fileItemBasePathsList.clear();
136-
lastFileDataStartIndex = 0;
137-
lastFileDataEndIndex = DEFAULT_VIEWPORT_FILE_ITEMS_COUNT - 1;
138150
viewportMaxFileItemsCount = DEFAULT_VIEWPORT_FILE_ITEMS_COUNT;
151+
lastFileDataStartIndex = 0;
152+
lastFileDataEndIndex = viewportMaxFileItemsCount - 1;
139153
recyclerViewAdapterInit = false;
140154
viewportCapacityMesaured = false;
141155
pathHistoryStack = new Stack<DisplayTypes.DirectoryResultContext>();
@@ -245,18 +259,23 @@ public static class FileItemFragment {
245259

246260
public static void resetLayout(View layoutContainer, DisplayTypes.FileType fileItem, int displayPosition) {
247261

248-
ImageView fileTypeIcon = layoutContainer.findViewById(R.id.fileTypeIcon);
249-
if(!fileItem.isDirectory()) {
250-
if(!fileItem.isHidden()) {
251-
fileTypeIcon.setImageDrawable(getInstance().fileIconInst);
252-
}
253-
else {
254-
fileTypeIcon.setImageDrawable(getInstance().hiddenFileIconInst);
262+
CustomThemeBuilder.FileItemLayoutStylizer fileItemLayoutStylizer = DisplayFragments.getInstance().getFileItemLayoutStylizer();
263+
if(fileItemLayoutStylizer == null) {
264+
ImageView fileTypeIcon = layoutContainer.findViewById(R.id.fileTypeIcon);
265+
if (!fileItem.isDirectory()) {
266+
if (!fileItem.isHidden()) {
267+
fileTypeIcon.setImageDrawable(getInstance().fileIconInst);
268+
} else {
269+
fileTypeIcon.setImageDrawable(getInstance().hiddenFileIconInst);
270+
}
271+
} else {
272+
fileTypeIcon.setImageDrawable(getInstance().folderIconInst);
255273
}
256274
}
257275
else {
258-
fileTypeIcon.setImageDrawable(getInstance().folderIconInst);
276+
fileItemLayoutStylizer.applyStyleToLayout(layoutContainer, fileItem);
259277
}
278+
260279
TextView fileSizeText = layoutContainer.findViewById(R.id.fileEntrySizeText);
261280
fileSizeText.setText(fileItem.getFileSizeString());
262281
TextView filePermsSummary = layoutContainer.findViewById(R.id.fileEntryPermsSummaryText);

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

Lines changed: 157 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This program (the AndroidFilePickerLight library) is free software written by
1818
package com.maxieds.androidfilepickerlightlibrary;
1919

2020
import android.app.Activity;
21+
import android.graphics.Color;
2122
import android.graphics.PorterDuff;
2223
import android.graphics.Typeface;
2324
import android.graphics.drawable.Drawable;
@@ -32,69 +33,194 @@ This program (the AndroidFilePickerLight library) is free software written by
3233
import android.widget.Toast;
3334

3435
import androidx.annotation.ColorInt;
36+
import androidx.annotation.DrawableRes;
37+
import androidx.annotation.StringRes;
3538

3639
import java.util.Locale;
3740

3841
public class DisplayUtils {
3942

4043
private static String LOGTAG = DisplayUtils.class.getSimpleName();
4144

42-
private static Activity defaultActivityContextRef = FileChooserActivity.getInstance();
43-
public static void setDefaultActivityContext(Activity activityContextRef) {
44-
defaultActivityContextRef = activityContextRef;
45+
public static int getColorVariantFromTheme(Activity activityRef, int attrID) throws FileChooserException.InvalidActivityContextException {
46+
if(activityRef == null) {
47+
throw new FileChooserException.InvalidThemeResourceException();
48+
}
49+
return activityRef.getTheme().obtainStyledAttributes(new int[] { attrID }).getColor(0, attrID);
50+
}
51+
52+
public static int getColorVariantFromTheme(int attrID) throws FileChooserException.InvalidActivityContextException {
53+
return getColorVariantFromTheme(FileChooserActivity.getInstance(), attrID);
4554
}
4655

47-
@ColorInt
48-
public static int getColorVariantFromTheme(int attrID) {
49-
if(defaultActivityContextRef == null) {
50-
setDefaultActivityContext(FileChooserActivity.getInstance());
56+
public static int getColorFromResource(Activity activityRef, int colorRefID) throws FileChooserException.InvalidActivityContextException {
57+
if(activityRef == null) {
58+
throw new FileChooserException.InvalidThemeResourceException();
5159
}
52-
return defaultActivityContextRef.getTheme().obtainStyledAttributes(new int[] { attrID }).getColor(0, attrID);
60+
return activityRef.getResources().getColor(colorRefID, activityRef.getTheme());
5361
}
5462

5563
public static int getColorFromResource(int colorRefID) throws FileChooserException.InvalidActivityContextException {
56-
if(defaultActivityContextRef == null) {
57-
setDefaultActivityContext(FileChooserActivity.getInstance());
64+
return getColorFromResource(FileChooserActivity.getInstance(), colorRefID);
65+
}
66+
67+
public static Drawable getDrawableFromResource(Activity activityRef, int drawableRefID) throws FileChooserException.InvalidActivityContextException {
68+
if(activityRef == null) {
69+
throw new FileChooserException.InvalidThemeResourceException();
5870
}
59-
return defaultActivityContextRef.getResources().getColor(colorRefID, defaultActivityContextRef.getTheme());
71+
return activityRef.getResources().getDrawable(drawableRefID, activityRef.getTheme());
6072
}
6173

6274
public static Drawable getDrawableFromResource(int drawableRefID) throws FileChooserException.InvalidActivityContextException {
63-
if(defaultActivityContextRef == null) {
64-
setDefaultActivityContext(FileChooserActivity.getInstance());
75+
return getDrawableFromResource(FileChooserActivity.getInstance(), drawableRefID);
76+
}
77+
78+
public static String getStringFromResource(Activity activityRef, int strRefID) throws FileChooserException.InvalidActivityContextException {
79+
if(activityRef == null) {
80+
throw new FileChooserException.InvalidThemeResourceException();
6581
}
66-
return defaultActivityContextRef.getResources().getDrawable(drawableRefID, defaultActivityContextRef.getTheme());
82+
return activityRef.getString(strRefID);
6783
}
6884

6985
public static String getStringFromResource(int strRefID) throws FileChooserException.InvalidActivityContextException {
70-
if(defaultActivityContextRef == null) {
71-
setDefaultActivityContext(FileChooserActivity.getInstance());
86+
return getStringFromResource(FileChooserActivity.getInstance(), strRefID);
87+
}
88+
89+
public static String resolveStringFromAttribute(Activity activityRef, int attrID) throws FileChooserException.InvalidActivityContextException {
90+
if(activityRef == null) {
91+
throw new FileChooserException.InvalidThemeResourceException();
7292
}
73-
return defaultActivityContextRef.getString(strRefID);
93+
TypedValue typedValueAttr = new TypedValue();
94+
activityRef.getTheme().resolveAttribute(attrID, typedValueAttr, true);
95+
return activityRef.getString(typedValueAttr.resourceId);
7496
}
7597

76-
public static int resolveColorFromAttribute(int attrID) {
77-
if(defaultActivityContextRef == null) {
78-
setDefaultActivityContext(FileChooserActivity.getInstance());
98+
public static String resolveStringFromAttribute(int attrID) throws FileChooserException.InvalidActivityContextException {
99+
return resolveStringFromAttribute(FileChooserActivity.getInstance(), attrID);
100+
}
101+
102+
public static String resolveStringFromResId(Activity activityCtxRef, @StringRes int resId) {
103+
try {
104+
return DisplayUtils.getStringFromResource(activityCtxRef, resId);
105+
} catch(Exception ex) {
106+
try {
107+
return DisplayUtils.resolveStringFromAttribute(activityCtxRef, resId);
108+
} catch(Exception ex2) {
109+
return null;
110+
}
79111
}
80-
if(defaultActivityContextRef == null) {
112+
}
113+
114+
public static String resolveStringFromResId(@StringRes int resId) {
115+
return resolveStringFromResId(FileChooserActivity.getInstance(), resId);
116+
}
117+
118+
public static int resolveColorFromAttribute(Activity activityRef, int attrID) throws FileChooserException.InvalidActivityContextException {
119+
if(activityRef == null) {
81120
throw new FileChooserException.InvalidThemeResourceException();
82121
}
83122
TypedValue typedValueAttr = new TypedValue();
84-
defaultActivityContextRef.getTheme().resolveAttribute(attrID, typedValueAttr, true);
123+
activityRef.getTheme().resolveAttribute(attrID, typedValueAttr, true);
85124
return typedValueAttr.data;
86125
}
87126

88-
public static Drawable resolveDrawableFromAttribute(int attrID) {
89-
if(defaultActivityContextRef == null) {
90-
setDefaultActivityContext(FileChooserActivity.getInstance());
127+
public static int resolveColorFromAttribute(int attrID) throws FileChooserException.InvalidActivityContextException {
128+
return resolveColorFromAttribute(FileChooserActivity.getInstance(), attrID);
129+
}
130+
131+
public static int resolveColorFromResId(Activity activityRef, int resID) throws FileChooserException.InvalidActivityContextException {
132+
if(activityRef == null) {
133+
throw new FileChooserException.InvalidThemeResourceException();
91134
}
92-
if(defaultActivityContextRef == null) {
135+
try {
136+
return getColorVariantFromTheme(activityRef, resID);
137+
} catch(Exception ex) {
138+
try {
139+
return getColorFromResource(activityRef, resID);
140+
} catch(Exception ex2) {
141+
try {
142+
return resolveColorFromAttribute(activityRef, resID);
143+
}
144+
catch(Exception ex3) {
145+
return resID;
146+
}
147+
}
148+
}
149+
}
150+
151+
public static int resolveColorFromResId(int resID) throws FileChooserException.InvalidActivityContextException {
152+
return resolveColorFromResId(FileChooserActivity.getInstance(), resID);
153+
}
154+
155+
156+
157+
public static Drawable resolveDrawableFromAttribute(Activity activityRef, int attrID) throws FileChooserException.InvalidActivityContextException {
158+
if(activityRef == null) {
93159
throw new FileChooserException.InvalidThemeResourceException();
94160
}
95161
TypedValue typedValueAttr = new TypedValue();
96-
defaultActivityContextRef.getTheme().resolveAttribute(attrID, typedValueAttr, true);
97-
return defaultActivityContextRef.getDrawable(typedValueAttr.resourceId);
162+
activityRef.getTheme().resolveAttribute(attrID, typedValueAttr, true);
163+
return activityRef.getDrawable(typedValueAttr.resourceId);
164+
}
165+
166+
public static Drawable resolveDrawableFromAttribute(int attrID) throws FileChooserException.InvalidActivityContextException {
167+
return resolveDrawableFromAttribute(FileChooserActivity.getInstance(), attrID);
168+
}
169+
170+
public static Drawable resolveDrawableFromResId(Activity activityCtxRef, @DrawableRes int resId) {
171+
try {
172+
return DisplayUtils.getDrawableFromResource(activityCtxRef, resId);
173+
} catch(Exception ex) {
174+
try {
175+
return DisplayUtils.resolveDrawableFromAttribute(activityCtxRef, resId);
176+
} catch(Exception ex2) {
177+
return null;
178+
}
179+
}
180+
}
181+
182+
public static Drawable resolveDrawableFromResId(@DrawableRes int resId) {
183+
return resolveDrawableFromResId(FileChooserActivity.getInstance(), resId);
184+
}
185+
186+
public static int lightenColor(int color, float percentToLighten) {
187+
if(percentToLighten < 0.0f || percentToLighten > 1.0f) {
188+
return color;
189+
}
190+
float[] hsvColorComps = new float[3];
191+
Color.colorToHSV(color, hsvColorComps);
192+
hsvColorComps[2] = 1.0f - percentToLighten * (1.0f - hsvColorComps[2]);
193+
return Color.HSVToColor(hsvColorComps);
194+
}
195+
196+
public static int darkenColor(int color, float percentToDarken) {
197+
if(percentToDarken < 0.0f || percentToDarken > 1.0f) {
198+
return color;
199+
}
200+
float[] hsvColorComps = new float[3];
201+
Color.colorToHSV(color, hsvColorComps);
202+
hsvColorComps[2] = percentToDarken * hsvColorComps[2];
203+
return Color.HSVToColor(hsvColorComps);
204+
}
205+
206+
public static boolean checkIconDimensions(Drawable iconInput, int dimsHeight, int dimsWidth) {
207+
if(iconInput == null) {
208+
return false;
209+
}
210+
return (iconInput.getIntrinsicHeight() == dimsHeight) && (iconInput.getIntrinsicWidth() == dimsWidth);
211+
}
212+
213+
public static boolean checkIconDimensions(Drawable iconInput, int dimsHW) {
214+
return checkIconDimensions(iconInput, dimsHW, dimsHW);
215+
}
216+
217+
public static <T extends Object> T firstNonNull(T firstObj, T secondObj) {
218+
if(firstObj != null) {
219+
return firstObj;
220+
}
221+
else {
222+
return secondObj;
223+
}
98224
}
99225

100226
private static void displayToastMessage(Activity activityInst, String toastMsg, int msgDuration) {
@@ -326,7 +452,7 @@ else if(borderStyleSpec == BorderStyleSpec.BORDER_STYLE_DASHED_LONG)
326452
gradientDrawObj.setStroke(borderWidth, borderColor, 25, 10);
327453
else if(borderStyleSpec == BorderStyleSpec.BORDER_STYLE_DASHED_SHORT)
328454
gradientDrawObj.setStroke(borderWidth, borderColor, 4, 10);
329-
//gradientDrawObj.setUseLevel(true);
455+
gradientDrawObj.setUseLevel(true);
330456
return gradientDrawObj;
331457
}
332458

@@ -335,7 +461,7 @@ public static GradientDrawable generateNamedGradientType(BorderStyleSpec borderS
335461
NamedGradientColorThemes namedColorTheme) {
336462
GradientMethodSpec gmethodSpec;
337463
GradientTypeSpec gfillTypeSpec;
338-
float angleSpec = 0.5f;
464+
float angleSpec = 45.0f; // Must be a multiple of 45.0f
339465
int[] colorList;
340466
switch(namedColorTheme) {
341467
case NAMED_COLOR_SCHEME_TURQUOISE:
@@ -412,7 +538,7 @@ public static GradientDrawable generateNamedGradientType(BorderStyleSpec borderS
412538
};
413539
break;
414540
case NAMED_COLOR_SCHEME_FIRE_BRIMSTONE:
415-
gmethodSpec = GradientMethodSpec.GRADIENT_METHOD_RADIAL;
541+
gmethodSpec = GradientMethodSpec.GRADIENT_METHOD_LINEAR;
416542
gfillTypeSpec = GradientTypeSpec.GRADIENT_FILL_TYPE_BL_TR;
417543
angleSpec = 45.0f;
418544
colorList = new int[] {

0 commit comments

Comments
 (0)