Show empty state feedback for latest + categories
The text is more comprehensive on the main screen than on categories, because this is the view that all users will see when they first open F-Droid. Fixes #879.
This commit is contained in:
parent
510ec5f7c7
commit
ab5ea39f7c
@ -12,6 +12,7 @@ import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.CategoryProvider;
|
||||
@ -30,6 +31,8 @@ class CategoriesViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private final CategoryAdapter categoryAdapter;
|
||||
private final AppCompatActivity activity;
|
||||
private final TextView emptyState;
|
||||
private final RecyclerView categoriesList;
|
||||
|
||||
CategoriesViewBinder(final AppCompatActivity activity, FrameLayout parent) {
|
||||
this.activity = activity;
|
||||
@ -38,7 +41,9 @@ class CategoriesViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
categoryAdapter = new CategoryAdapter(activity, activity.getSupportLoaderManager());
|
||||
|
||||
RecyclerView categoriesList = (RecyclerView) categoriesView.findViewById(R.id.category_list);
|
||||
emptyState = (TextView) categoriesView.findViewById(R.id.empty_state);
|
||||
|
||||
categoriesList = (RecyclerView) categoriesView.findViewById(R.id.category_list);
|
||||
categoriesList.setHasFixedSize(true);
|
||||
categoriesList.setLayoutManager(new LinearLayoutManager(activity));
|
||||
categoriesList.setAdapter(categoryAdapter);
|
||||
@ -77,6 +82,14 @@ class CategoriesViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
}
|
||||
|
||||
categoryAdapter.setCategoriesCursor(cursor);
|
||||
|
||||
if (categoryAdapter.getItemCount() == 0) {
|
||||
emptyState.setVisibility(View.VISIBLE);
|
||||
categoriesList.setVisibility(View.GONE);
|
||||
} else {
|
||||
emptyState.setVisibility(View.GONE);
|
||||
categoriesList.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,14 +13,20 @@ import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.data.RepoProvider;
|
||||
import org.fdroid.fdroid.data.Schema;
|
||||
import org.fdroid.fdroid.views.apps.AppListActivity;
|
||||
import org.fdroid.fdroid.views.whatsnew.WhatsNewAdapter;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Loads a list of newly added or recently updated apps and displays them to the user.
|
||||
*/
|
||||
@ -30,6 +36,8 @@ class WhatsNewViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private final WhatsNewAdapter whatsNewAdapter;
|
||||
private final AppCompatActivity activity;
|
||||
private final TextView emptyState;
|
||||
private final RecyclerView appList;
|
||||
|
||||
WhatsNewViewBinder(final AppCompatActivity activity, FrameLayout parent) {
|
||||
this.activity = activity;
|
||||
@ -41,7 +49,9 @@ class WhatsNewViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
GridLayoutManager layoutManager = new GridLayoutManager(activity, 2);
|
||||
layoutManager.setSpanSizeLookup(new WhatsNewAdapter.SpanSizeLookup());
|
||||
|
||||
RecyclerView appList = (RecyclerView) whatsNewView.findViewById(R.id.app_list);
|
||||
emptyState = (TextView) whatsNewView.findViewById(R.id.empty_state);
|
||||
|
||||
appList = (RecyclerView) whatsNewView.findViewById(R.id.app_list);
|
||||
appList.setHasFixedSize(true);
|
||||
appList.setLayoutManager(layoutManager);
|
||||
appList.setAdapter(whatsNewAdapter);
|
||||
@ -89,6 +99,37 @@ class WhatsNewViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
}
|
||||
|
||||
whatsNewAdapter.setAppsCursor(cursor);
|
||||
|
||||
if (whatsNewAdapter.getItemCount() == 0) {
|
||||
emptyState.setVisibility(View.VISIBLE);
|
||||
appList.setVisibility(View.GONE);
|
||||
explainEmptyStateToUser();
|
||||
} else {
|
||||
emptyState.setVisibility(View.GONE);
|
||||
appList.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void explainEmptyStateToUser() {
|
||||
StringBuilder emptyStateText = new StringBuilder();
|
||||
emptyStateText.append(activity.getString(R.string.latest__empty_state__no_recent_apps));
|
||||
emptyStateText.append("\n\n");
|
||||
|
||||
int repoCount = RepoProvider.Helper.countEnabledRepos(activity);
|
||||
if (repoCount == 0) {
|
||||
emptyStateText.append(activity.getString(R.string.latest__empty_state__no_enabled_repos));
|
||||
} else {
|
||||
Date lastUpdate = RepoProvider.Helper.lastUpdate(activity);
|
||||
if (lastUpdate == null) {
|
||||
emptyStateText.append(activity.getString(R.string.latest__empty_state__never_updated));
|
||||
} else {
|
||||
long msDiff = Calendar.getInstance().getTimeInMillis() - lastUpdate.getTime();
|
||||
int daysDiff = (int) TimeUnit.MILLISECONDS.toDays(msDiff);
|
||||
emptyStateText.append(activity.getResources().getQuantityString(R.plurals.details_last_update_days, daysDiff, daysDiff));
|
||||
}
|
||||
}
|
||||
|
||||
emptyState.setText(emptyStateText.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +16,18 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:layout_editor_absoluteX="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
style="@style/AppListEmptyText"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:visibility="gone"
|
||||
android:text="@string/categories__empty_state__no_categories" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/category_list"
|
||||
android:layout_width="0dp"
|
||||
|
@ -21,6 +21,14 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
style="@style/AppListEmptyText"
|
||||
android:visibility="gone"
|
||||
tools:text="@string/latest__empty_state__no_recent_apps"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/app_list"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -159,6 +159,12 @@
|
||||
<string name="main_menu__categories">Categories</string>
|
||||
<string name="main_menu__swap_nearby">Nearby</string>
|
||||
|
||||
<string name="latest__empty_state__no_recent_apps">No recent apps found</string>
|
||||
<string name="latest__empty_state__never_updated">Once your list of apps has been updated, the latest apps should show here</string>
|
||||
<string name="latest__empty_state__no_enabled_repos">Once you enable a repository and let it update, the latest apps should show here</string>
|
||||
|
||||
<string name="categories__empty_state__no_categories">No categories to display</string>
|
||||
|
||||
<string name="preference_category__my_apps">My Apps</string>
|
||||
<string name="preference_manage_installed_apps">Manage Installed Apps</string>
|
||||
|
||||
|
@ -93,6 +93,13 @@
|
||||
</style>
|
||||
<style name="BodyText" parent="BodyTextBase" />
|
||||
|
||||
<style name="AppListEmptyText">
|
||||
<item name="android:id">@android:id/empty</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:padding">20dp</item>
|
||||
<item name="android:textSize">20sp</item>
|
||||
</style>
|
||||
|
||||
<style name="SwapTheme.Wizard" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="colorButtonNormal">@color/swap_bright_blue</item>
|
||||
<item name="actionButtonStyle">@style/SwapTheme.Wizard.ActionButton</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user