diff --git a/F-Droid/res/layout/empty_app_list.xml b/F-Droid/res/layout/empty_app_list.xml
new file mode 100644
index 000000000..d43cbe496
--- /dev/null
+++ b/F-Droid/res/layout/empty_app_list.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml
index 5cb6672d5..5a59b0218 100644
--- a/F-Droid/res/values/strings.xml
+++ b/F-Droid/res/values/strings.xml
@@ -278,6 +278,11 @@
System
Wallpaper
+ No apps installed.\n\nThere are apps on your device, but they are not available from F-Droid. This could be because you need to update your repositories, or the repositories genuinely don\'t have your apps available.
+ No apps available to swap.\n\nEither the device you are swapping with didn\'t offer any apps to swap, or an error occurred while communicating with it.
+ No apps in this category.\n\nTry selecting a different category or updating your repositories to get a fresh list of apps.
+ All apps up to date.\n\nCongratulations! All of your apps are up to date (or your repositories are out of date).
+
Root access
Requesting root access…
Root access denied
diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java
index f0453ee5e..0a9ab8f17 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/AppListFragment.java
@@ -6,15 +6,20 @@ import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
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;
import android.util.Log;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.TextView;
+
import org.fdroid.fdroid.AppDetails;
import org.fdroid.fdroid.FDroid;
import org.fdroid.fdroid.Preferences;
+import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.AppProvider;
@@ -53,6 +58,17 @@ abstract public class AppListFragment extends ThemeableListFragment implements
protected abstract Uri getDataUri();
+ /**
+ * Depending on the subclass, a different message may be desired. For example, in the main list
+ * of apps, might want to say "No apps for this category, how about you try...", while the
+ * "Update" tab may wish to say "Congratulations, all your apps are up to date."
+ *
+ * In the future, this may want to return a view instead of a string. That would allow nice
+ * visual graphics helping to show the message.
+ */
+ @Nullable
+ protected abstract String getEmptyMessage();
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -62,6 +78,14 @@ abstract public class AppListFragment extends ThemeableListFragment implements
// onActivityCreated" according to the docs.
getListView().setFastScrollEnabled(true);
getListView().setOnItemClickListener(this);
+
+ String emptyMessage = getEmptyMessage();
+ if (emptyMessage != null) {
+ View emptyView = getLayoutInflater(savedInstanceState).inflate(R.layout.empty_app_list, null);
+ ((TextView)emptyView.findViewById(R.id.text)).setText(emptyMessage);
+ ((ViewGroup)getListView().getParent()).addView(emptyView); // Needs to be added to this parent or it doesn't show.
+ getListView().setEmptyView(emptyView);
+ }
}
@Override
diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java
index c664e1185..715c4cf8a 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/AvailableAppsFragment.java
@@ -61,6 +61,11 @@ public class AvailableAppsFragment extends AppListFragment implements
return adapter;
}
+ @Override
+ protected String getEmptyMessage() {
+ return getActivity().getString(R.string.empty_available_app_list);
+ }
+
private class CategoryObserver extends ContentObserver {
private ArrayAdapter adapter;
diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java
index 1dfb84e6b..e7ed8f010 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/CanUpdateAppsFragment.java
@@ -44,6 +44,11 @@ public class CanUpdateAppsFragment extends AppListFragment {
return getString(R.string.tab_updates);
}
+ @Override
+ protected String getEmptyMessage() {
+ return getActivity().getString(R.string.empty_can_update_app_list);
+ }
+
@Override
protected Uri getDataUri() {
return AppProvider.getCanUpdateUri();
@@ -53,8 +58,7 @@ public class CanUpdateAppsFragment extends AppListFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mInstaller = Installer.getActivityInstaller(getActivity(), getActivity()
- .getPackageManager(), null);
+ mInstaller = Installer.getActivityInstaller(getActivity(), getActivity().getPackageManager(), null);
}
@Override
diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java
index 8585786b0..8ee5baeef 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/InstalledAppsFragment.java
@@ -13,6 +13,11 @@ public class InstalledAppsFragment extends AppListFragment {
return new InstalledAppListAdapter(getActivity(), null);
}
+ @Override
+ protected String getEmptyMessage() {
+ return getActivity().getString(R.string.empty_installed_app_list);
+ }
+
@Override
protected String getFromTitle() {
return getString(R.string.inst);
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppListActivity.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppListActivity.java
index c852ef2b7..2aa1f910f 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppListActivity.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppListActivity.java
@@ -2,6 +2,7 @@ package org.fdroid.fdroid.views.swap;
import android.net.Uri;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v7.app.ActionBarActivity;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.AppProvider;
@@ -25,7 +26,7 @@ public class SwapAppListActivity extends ActionBarActivity {
}
- private static class SwapAppListFragment extends AppListFragment {
+ public static class SwapAppListFragment extends AppListFragment {
@Override
protected int getHeaderLayout() {
@@ -37,6 +38,12 @@ public class SwapAppListActivity extends ActionBarActivity {
return new AvailableAppListAdapter(getActivity(), null);
}
+ @Nullable
+ @Override
+ protected String getEmptyMessage() {
+ return getActivity().getString(R.string.empty_swap_app_list);
+ }
+
@Override
protected String getFromTitle() {
return getString(R.string.swap);