diff --git a/android/res/layout/fragment_bookmark_categories.xml b/android/res/layout/fragment_bookmark_categories.xml
index 1db4c50a18..7ad06e39e9 100644
--- a/android/res/layout/fragment_bookmark_categories.xml
+++ b/android/res/layout/fragment_bookmark_categories.xml
@@ -9,8 +9,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
-
-
+
diff --git a/android/res/layout/item_bookmark_backup.xml b/android/res/layout/item_bookmark_backup.xml
index a2c25a9cd5..62ae4c23b4 100644
--- a/android/res/layout/item_bookmark_backup.xml
+++ b/android/res/layout/item_bookmark_backup.xml
@@ -18,14 +18,13 @@
android:paddingTop="@dimen/margin_half_plus"
android:paddingBottom="@dimen/margin_half_plus">
@@ -36,6 +35,7 @@
android:orientation="vertical"
android:padding="@dimen/margin_base">
diff --git a/android/res/layout/item_bookmark_category.xml b/android/res/layout/item_bookmark_category.xml
index 4b2bf3ff60..97031e57c9 100644
--- a/android/res/layout/item_bookmark_category.xml
+++ b/android/res/layout/item_bookmark_category.xml
@@ -7,6 +7,7 @@
android:background="?clickableBackground"
android:gravity="center_vertical"
android:minHeight="@dimen/height_item_oneline"
+ android:layout_marginTop="@dimen/margin_half"
android:paddingEnd="@dimen/margin_base"
android:paddingLeft="0dp"
android:paddingRight="@dimen/margin_base"
diff --git a/android/src/com/mapswithme/maps/bookmarks/BookmarkCategoriesFragment.java b/android/src/com/mapswithme/maps/bookmarks/BookmarkCategoriesFragment.java
index 7e88fa0e2f..26358dfd4c 100644
--- a/android/src/com/mapswithme/maps/bookmarks/BookmarkCategoriesFragment.java
+++ b/android/src/com/mapswithme/maps/bookmarks/BookmarkCategoriesFragment.java
@@ -78,11 +78,15 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment
private void updateResultsPlaceholder()
{
+ boolean showLoadingPlaceholder = BookmarkManager.nativeIsAsyncBookmarksLoadingInProgress();
+ boolean showPlaceHolder = !showLoadingPlaceholder &&
+ (getAdapter() == null || getAdapter().getItemCount() == 0);
if (getAdapter() != null)
- {
- boolean showLoadingPlaceholder = BookmarkManager.nativeIsAsyncBookmarksLoadingInProgress();
- showPlaceholder(!showLoadingPlaceholder && getAdapter().getItemCount() == 0);
- }
+ showPlaceholder(showPlaceHolder);
+
+ View root = getView();
+ if (root != null)
+ UiUtils.showIf(!showLoadingPlaceholder && !showPlaceHolder, root, R.id.backup);
}
private void updateLoadingPlaceholder()
diff --git a/android/src/com/mapswithme/maps/widget/BookmarkBackupView.java b/android/src/com/mapswithme/maps/widget/BookmarkBackupView.java
new file mode 100644
index 0000000000..1e8c39de4b
--- /dev/null
+++ b/android/src/com/mapswithme/maps/widget/BookmarkBackupView.java
@@ -0,0 +1,148 @@
+package com.mapswithme.maps.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.util.Graphics;
+import com.mapswithme.util.UiUtils;
+
+public class BookmarkBackupView extends LinearLayout
+{
+ private final static int ANIMATION_DURATION = 300;
+
+ @SuppressWarnings("NullableProblems")
+ @NonNull
+ private View mHeader;
+ @SuppressWarnings("NullableProblems")
+ @NonNull
+ private View mContentLayout;
+ @SuppressWarnings("NullableProblems")
+ @NonNull
+ private TextView mTitle;
+
+ @NonNull
+ private final OnClickListener mHeaderClickListener = v -> onHeaderClick();
+
+ private boolean mExpanded = false;
+
+ public BookmarkBackupView(Context context)
+ {
+ super(context);
+ init();
+ }
+
+ public BookmarkBackupView(Context context, @Nullable AttributeSet attrs)
+ {
+ super(context, attrs);
+ init();
+ }
+
+ public BookmarkBackupView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
+ {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init()
+ {
+ LayoutInflater.from(getContext()).inflate(R.layout.item_bookmark_backup, this);
+ mHeader = findViewById(R.id.header);
+ mContentLayout = findViewById(R.id.content);
+ UiUtils.showIf(mExpanded, mContentLayout);
+
+ mTitle = mHeader.findViewById(R.id.title);
+ mTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, getToggle(), null);
+ mHeader.setOnClickListener(mHeaderClickListener);
+ }
+
+ private void onHeaderClick()
+ {
+ mExpanded = !mExpanded;
+ Animator animator = mExpanded ? createFadeInAnimator() : createFadeOutAnimator();
+ animator.setDuration(ANIMATION_DURATION);
+ animator.start();
+ mTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, getToggle(), null);
+ }
+
+ @NonNull
+ private Animator createFadeInAnimator()
+ {
+ ObjectAnimator animator = ObjectAnimator.ofFloat(mContentLayout, "alpha",
+ 0, 1f);
+ animator.addListener(new AnimatorListenerAdapter()
+ {
+ @Override
+ public void onAnimationStart(Animator animation)
+ {
+ UiUtils.show(mContentLayout);
+ mHeader.setEnabled(false);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation)
+ {
+ mHeader.setEnabled(true);
+ }
+ });
+ return animator;
+ }
+
+ @NonNull
+ private Animator createFadeOutAnimator()
+ {
+ ObjectAnimator animator = ObjectAnimator.ofFloat(mContentLayout, "alpha",
+ 1f, 0);
+ animator.addListener(new AnimatorListenerAdapter()
+ {
+ @Override
+ public void onAnimationStart(Animator animation)
+ {
+ mHeader.setEnabled(false);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation)
+ {
+ UiUtils.hide(mContentLayout);
+ mHeader.setEnabled(true);
+ }
+ });
+ return animator;
+ }
+
+ @NonNull
+ private Drawable getToggle()
+ {
+ return Graphics.tint(getContext(),
+ mExpanded ? R.drawable.ic_expand_less : R.drawable.ic_expand_more,
+ R.attr.secondary);
+ }
+
+ public void setMessage(@NonNull String msg)
+ {
+ TextView message = mContentLayout.findViewById(R.id.message);
+ message.setText(msg);
+ }
+
+ public void setButtonLabel(@NonNull String label)
+ {
+ TextView button = mContentLayout.findViewById(R.id.button);
+ button.setText(label);
+ }
+
+ public void setClickListener(@Nullable OnClickListener listener)
+ {
+ mContentLayout.findViewById(R.id.button).setOnClickListener(listener);
+ }
+}