mirror of
https://github.com/f-droid/fdroidclient.git
synced 2026-05-24 16:35:49 -04:00
[app] Fix all warnings in AppDetailsRecyclerViewAdapter
This commit is contained in:
@@ -18,6 +18,7 @@ import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -173,7 +174,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
if (apks != null) suggestedApk = app.findSuggestedApk(apks, appPrefs);
|
||||
|
||||
addItem(VIEWTYPE_HEADER);
|
||||
if (app.getAllScreenshots().size() > 0) addItem(VIEWTYPE_SCREENSHOTS);
|
||||
if (!app.getAllScreenshots().isEmpty()) addItem(VIEWTYPE_SCREENSHOTS);
|
||||
addItem(VIEWTYPE_DONATE);
|
||||
addItem(VIEWTYPE_LINKS);
|
||||
addItem(VIEWTYPE_PERMISSIONS);
|
||||
@@ -187,6 +188,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
setShowVersions(true);
|
||||
}
|
||||
}
|
||||
//noinspection NotifyDataSetChanged // too hard to know what exactly has changed
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@@ -214,7 +216,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
setShowVersions(showVersions, false);
|
||||
}
|
||||
|
||||
void setShowVersions(boolean showVersions, boolean scrollTo) {
|
||||
private void setShowVersions(boolean showVersions, boolean scrollTo) {
|
||||
this.showVersions = showVersions;
|
||||
boolean itemsWereRemoved = items.removeAll(versions);
|
||||
int startIndex = items.indexOf(VIEWTYPE_VERSIONS) + 1;
|
||||
@@ -227,19 +229,8 @@ public class AppDetailsRecyclerViewAdapter
|
||||
items.addAll(startIndex, versions);
|
||||
notifyItemRangeInserted(startIndex, versions.size());
|
||||
if (recyclerView != null && scrollTo) {
|
||||
final LinearSmoothScroller smoothScroller = new LinearSmoothScroller(context) {
|
||||
@Override
|
||||
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
|
||||
// The default speed of smooth scrolling doesn't look good
|
||||
// and it's too fast when it happens while inserting
|
||||
// multiple recycler view items
|
||||
return 75f / displayMetrics.densityDpi;
|
||||
}
|
||||
};
|
||||
// Expanding the version list reveals up to 5 items by default
|
||||
int visibleVersionLimit = Math.min(versions.size(), 5);
|
||||
smoothScroller.setTargetPosition(startIndex + visibleVersionLimit - 1);
|
||||
recyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
|
||||
final LinearSmoothScroller smoothScroller = getLinearSmoothScroller(startIndex);
|
||||
Objects.requireNonNull(recyclerView.getLayoutManager()).startSmoothScroll(smoothScroller);
|
||||
}
|
||||
} else if (itemsWereRemoved) {
|
||||
notifyItemRangeRemoved(startIndex, versions.size());
|
||||
@@ -249,6 +240,23 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private LinearSmoothScroller getLinearSmoothScroller(int startIndex) {
|
||||
final LinearSmoothScroller smoothScroller = new LinearSmoothScroller(context) {
|
||||
@Override
|
||||
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
|
||||
// The default speed of smooth scrolling doesn't look good
|
||||
// and it's too fast when it happens while inserting
|
||||
// multiple recycler view items
|
||||
return 75f / displayMetrics.densityDpi;
|
||||
}
|
||||
};
|
||||
// Expanding the version list reveals up to 5 items by default
|
||||
int visibleVersionLimit = Math.min(versions.size(), 5);
|
||||
smoothScroller.setTargetPosition(startIndex + visibleVersionLimit - 1);
|
||||
return smoothScroller;
|
||||
}
|
||||
|
||||
private void addItem(int item) {
|
||||
// Gives us a chance to hide sections that are not used, e.g. the donate section when
|
||||
// we have no donation links.
|
||||
@@ -265,7 +273,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
// Figure out if we should show permissions section
|
||||
Apk curApk = app.installedApk == null ? suggestedApk : app.installedApk;
|
||||
final boolean curApkCompatible = curApk != null && curApk.compatible;
|
||||
return versions.size() > 0 && (curApkCompatible || Preferences.get().showIncompatibleVersions());
|
||||
return !versions.isEmpty() && (curApkCompatible || Preferences.get().showIncompatibleVersions());
|
||||
}
|
||||
|
||||
private boolean shouldShowDonate() {
|
||||
@@ -314,36 +322,45 @@ public class AppDetailsRecyclerViewAdapter
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
switch (viewType) {
|
||||
case VIEWTYPE_HEADER:
|
||||
return switch (viewType) {
|
||||
case VIEWTYPE_HEADER -> {
|
||||
View header = inflater.inflate(R.layout.app_details2_header, parent, false);
|
||||
return new HeaderViewHolder(header);
|
||||
case VIEWTYPE_SCREENSHOTS:
|
||||
yield new HeaderViewHolder(header);
|
||||
}
|
||||
case VIEWTYPE_SCREENSHOTS -> {
|
||||
View screenshots = inflater.inflate(R.layout.app_details2_screenshots, parent, false);
|
||||
return new ScreenShotsViewHolder(screenshots);
|
||||
case VIEWTYPE_DONATE:
|
||||
yield new ScreenShotsViewHolder(screenshots);
|
||||
}
|
||||
case VIEWTYPE_DONATE -> {
|
||||
View donate = inflater.inflate(R.layout.app_details2_donate, parent, false);
|
||||
return new DonateViewHolder(donate);
|
||||
case VIEWTYPE_LINKS:
|
||||
yield new DonateViewHolder(donate);
|
||||
}
|
||||
case VIEWTYPE_LINKS -> {
|
||||
View links = inflater.inflate(R.layout.app_details2_links, parent, false);
|
||||
return new LinksViewHolder(links);
|
||||
case VIEWTYPE_PERMISSIONS:
|
||||
yield new LinksViewHolder(links);
|
||||
}
|
||||
case VIEWTYPE_PERMISSIONS -> {
|
||||
View permissions = inflater.inflate(R.layout.app_details2_links, parent, false);
|
||||
return new PermissionsViewHolder(permissions);
|
||||
case VIEWTYPE_VERSIONS:
|
||||
yield new PermissionsViewHolder(permissions);
|
||||
}
|
||||
case VIEWTYPE_VERSIONS -> {
|
||||
View versionsView = inflater.inflate(R.layout.app_details2_links, parent, false);
|
||||
return new VersionsViewHolder(versionsView);
|
||||
case VIEWTYPE_NO_VERSIONS:
|
||||
yield new VersionsViewHolder(versionsView);
|
||||
}
|
||||
case VIEWTYPE_NO_VERSIONS -> {
|
||||
View noVersionsView = inflater.inflate(R.layout.app_details2_links, parent, false);
|
||||
return new NoVersionsViewHolder(noVersionsView);
|
||||
case VIEWTYPE_VERSIONS_LOADING:
|
||||
yield new NoVersionsViewHolder(noVersionsView);
|
||||
}
|
||||
case VIEWTYPE_VERSIONS_LOADING -> {
|
||||
View loadingView = inflater.inflate(R.layout.app_details2_loading, parent, false);
|
||||
return new VersionsLoadingViewHolder(loadingView);
|
||||
case VIEWTYPE_VERSION:
|
||||
yield new VersionsLoadingViewHolder(loadingView);
|
||||
}
|
||||
case VIEWTYPE_VERSION -> {
|
||||
View version = inflater.inflate(R.layout.app_details2_version_item, parent, false);
|
||||
return new VersionViewHolder(version);
|
||||
}
|
||||
return null;
|
||||
yield new VersionViewHolder(version);
|
||||
}
|
||||
default -> throw new IllegalStateException("Unknown view type: " + viewType);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -601,8 +618,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
descriptionView.setText(trimTrailingNewlines(desc));
|
||||
LinkifyCompat.addLinks(descriptionView, Linkify.WEB_URLS);
|
||||
|
||||
if (descriptionView.getText() instanceof Spannable) {
|
||||
Spannable spannable = (Spannable) descriptionView.getText();
|
||||
if (descriptionView.getText() instanceof Spannable spannable) {
|
||||
URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
|
||||
for (URLSpan span : spans) {
|
||||
int start = spannable.getSpanStart(span);
|
||||
@@ -664,13 +680,13 @@ public class AppDetailsRecyclerViewAdapter
|
||||
viewIntent.setDataAndType(uri, mimeType);
|
||||
viewIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
||||
if (context.getPackageManager().queryIntentActivities(viewIntent, 0).size() > 0) {
|
||||
if (!context.getPackageManager().queryIntentActivities(viewIntent, 0).isEmpty()) {
|
||||
buttonPrimaryView.setText(R.string.menu_open);
|
||||
buttonPrimaryView.setOnClickListener(v -> {
|
||||
try {
|
||||
context.startActivity(viewIntent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "Error starting activity: ", e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -711,7 +727,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
|
||||
private void updateAntiFeaturesWarning() {
|
||||
if (app.antiFeatures == null || app.antiFeatures.length == 0) {
|
||||
if (app != null && (app.antiFeatures == null || app.antiFeatures.length == 0)) {
|
||||
antiFeaturesSectionView.setVisibility(View.GONE);
|
||||
} else if (descriptionIsExpanded) {
|
||||
antiFeaturesSectionView.setVisibility(View.VISIBLE);
|
||||
@@ -776,7 +792,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
context.startActivity(ScreenShotsActivity.getStartIntent(context, app.repoId, screenshots, position));
|
||||
}
|
||||
|
||||
private class ItemDecorator extends RecyclerView.ItemDecoration {
|
||||
private static class ItemDecorator extends RecyclerView.ItemDecoration {
|
||||
private final Context context;
|
||||
|
||||
ItemDecorator(Context context) {
|
||||
@@ -784,7 +800,8 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, RecyclerView parent,
|
||||
@NonNull RecyclerView.State state) {
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
int padding = (int) context.getResources().getDimension(R.dimen.details_activity_padding_screenshot);
|
||||
if (position == 0) {
|
||||
@@ -885,7 +902,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
* Depending on whether we are expanded or not, update the icon which indicates whether the
|
||||
* user can expand/collapse this item.
|
||||
*/
|
||||
protected void updateExpandableItem(boolean isExpanded) {
|
||||
void updateExpandableItem(boolean isExpanded) {
|
||||
final int icon = getIcon();
|
||||
Drawable iconDrawable = ContextCompat.getDrawable(headerView.getContext(), icon);
|
||||
final Drawable expandLess = ContextCompat.getDrawable(headerView.getContext(), R.drawable.ic_expand_less);
|
||||
@@ -923,8 +940,8 @@ public class AppDetailsRecyclerViewAdapter
|
||||
NoVersionsViewHolder(View view) {
|
||||
super(view);
|
||||
headerView = view.findViewById(R.id.information);
|
||||
final Drawable accessTime = DrawableCompat.wrap(ContextCompat.getDrawable(headerView.getContext(),
|
||||
R.drawable.ic_versions)).mutate();
|
||||
final Drawable versions = ContextCompat.getDrawable(headerView.getContext(), R.drawable.ic_versions);
|
||||
final Drawable accessTime = DrawableCompat.wrap(Objects.requireNonNull(versions)).mutate();
|
||||
DrawableCompat.setTint(accessTime, Color.parseColor("#B4B4B4"));
|
||||
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(headerView,
|
||||
accessTime, null, null, null);
|
||||
@@ -976,11 +993,11 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
|
||||
private boolean hasCompatibleApksDifferentSigners() {
|
||||
return compatibleVersionsDifferentSigner.size() > 0;
|
||||
return !compatibleVersionsDifferentSigner.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private class VersionsLoadingViewHolder extends AppDetailsViewHolder {
|
||||
private static class VersionsLoadingViewHolder extends AppDetailsViewHolder {
|
||||
VersionsLoadingViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
@@ -1002,8 +1019,9 @@ public class AppDetailsRecyclerViewAdapter
|
||||
boolean shouldBeVisible = contentView.getVisibility() != View.VISIBLE;
|
||||
contentView.setVisibility(shouldBeVisible ? View.VISIBLE : View.GONE);
|
||||
updateExpandableItem(shouldBeVisible);
|
||||
if (shouldBeVisible && recyclerView != null) {
|
||||
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(items.indexOf(VIEWTYPE_PERMISSIONS), 0);
|
||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
if (shouldBeVisible && recyclerView != null && layoutManager != null) {
|
||||
layoutManager.scrollToPositionWithOffset(items.indexOf(VIEWTYPE_PERMISSIONS), 0);
|
||||
}
|
||||
});
|
||||
headerView.setText(R.string.permissions);
|
||||
@@ -1035,8 +1053,9 @@ public class AppDetailsRecyclerViewAdapter
|
||||
boolean shouldBeVisible = contentView.getVisibility() != View.VISIBLE;
|
||||
contentView.setVisibility(shouldBeVisible ? View.VISIBLE : View.GONE);
|
||||
updateExpandableItem(shouldBeVisible);
|
||||
if (shouldBeVisible && recyclerView != null) {
|
||||
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(items.indexOf(VIEWTYPE_LINKS), 0);
|
||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
if (shouldBeVisible && recyclerView != null && layoutManager != null) {
|
||||
layoutManager.scrollToPositionWithOffset(items.indexOf(VIEWTYPE_LINKS), 0);
|
||||
}
|
||||
});
|
||||
headerView.setText(R.string.links);
|
||||
@@ -1137,7 +1156,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
ViewCompat.setPaddingRelative(view, margin + padding + ViewCompat.getPaddingStart(view), view.getPaddingTop(), margin + ViewCompat.getPaddingEnd(view), view.getPaddingBottom());
|
||||
}
|
||||
|
||||
public void bindModel(final Apk apk) {
|
||||
void bindModel(final Apk apk) {
|
||||
if (app == null) return;
|
||||
this.apk = apk;
|
||||
|
||||
@@ -1228,7 +1247,8 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
|
||||
// Expand the view if it was previously expanded or when downloading
|
||||
expand(versionsExpandTracker.get(apk.getApkPath()) || isApkDownloading);
|
||||
Boolean expandedVersion = versionsExpandTracker.get(apk.getApkPath());
|
||||
expand(Boolean.TRUE.equals(expandedVersion) || isApkDownloading);
|
||||
|
||||
// Toggle expanded view when clicking the whole version item,
|
||||
// unless it's an installed app version dummy item - it doesn't
|
||||
@@ -1241,10 +1261,12 @@ public class AppDetailsRecyclerViewAdapter
|
||||
itemView.setOnClickListener(null);
|
||||
}
|
||||
// Copy version name to clipboard when long clicking the whole version item
|
||||
itemView.setOnLongClickListener(v -> {
|
||||
Utils.copyToClipboard(context, app.name, apk.versionName);
|
||||
return true;
|
||||
});
|
||||
if (apk.versionName != null) {
|
||||
itemView.setOnLongClickListener(v -> {
|
||||
Utils.copyToClipboard(context, app.name, apk.versionName);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String getApiText(final Apk apk) {
|
||||
@@ -1337,14 +1359,14 @@ public class AppDetailsRecyclerViewAdapter
|
||||
return;
|
||||
}
|
||||
|
||||
boolean expand = !versionsExpandTracker.get(apk.getApkPath());
|
||||
boolean expand = Boolean.FALSE.equals(versionsExpandTracker.get(apk.getApkPath()));
|
||||
expand(expand);
|
||||
|
||||
if (expand) {
|
||||
// Scroll the versions view to a correct position so it can show the whole item
|
||||
final LinearLayoutManager lm = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
final int currentPosition = getAdapterPosition();
|
||||
if (currentPosition >= lm.findLastCompletelyVisibleItemPosition()) {
|
||||
final int currentPosition = getBindingAdapterPosition();
|
||||
if (lm != null && currentPosition >= lm.findLastCompletelyVisibleItemPosition()) {
|
||||
// Do it only if the item is near the bottom of current viewport
|
||||
recyclerView.getViewTreeObserver()
|
||||
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
|
||||
Reference in New Issue
Block a user