Further refactor the AppListItemController for readability and predictability.
This breaks out subclasses for each specific type of app list item, allowing for code reuse, but also letting the specific business logic belonging to each different app list item to be separate. This is particularly helpful in the following situation: * In the search results, it is great to be able to render "App downloaded, ready to install" in the same manner as the update tab. * In the installed app list, this is not desired. Indeed, the status text which should be shown should reference the currently installed version and whether the user has ignored any updates. By separating the AppListItemController into subclasses, it reduced the need to handle several different types of text view (e.g. "installedStatus", "status", "ignoredStatus", "downloadReady"), and replace them all with a "status" and "secondaryStatus" TextView. What is displayed in status and secondaryStatus is up to the individual subclasses of AppListItemController.
This commit is contained in:
parent
ef230f749c
commit
427d7bcbfa
@ -7,7 +7,7 @@ import android.view.ViewGroup;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
|
||||
class AppListAdapter extends RecyclerView.Adapter<AppListItemController> {
|
||||
class AppListAdapter extends RecyclerView.Adapter<StandardAppListItemController> {
|
||||
|
||||
private Cursor cursor;
|
||||
private final Activity activity;
|
||||
@ -24,13 +24,13 @@ class AppListAdapter extends RecyclerView.Adapter<AppListItemController> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppListItemController onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new AppListItemController(activity, activity.getLayoutInflater()
|
||||
public StandardAppListItemController onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new StandardAppListItemController(activity, activity.getLayoutInflater()
|
||||
.inflate(R.layout.app_list_item, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(AppListItemController holder, int position) {
|
||||
public void onBindViewHolder(StandardAppListItemController holder, int position) {
|
||||
cursor.moveToPosition(position);
|
||||
holder.bindModel(new App(cursor));
|
||||
}
|
||||
|
@ -47,11 +47,11 @@ import java.util.Iterator;
|
||||
|
||||
// TODO: Support cancelling of downloads by tapping the install button a second time.
|
||||
@SuppressWarnings("LineLength")
|
||||
public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
public abstract class AppListItemController extends RecyclerView.ViewHolder {
|
||||
|
||||
private static final String TAG = "AppListItemController";
|
||||
|
||||
private final Activity activity;
|
||||
protected final Activity activity;
|
||||
|
||||
@NonNull
|
||||
private final ImageView icon;
|
||||
@ -66,13 +66,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
private final TextView status;
|
||||
|
||||
@Nullable
|
||||
private final TextView appInstallStatus;
|
||||
|
||||
@Nullable
|
||||
private final TextView installedVersion;
|
||||
|
||||
@Nullable
|
||||
private final TextView ignoredStatus;
|
||||
private final TextView secondaryStatus;
|
||||
|
||||
@Nullable
|
||||
private final ProgressBar progressBar;
|
||||
@ -125,9 +119,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
icon = (ImageView) itemView.findViewById(R.id.icon);
|
||||
name = (TextView) itemView.findViewById(R.id.app_name);
|
||||
status = (TextView) itemView.findViewById(R.id.status);
|
||||
appInstallStatus = (TextView) itemView.findViewById(R.id.app_install_status);
|
||||
installedVersion = (TextView) itemView.findViewById(R.id.installed_version);
|
||||
ignoredStatus = (TextView) itemView.findViewById(R.id.ignored_status);
|
||||
secondaryStatus = (TextView) itemView.findViewById(R.id.secondary_status);
|
||||
progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
|
||||
cancelButton = (ImageButton) itemView.findViewById(R.id.cancel_button);
|
||||
actionButton = (Button) itemView.findViewById(R.id.action_button);
|
||||
@ -179,7 +171,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private AppListItemState getCurrentViewState(
|
||||
protected AppListItemState getCurrentViewState(
|
||||
@NonNull App app, @Nullable AppUpdateStatusManager.AppUpdateStatus appStatus) {
|
||||
if (appStatus == null) {
|
||||
return getViewStateDefault(app);
|
||||
@ -207,15 +199,6 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
|
||||
name.setText(viewState.getMainText());
|
||||
|
||||
if (appInstallStatus != null) {
|
||||
if (viewState.shouldShowAppInstallStatusText()) {
|
||||
appInstallStatus.setVisibility(View.VISIBLE);
|
||||
appInstallStatus.setText(viewState.getAppInstallStatusText());
|
||||
} else {
|
||||
appInstallStatus.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (actionButton != null) {
|
||||
if (viewState.shouldShowActionButton()) {
|
||||
actionButton.setVisibility(View.VISIBLE);
|
||||
@ -265,11 +248,6 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
}
|
||||
|
||||
if (installedVersion != null) {
|
||||
installedVersion.setVisibility(View.VISIBLE);
|
||||
installedVersion.setText(viewState.getInstalledVersionText());
|
||||
}
|
||||
|
||||
if (status != null) {
|
||||
CharSequence statusText = viewState.getStatusText();
|
||||
if (statusText == null) {
|
||||
@ -280,24 +258,24 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoredStatus != null) {
|
||||
CharSequence ignoredStatusText = viewState.getIgnoredStatusText();
|
||||
if (ignoredStatusText == null) {
|
||||
ignoredStatus.setVisibility(View.GONE);
|
||||
if (secondaryStatus != null) {
|
||||
CharSequence statusText = viewState.getSecondaryStatusText();
|
||||
if (statusText == null) {
|
||||
secondaryStatus.setVisibility(View.GONE);
|
||||
} else {
|
||||
ignoredStatus.setVisibility(View.VISIBLE);
|
||||
ignoredStatus.setText(ignoredStatusText);
|
||||
secondaryStatus.setVisibility(View.VISIBLE);
|
||||
secondaryStatus.setText(statusText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AppListItemState getViewStateInstalled(@NonNull App app) {
|
||||
protected AppListItemState getViewStateInstalled(@NonNull App app) {
|
||||
CharSequence mainText = activity.getString(
|
||||
R.string.app_list__name__successfully_installed, app.name);
|
||||
|
||||
AppListItemState state = new AppListItemState(activity, app)
|
||||
AppListItemState state = new AppListItemState(app)
|
||||
.setMainText(mainText)
|
||||
.setAppInstallStatusText(activity.getString(R.string.notification_content_single_installed));
|
||||
.setStatusText(activity.getString(R.string.notification_content_single_installed));
|
||||
|
||||
if (activity.getPackageManager().getLaunchIntentForPackage(app.packageName) != null) {
|
||||
state.showActionButton(activity.getString(R.string.menu_launch));
|
||||
@ -306,29 +284,29 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
return state;
|
||||
}
|
||||
|
||||
private AppListItemState getViewStateDownloading(
|
||||
protected AppListItemState getViewStateDownloading(
|
||||
@NonNull App app, @NonNull AppUpdateStatusManager.AppUpdateStatus currentStatus) {
|
||||
CharSequence mainText = activity.getString(
|
||||
R.string.app_list__name__downloading_in_progress, app.name);
|
||||
|
||||
return new AppListItemState(activity, app)
|
||||
return new AppListItemState(app)
|
||||
.setMainText(mainText)
|
||||
.setProgress(currentStatus.progressCurrent, currentStatus.progressMax);
|
||||
}
|
||||
|
||||
private AppListItemState getViewStateReadyToInstall(@NonNull App app) {
|
||||
protected AppListItemState getViewStateReadyToInstall(@NonNull App app) {
|
||||
int actionButtonLabel = app.isInstalled()
|
||||
? R.string.app__install_downloaded_update
|
||||
: R.string.menu_install;
|
||||
|
||||
return new AppListItemState(activity, app)
|
||||
return new AppListItemState(app)
|
||||
.setMainText(app.name)
|
||||
.showActionButton(activity.getString(actionButtonLabel))
|
||||
.setAppInstallStatusText(activity.getString(R.string.app_list_download_ready));
|
||||
.setStatusText(activity.getString(R.string.app_list_download_ready));
|
||||
}
|
||||
|
||||
private AppListItemState getViewStateDefault(@NonNull App app) {
|
||||
return new AppListItemState(activity, app);
|
||||
protected AppListItemState getViewStateDefault(@NonNull App app) {
|
||||
return new AppListItemState(app);
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
|
@ -1,42 +1,46 @@
|
||||
package org.fdroid.fdroid.views.apps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppPrefs;
|
||||
|
||||
/**
|
||||
* A dumb model which is used to specify what should/should not be shown in an {@link AppListItemController}.
|
||||
* @see AppListItemController and its subclasses.
|
||||
*/
|
||||
public class AppListItemState {
|
||||
private final Context context;
|
||||
private final App app;
|
||||
private CharSequence mainText = null;
|
||||
private CharSequence appInstallStatusText = null;
|
||||
private CharSequence actionButtonText = null;
|
||||
private CharSequence statusText = null;
|
||||
private CharSequence secondaryStatusText = null;
|
||||
private int progressCurrent = -1;
|
||||
private int progressMax = -1;
|
||||
private boolean showInstallButton;
|
||||
|
||||
public AppListItemState(Context context, @NonNull App app) {
|
||||
public AppListItemState(@NonNull App app) {
|
||||
this.app = app;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public AppListItemState setMainText(@NonNull CharSequence mainText) {
|
||||
public AppListItemState setMainText(CharSequence mainText) {
|
||||
this.mainText = mainText;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AppListItemState showActionButton(@NonNull CharSequence label) {
|
||||
public AppListItemState showActionButton(CharSequence label) {
|
||||
actionButtonText = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AppListItemState setAppInstallStatusText(@NonNull CharSequence text) {
|
||||
appInstallStatusText = text;
|
||||
public AppListItemState setStatusText(CharSequence text) {
|
||||
this.statusText = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AppListItemState setSecondaryStatusText(CharSequence text) {
|
||||
this.secondaryStatusText = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -46,6 +50,11 @@ public class AppListItemState {
|
||||
return this;
|
||||
}
|
||||
|
||||
public AppListItemState setShowInstallButton(boolean show) {
|
||||
this.showInstallButton = show;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CharSequence getMainText() {
|
||||
return mainText != null
|
||||
@ -54,10 +63,7 @@ public class AppListItemState {
|
||||
}
|
||||
|
||||
public boolean shouldShowInstall() {
|
||||
boolean installable = app.canAndWantToUpdate(context) || !app.isInstalled();
|
||||
boolean shouldAllow = app.compatible && !app.isFiltered();
|
||||
|
||||
return installable && shouldAllow && !shouldShowActionButton() && !showProgress();
|
||||
return showInstallButton;
|
||||
}
|
||||
|
||||
public boolean shouldShowActionButton() {
|
||||
@ -84,62 +90,13 @@ public class AppListItemState {
|
||||
return progressMax;
|
||||
}
|
||||
|
||||
public boolean shouldShowAppInstallStatusText() {
|
||||
return appInstallStatusText != null;
|
||||
}
|
||||
|
||||
public CharSequence getAppInstallStatusText() {
|
||||
return appInstallStatusText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text/visibility of the {@link R.id#status} {@link TextView} based on whether the app:
|
||||
* * Is compatible with the users device
|
||||
* * Is installed
|
||||
* * Can be updated
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getStatusText() {
|
||||
String statusText = null;
|
||||
if (!app.compatible) {
|
||||
statusText = context.getString(R.string.app_incompatible);
|
||||
} else if (app.isInstalled()) {
|
||||
if (app.canAndWantToUpdate(context)) {
|
||||
statusText = context.getString(R.string.app_version_x_available, app.getSuggestedVersionName());
|
||||
} else {
|
||||
statusText = context.getString(R.string.app_version_x_installed, app.installedVersionName);
|
||||
}
|
||||
}
|
||||
return statusText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the currently installed version name, and whether or not it is the recommended version.
|
||||
*/
|
||||
public CharSequence getInstalledVersionText() {
|
||||
int res = (app.suggestedVersionCode == app.installedVersionCode)
|
||||
? R.string.app_recommended_version_installed
|
||||
: R.string.app_version_x_installed;
|
||||
|
||||
return context.getString(res, app.installedVersionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows whether the user has previously asked to ignore updates for this app entirely, or for a
|
||||
* specific version of this app. Binds to the {@link R.id#ignored_status} {@link TextView}.
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getIgnoredStatusText() {
|
||||
AppPrefs prefs = app.getPrefs(context);
|
||||
if (prefs.ignoreAllUpdates) {
|
||||
return context.getString(R.string.installed_app__updates_ignored);
|
||||
} else if (prefs.ignoreThisUpdate > 0 && prefs.ignoreThisUpdate == app.suggestedVersionCode) {
|
||||
return context.getString(
|
||||
R.string.installed_app__updates_ignored_for_suggested_version,
|
||||
app.getSuggestedVersionName());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public CharSequence getSecondaryStatusText() {
|
||||
return secondaryStatusText;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
package org.fdroid.fdroid.views.apps;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
|
||||
/**
|
||||
* Used for search results or for category lists.
|
||||
* Shows an inline download button, and also (if appropriate):
|
||||
* * Whether the app is incompatible.
|
||||
* * Version that app can be upgraded to.
|
||||
* * Installed version.
|
||||
*/
|
||||
public class StandardAppListItemController extends AppListItemController {
|
||||
public StandardAppListItemController(Activity activity, View itemView) {
|
||||
super(activity, itemView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected AppListItemState getCurrentViewState(
|
||||
@NonNull App app, @Nullable AppUpdateStatusManager.AppUpdateStatus appStatus) {
|
||||
|
||||
return super.getCurrentViewState(app, appStatus)
|
||||
.setStatusText(getStatusText(app))
|
||||
.setShowInstallButton(shouldShowInstall(app));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CharSequence getStatusText(@NonNull App app) {
|
||||
if (!app.compatible) {
|
||||
return activity.getString(R.string.app_incompatible);
|
||||
} else if (app.isInstalled()) {
|
||||
if (app.canAndWantToUpdate(activity)) {
|
||||
return activity.getString(R.string.app_version_x_available, app.getSuggestedVersionName());
|
||||
} else {
|
||||
return activity.getString(R.string.app_version_x_installed, app.installedVersionName);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean shouldShowInstall(@NonNull App app) {
|
||||
boolean installable = app.canAndWantToUpdate(activity) || !app.isInstalled();
|
||||
boolean shouldAllow = app.compatible && !app.isFiltered();
|
||||
|
||||
return installable && shouldAllow;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.fdroid.fdroid.views.installed;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.Schema;
|
||||
|
||||
class InstalledAppListAdapter extends RecyclerView.Adapter<InstalledAppListItemController> {
|
||||
|
||||
private final Activity activity;
|
||||
|
||||
@Nullable
|
||||
private Cursor cursor;
|
||||
|
||||
InstalledAppListAdapter(Activity activity) {
|
||||
this.activity = activity;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (cursor == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cursor.moveToPosition(position);
|
||||
return cursor.getLong(cursor.getColumnIndex(Schema.AppMetadataTable.Cols.ROW_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstalledAppListItemController onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = activity.getLayoutInflater().inflate(R.layout.installed_app_list_item, parent, false);
|
||||
return new InstalledAppListItemController(activity, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InstalledAppListItemController holder, int position) {
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.moveToPosition(position);
|
||||
holder.bindModel(new App(cursor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cursor == null ? 0 : cursor.getCount();
|
||||
}
|
||||
|
||||
public void setApps(@Nullable Cursor cursor) {
|
||||
this.cursor = cursor;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package org.fdroid.fdroid.views.installed;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppPrefs;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemState;
|
||||
|
||||
/**
|
||||
* Shows the currently installed version name, and whether or not it is the recommended version.
|
||||
* Also shows whether the user has previously asked to ignore updates for this app entirely, or for
|
||||
* a specific version of this app.
|
||||
*/
|
||||
public class InstalledAppListItemController extends AppListItemController {
|
||||
public InstalledAppListItemController(Activity activity, View itemView) {
|
||||
super(activity, itemView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected AppListItemState getCurrentViewState(
|
||||
@NonNull App app, @Nullable AppUpdateStatusManager.AppUpdateStatus appStatus) {
|
||||
return new AppListItemState(app)
|
||||
.setStatusText(getInstalledVersion(app))
|
||||
.setSecondaryStatusText(getIgnoreStatus(app));
|
||||
}
|
||||
|
||||
/**
|
||||
* Either "Version X" or "Version Y (Recommended)", depending on the installed version.
|
||||
*/
|
||||
private CharSequence getInstalledVersion(@NonNull App app) {
|
||||
int statusStringRes = (app.suggestedVersionCode == app.installedVersionCode)
|
||||
? R.string.app_recommended_version_installed
|
||||
: R.string.app_version_x_installed;
|
||||
|
||||
return activity.getString(statusStringRes, app.installedVersionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show whether the user has ignored a specific version ("Updates ignored for Version X"), or
|
||||
* all versions ("Updates ignored").
|
||||
*/
|
||||
@Nullable
|
||||
private CharSequence getIgnoreStatus(@NonNull App app) {
|
||||
AppPrefs prefs = app.getPrefs(activity);
|
||||
if (prefs.ignoreAllUpdates) {
|
||||
return activity.getString(R.string.installed_app__updates_ignored);
|
||||
} else if (prefs.ignoreThisUpdate > 0 && prefs.ignoreThisUpdate == app.suggestedVersionCode) {
|
||||
return activity.getString(
|
||||
R.string.installed_app__updates_ignored_for_suggested_version,
|
||||
app.getSuggestedVersionName());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -19,10 +19,8 @@
|
||||
|
||||
package org.fdroid.fdroid.views.installed;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
@ -31,15 +29,12 @@ import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.data.Schema;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
|
||||
public class InstalledAppsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
@ -105,52 +100,4 @@ public class InstalledAppsActivity extends AppCompatActivity implements LoaderMa
|
||||
adapter.setApps(null);
|
||||
}
|
||||
|
||||
static class InstalledAppListAdapter extends RecyclerView.Adapter<AppListItemController> {
|
||||
|
||||
private final Activity activity;
|
||||
|
||||
@Nullable
|
||||
private Cursor cursor;
|
||||
|
||||
InstalledAppListAdapter(Activity activity) {
|
||||
this.activity = activity;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (cursor == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cursor.moveToPosition(position);
|
||||
return cursor.getLong(cursor.getColumnIndex(Schema.AppMetadataTable.Cols.ROW_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppListItemController onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = activity.getLayoutInflater().inflate(R.layout.installed_app_list_item, parent, false);
|
||||
return new AppListItemController(activity, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(AppListItemController holder, int position) {
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.moveToPosition(position);
|
||||
holder.bindModel(new App(cursor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cursor == null ? 0 : cursor.getCount();
|
||||
}
|
||||
|
||||
public void setApps(@Nullable Cursor cursor) {
|
||||
this.cursor = cursor;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import com.hannesdorfmann.adapterdelegates3.AdapterDelegate;
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -16,8 +15,8 @@ import java.util.List;
|
||||
* Apps which we want to show some more substantial information about.
|
||||
*
|
||||
* @see R.layout#updateable_app_status_item The view that this binds to
|
||||
* @see AppListItemController Used for binding the {@link App} to the
|
||||
* {@link R.layout#updateable_app_status_item}
|
||||
* @see AppStatusListItemController Used for binding the {@link App} to the
|
||||
* {@link R.layout#updateable_app_status_item}.
|
||||
*/
|
||||
public class AppStatus extends AppUpdateData {
|
||||
|
||||
@ -44,7 +43,7 @@ public class AppStatus extends AppUpdateData {
|
||||
@NonNull
|
||||
@Override
|
||||
protected RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
|
||||
return new AppListItemController(activity, activity.getLayoutInflater()
|
||||
return new AppStatusListItemController(activity, activity.getLayoutInflater()
|
||||
.inflate(R.layout.updateable_app_status_item, parent, false));
|
||||
}
|
||||
|
||||
@ -52,7 +51,7 @@ public class AppStatus extends AppUpdateData {
|
||||
protected void onBindViewHolder(@NonNull List<AppUpdateData> items, int position,
|
||||
@NonNull RecyclerView.ViewHolder holder, @NonNull List<Object> payloads) {
|
||||
AppStatus app = (AppStatus) items.get(position);
|
||||
((AppListItemController) holder).bindModel(app.status.app);
|
||||
((AppStatusListItemController) holder).bindModel(app.status.app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
package org.fdroid.fdroid.views.updates.items;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemState;
|
||||
|
||||
/**
|
||||
* Shows apps which are:
|
||||
* * In the process of being downloaded.
|
||||
* * Downloaded and ready to install.
|
||||
* * Recently installed and ready to run.
|
||||
*/
|
||||
public class AppStatusListItemController extends AppListItemController {
|
||||
public AppStatusListItemController(Activity activity, View itemView) {
|
||||
super(activity, itemView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected AppListItemState getCurrentViewState(
|
||||
@NonNull App app, @Nullable AppUpdateStatusManager.AppUpdateStatus appStatus) {
|
||||
|
||||
return super.getCurrentViewState(app, appStatus)
|
||||
.setStatusText(getStatusText(appStatus));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CharSequence getStatusText(@Nullable AppUpdateStatusManager.AppUpdateStatus appStatus) {
|
||||
if (appStatus != null) {
|
||||
switch (appStatus.status) {
|
||||
case ReadyToInstall:
|
||||
return activity.getString(R.string.app_list_download_ready);
|
||||
|
||||
case Installed:
|
||||
return activity.getString(R.string.notification_content_single_installed);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ import android.view.ViewGroup;
|
||||
import com.hannesdorfmann.adapterdelegates3.AdapterDelegate;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -16,7 +15,8 @@ import java.util.List;
|
||||
*
|
||||
* @see UpdateableApp The data that is bound to this view.
|
||||
* @see R.layout#updateable_app_list_item The view that this binds to.
|
||||
* @see AppListItemController Used for binding the {@link App} to the {@link R.layout#updateable_app_list_item}
|
||||
* @see UpdateableAppListItemController Used for binding the {@link App} to
|
||||
* the {@link R.layout#updateable_app_list_item}
|
||||
*/
|
||||
public class UpdateableApp extends AppUpdateData {
|
||||
|
||||
@ -43,7 +43,7 @@ public class UpdateableApp extends AppUpdateData {
|
||||
@NonNull
|
||||
@Override
|
||||
protected RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
|
||||
return new AppListItemController(activity, activity.getLayoutInflater()
|
||||
return new UpdateableAppListItemController(activity, activity.getLayoutInflater()
|
||||
.inflate(R.layout.updateable_app_list_item, parent, false));
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class UpdateableApp extends AppUpdateData {
|
||||
protected void onBindViewHolder(@NonNull List<AppUpdateData> items, int position,
|
||||
@NonNull RecyclerView.ViewHolder holder, @NonNull List<Object> payloads) {
|
||||
UpdateableApp app = (UpdateableApp) items.get(position);
|
||||
((AppListItemController) holder).bindModel(app.app);
|
||||
((UpdateableAppListItemController) holder).bindModel(app.app);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
package org.fdroid.fdroid.views.updates.items;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
|
||||
import org.fdroid.fdroid.AppUpdateStatusManager;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemState;
|
||||
|
||||
/**
|
||||
* Very trimmed down list item. Only displays the app icon, name, and a download button.
|
||||
* We don't even need to show download progress, because the intention is that as soon as
|
||||
* we have started downloading the app, it is removed from the list (and replaced with an
|
||||
* {@link AppStatusListItemController}.
|
||||
*/
|
||||
public class UpdateableAppListItemController extends AppListItemController {
|
||||
public UpdateableAppListItemController(Activity activity, View itemView) {
|
||||
super(activity, itemView);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected AppListItemState getCurrentViewState(
|
||||
@NonNull App app, @Nullable AppUpdateStatusManager.AppUpdateStatus appStatus) {
|
||||
return new AppListItemState(app)
|
||||
.setShowInstallButton(true);
|
||||
}
|
||||
}
|
@ -44,24 +44,20 @@
|
||||
android:layout_marginRight="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/installed_version"
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
tools:text="Version 4.7.3 (recommended)"
|
||||
android:textStyle="italic"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?attr/installedApps"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="sans-serif-light"
|
||||
style="@style/AppListItemStatusText"
|
||||
app:layout_constraintTop_toBottomOf="@+id/app_name"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ignored_status"
|
||||
android:id="@+id/secondary_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
@ -69,7 +65,7 @@
|
||||
android:textSize="14sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@+id/installed_version"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
@ -55,22 +55,8 @@
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/action_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/icon"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/icon" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_button"
|
||||
style="@style/DetailsPrimaryButtonStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Update" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -43,7 +43,7 @@
|
||||
app:layout_constraintVertical_bias="0.333" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_install_status"
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@string/app_list_download_ready"
|
||||
|
Loading…
x
Reference in New Issue
Block a user