Dbrant has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/389564 )

Change subject: WIP: Randomizr var. B
......................................................................

WIP: Randomizr var. B

Bug: T158788
Change-Id: I852dd46323258cfab4d89ddbdcbc4fefb9ed5734
---
M app/build.gradle
M app/src/main/AndroidManifest.xml
M app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
M app/src/main/java/org/wikipedia/feed/FeedFragment.java
M app/src/main/java/org/wikipedia/feed/featured/FeaturedArticleCardView.java
M app/src/main/java/org/wikipedia/feed/mainpage/MainPageCardView.java
M app/src/main/java/org/wikipedia/feed/random/RandomCardView.java
M app/src/main/java/org/wikipedia/feed/view/StaticCardView.java
M app/src/main/java/org/wikipedia/main/MainFragment.java
A app/src/main/java/org/wikipedia/random/RandomActivity.java
M app/src/main/java/org/wikipedia/random/RandomArticleRequestHandler.java
A app/src/main/java/org/wikipedia/random/RandomFragment.java
A app/src/main/java/org/wikipedia/random/RandomItemView.java
M app/src/main/java/org/wikipedia/random/RandomSummaryClient.java
M app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
A app/src/main/res/drawable/background_random.png
A app/src/main/res/drawable/ic_replay_black_24dp.xml
A app/src/main/res/drawable/ic_today_24dp.xml
D app/src/main/res/drawable/icon_feed_random.xml
D app/src/main/res/drawable/icon_feed_today.xml
A app/src/main/res/layout-land/fragment_random.xml
A app/src/main/res/layout/fragment_random.xml
A app/src/main/res/layout/view_random_item.xml
M app/src/main/res/layout/view_static_card.xml
M app/src/main/res/values/strings.xml
M app/src/main/res/values/strings_no_translate.xml
M app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java
27 files changed, 689 insertions(+), 164 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/64/389564/1

diff --git a/app/build.gradle b/app/build.gradle
index f2a915b..8458420 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -208,6 +208,7 @@
     implementation "commons-io:commons-io:2.5"
     implementation 'org.jsoup:jsoup:1.10.2'
     implementation 'com.dmitrybrant:zimdroid:0.0.14'
+    implementation "com.yuyakaido.android:card-stack-view:1.0.0-beta8"
 
     annotationProcessor 
"com.jakewharton:butterknife-compiler:$butterKnifeVersion"
 
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 02b4856..d86513b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -236,6 +236,10 @@
             android:label="@string/on_this_day"
             android:theme="@style/AppTheme.ActionBar"/>
 
+        <activity android:name=".random.RandomActivity"
+            android:label="@string/view_random_card_title"
+            android:theme="@style/AppTheme.ActionBar"/>
+
         <provider
             android:authorities="${applicationId}"
             android:name=".database.AppContentProvider"
diff --git a/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java 
b/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
index 61a291c..7d6f4da 100644
--- a/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
+++ b/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
@@ -35,8 +35,8 @@
         conditionallyAddPendingClient(new AggregatedFeedContentClient(), 
online);
         addPendingClient(new ContinueReadingClient());
         conditionallyAddPendingClient(new OnThisDayClient(), online && 
isPreBetaRelease());
-        conditionallyAddPendingClient(new MainPageClient(), age == 0);
+        conditionallyAddPendingClient(new MainPageClient(), age % 2 == 0);
+        conditionallyAddPendingClient(new RandomClient(), age % 2 == 0);
         conditionallyAddPendingClient(new BecauseYouReadClient(), online);
-        conditionallyAddPendingClient(new RandomClient(), age == 0);
     }
 }
diff --git a/app/src/main/java/org/wikipedia/feed/FeedFragment.java 
b/app/src/main/java/org/wikipedia/feed/FeedFragment.java
index afacfa9..1e00c0e 100644
--- a/app/src/main/java/org/wikipedia/feed/FeedFragment.java
+++ b/app/src/main/java/org/wikipedia/feed/FeedFragment.java
@@ -7,6 +7,7 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.design.widget.Snackbar;
+import android.support.v4.app.ActivityOptionsCompat;
 import android.support.v4.app.Fragment;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.widget.RecyclerView;
@@ -23,7 +24,7 @@
 import org.wikipedia.WikipediaApp;
 import org.wikipedia.activity.FragmentUtil;
 import org.wikipedia.analytics.FeedFunnel;
-import org.wikipedia.feed.featured.FeaturedArticleCard;
+import org.wikipedia.feed.featured.FeaturedArticleCardView;
 import org.wikipedia.feed.image.FeaturedImage;
 import org.wikipedia.feed.image.FeaturedImageCard;
 import org.wikipedia.feed.model.Card;
@@ -37,6 +38,7 @@
 import org.wikipedia.history.HistoryEntry;
 import org.wikipedia.offline.LocalCompilationsActivity;
 import org.wikipedia.offline.OfflineTutorialActivity;
+import org.wikipedia.random.RandomActivity;
 import org.wikipedia.readinglist.sync.ReadingListSynchronizer;
 import org.wikipedia.settings.Prefs;
 import org.wikipedia.settings.SettingsActivity;
@@ -73,8 +75,8 @@
         void onFeedVoiceSearchRequested();
         void onFeedSelectPage(HistoryEntry entry);
         void onFeedAddPageToList(HistoryEntry entry);
-        void onFeedAddFeaturedPageToList(FeedFragment fragment, 
FeaturedArticleCard card, HistoryEntry entry);
-        void onFeedRemovePageFromList(FeedFragment fragment, Card card, 
HistoryEntry entry);
+        void onFeedAddFeaturedPageToList(FeaturedArticleCardView view, 
HistoryEntry entry);
+        void onFeedRemovePageFromList(FeaturedArticleCardView view, 
HistoryEntry entry);
         void onFeedSharePage(HistoryEntry entry);
         void onFeedNewsItemSelected(NewsItemCard card, 
HorizontalScrollingListCardItemView view);
         void onFeedShareImage(FeaturedImageCard card);
@@ -157,12 +159,6 @@
         ReadingListSynchronizer.instance().sync();
 
         return view;
-    }
-
-    public void notifyItemChanged(@NonNull Card card) {
-        if (feedAdapter != null && feedAdapter.getItemPosition(card) > -1) {
-            feedAdapter.notifyItemChanged(feedAdapter.getItemPosition(card));
-        }
     }
 
     public boolean shouldElevateToolbar() {
@@ -341,16 +337,16 @@
         }
 
         @Override
-        public void onAddFeaturedPageToList(@NonNull FeaturedArticleCard card, 
@NonNull HistoryEntry entry) {
+        public void onAddFeaturedPageToList(@NonNull FeaturedArticleCardView 
view, @NonNull HistoryEntry entry) {
             if (getCallback() != null) {
-                getCallback().onFeedAddFeaturedPageToList(FeedFragment.this, 
card, entry);
+                getCallback().onFeedAddFeaturedPageToList(view, entry);
             }
         }
 
         @Override
-        public void onRemoveFeaturedPageFromList(@NonNull FeaturedArticleCard 
card, @NonNull HistoryEntry entry) {
+        public void onRemoveFeaturedPageFromList(@NonNull 
FeaturedArticleCardView view, @NonNull HistoryEntry entry) {
             if (getCallback() != null) {
-                getCallback().onFeedRemovePageFromList(FeedFragment.this, 
card, entry);
+                getCallback().onFeedRemovePageFromList(view, entry);
             }
         }
 
@@ -441,6 +437,13 @@
         }
 
         @Override
+        public void onRandomClick(@NonNull RandomCardView view) {
+            ActivityOptionsCompat options = ActivityOptionsCompat.
+                    makeSceneTransitionAnimation(getActivity(), view, 
getString(R.string.transition_random_activity));
+            startActivity(RandomActivity.newIntent(getActivity()), 
options.toBundle());
+        }
+
+        @Override
         public void onGetRandomError(@NonNull Throwable t, @NonNull final 
RandomCardView view) {
             Snackbar snackbar = FeedbackUtil.makeSnackbar(getActivity(), 
ThrowableUtil.isOffline(t)
                     ? getString(R.string.view_wiki_error_message_offline) : 
t.getMessage(),
diff --git 
a/app/src/main/java/org/wikipedia/feed/featured/FeaturedArticleCardView.java 
b/app/src/main/java/org/wikipedia/feed/featured/FeaturedArticleCardView.java
index 5ff1ef0..df8288d 100644
--- a/app/src/main/java/org/wikipedia/feed/featured/FeaturedArticleCardView.java
+++ b/app/src/main/java/org/wikipedia/feed/featured/FeaturedArticleCardView.java
@@ -33,8 +33,8 @@
         implements ItemTouchHelperSwipeAdapter.SwipeableView {
 
     public interface Callback {
-        void onAddFeaturedPageToList(@NonNull FeaturedArticleCard card, 
@NonNull HistoryEntry entry);
-        void onRemoveFeaturedPageFromList(@NonNull FeaturedArticleCard card, 
@NonNull HistoryEntry entry);
+        void onAddFeaturedPageToList(@NonNull FeaturedArticleCardView view, 
@NonNull HistoryEntry entry);
+        void onRemoveFeaturedPageFromList(@NonNull FeaturedArticleCardView 
view, @NonNull HistoryEntry entry);
     }
 
     @BindView(R.id.view_featured_article_card_header) View headerView;
@@ -48,9 +48,10 @@
         super(context);
         inflate(getContext(), R.layout.view_card_featured_article, this);
         ButterKnife.bind(this);
+        imageView.setLegacyVisibilityHandlingEnabled(true);
     }
 
-    @Override public void setCard(@NonNull FeaturedArticleCard card) {
+    public void setCard(@NonNull FeaturedArticleCard card, boolean wantHeader) 
{
         super.setCard(card);
 
         String articleTitle = card.articleTitle();
@@ -63,8 +64,24 @@
         extract(extract);
         image(imageUri);
 
-        header(card);
+        if (wantHeader) {
+            header(card);
+        }
         footer(card);
+    }
+
+    @Override public void setCard(@NonNull FeaturedArticleCard card) {
+        setCard(card, true);
+    }
+
+    public void updateFooter() {
+        if (getCard() != null) {
+            footer(getCard());
+        }
+    }
+
+    @Nullable public String getTitle() {
+        return getCard() == null ? null : getCard().articleTitle();
     }
 
     @OnClick({R.id.view_featured_article_card_image, 
R.id.view_featured_article_card_text_container})
@@ -165,7 +182,7 @@
         @Override
         public void onClick(View v) {
             if (getCallback() != null && getCard() != null) {
-                getCallback().onAddFeaturedPageToList(getCard(), getEntry());
+                
getCallback().onAddFeaturedPageToList(FeaturedArticleCardView.this, getEntry());
             }
         }
     }
@@ -178,7 +195,7 @@
                     @Override
                     public void onAddRequest(@Nullable ReadingListPage page) {
                         if (getCallback() != null && getCard() != null) {
-                            getCallback().onAddFeaturedPageToList(getCard(),
+                            
getCallback().onAddFeaturedPageToList(FeaturedArticleCardView.this,
                                     
getCard().historyEntry(HistoryEntry.SOURCE_FEED_FEATURED));
                         }
                     }
@@ -186,7 +203,7 @@
                     @Override
                     public void onDeleted(@Nullable ReadingListPage page) {
                         if (getCallback() != null && getCard() != null) {
-                            
getCallback().onRemoveFeaturedPageFromList(getCard(), getEntry());
+                            
getCallback().onRemoveFeaturedPageFromList(FeaturedArticleCardView.this, 
getEntry());
                         }
                     }
                 }).show(getEntry().getTitle());
diff --git 
a/app/src/main/java/org/wikipedia/feed/mainpage/MainPageCardView.java 
b/app/src/main/java/org/wikipedia/feed/mainpage/MainPageCardView.java
index 7bdf2e2..8724a42 100644
--- a/app/src/main/java/org/wikipedia/feed/mainpage/MainPageCardView.java
+++ b/app/src/main/java/org/wikipedia/feed/mainpage/MainPageCardView.java
@@ -3,6 +3,7 @@
 import android.content.Context;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
 import android.view.View;
 
 import org.wikipedia.R;
@@ -23,7 +24,9 @@
         setTitle(getString(R.string.view_main_page_card_title));
         
setSubtitle(String.format(getString(R.string.view_main_page_card_subtitle),
                 DateFormat.getDateInstance().format(new Date())));
-        setIcon(R.drawable.icon_feed_today);
+        getIconView().setImageResource(R.drawable.ic_today_24dp);
+        getIconView().setBackgroundColor(ContextCompat.getColor(getContext(), 
R.color.green30));
+        setContainerBackground(R.color.green50);
     }
 
     @Override public void setCallback(@Nullable FeedAdapter.Callback callback) 
{
diff --git a/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java 
b/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java
index 592377c..364907a 100644
--- a/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java
+++ b/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java
@@ -1,6 +1,7 @@
 package org.wikipedia.feed.random;
 
 import android.content.Context;
+import android.os.Build;
 import android.support.annotation.NonNull;
 import android.view.View;
 
@@ -12,15 +13,21 @@
 
 public class RandomCardView extends StaticCardView<RandomCard> {
     public interface Callback {
+        void onRandomClick(@NonNull RandomCardView view);
         void onGetRandomError(@NonNull Throwable t, @NonNull RandomCardView 
view);
     }
 
     public RandomCardView(@NonNull Context context) {
         super(context);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            setTransitionName(getString(R.string.transition_random_activity));
+        }
         setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                getRandomPage();
+                if (getCallback() != null) {
+                    getCallback().onRandomClick(RandomCardView.this);
+                }
             }
         });
     }
@@ -29,7 +36,9 @@
         super.setCard(card);
         setTitle(getString(R.string.view_random_card_title));
         setSubtitle(getString(R.string.view_random_card_subtitle));
-        setIcon(R.drawable.icon_feed_random);
+        getIconView().setImageResource(R.drawable.ic_casino_accent50_24dp);
+        getIconView().setBackgroundResource(R.drawable.background_random);
+        setContainerBackground(R.color.accent50);
     }
 
     public void getRandomPage() {
diff --git a/app/src/main/java/org/wikipedia/feed/view/StaticCardView.java 
b/app/src/main/java/org/wikipedia/feed/view/StaticCardView.java
index c5902fd..6a0697d 100644
--- a/app/src/main/java/org/wikipedia/feed/view/StaticCardView.java
+++ b/app/src/main/java/org/wikipedia/feed/view/StaticCardView.java
@@ -1,8 +1,9 @@
 package org.wikipedia.feed.view;
 
 import android.content.Context;
-import android.support.annotation.DrawableRes;
+import android.support.annotation.ColorRes;
 import android.support.annotation.StringRes;
+import android.support.v4.content.ContextCompat;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -14,6 +15,7 @@
 import butterknife.ButterKnife;
 
 public abstract class StaticCardView<T extends Card> extends 
DefaultFeedCardView<T> {
+    @BindView(R.id.view_static_card_container) View containerView;
     @BindView(R.id.view_static_card_title) TextView title;
     @BindView(R.id.view_static_card_subtitle) TextView subtitle;
     @BindView(R.id.view_static_card_icon) ImageView icon;
@@ -35,8 +37,12 @@
         subtitle.setText(text);
     }
 
-    protected void setIcon(@DrawableRes int resId) {
-        icon.setImageResource(resId);
+    protected ImageView getIconView() {
+        return icon;
+    }
+
+    protected void setContainerBackground(@ColorRes int color) {
+        containerView.setBackgroundColor(ContextCompat.getColor(getContext(), 
color));
     }
 
     protected void setProgress(boolean enabled) {
diff --git a/app/src/main/java/org/wikipedia/main/MainFragment.java 
b/app/src/main/java/org/wikipedia/main/MainFragment.java
index 79abfab..1c50fe9 100644
--- a/app/src/main/java/org/wikipedia/main/MainFragment.java
+++ b/app/src/main/java/org/wikipedia/main/MainFragment.java
@@ -33,10 +33,9 @@
 import org.wikipedia.analytics.IntentFunnel;
 import org.wikipedia.analytics.LoginFunnel;
 import org.wikipedia.feed.FeedFragment;
-import org.wikipedia.feed.featured.FeaturedArticleCard;
+import org.wikipedia.feed.featured.FeaturedArticleCardView;
 import org.wikipedia.feed.image.FeaturedImage;
 import org.wikipedia.feed.image.FeaturedImageCard;
-import org.wikipedia.feed.model.Card;
 import org.wikipedia.feed.news.NewsActivity;
 import org.wikipedia.feed.news.NewsItemCard;
 import org.wikipedia.feed.view.HorizontalScrollingListCardItemView;
@@ -246,25 +245,24 @@
                         AddToReadingListDialog.InvokeSource.FEED));
     }
 
-    @Override public void onFeedAddFeaturedPageToList(@NonNull final 
FeedFragment fragment,
-                                                      @NonNull final 
FeaturedArticleCard card,
+    @Override public void onFeedAddFeaturedPageToList(@NonNull final 
FeaturedArticleCardView view,
                                                       @NonNull HistoryEntry 
entry) {
         bottomSheetPresenter.show(getChildFragmentManager(),
                 AddToReadingListDialog.newInstance(entry.getTitle(),
                         AddToReadingListDialog.InvokeSource.FEED,
                         new DialogInterface.OnDismissListener() {
                             @Override public void onDismiss(DialogInterface 
dialogInterface) {
-                                // Update card view in case saved state has 
changed
-                                fragment.notifyItemChanged(card);
+                                view.updateFooter();
                             }
                         }));
     }
 
     @Override
-    public void onFeedRemovePageFromList(FeedFragment fragment, Card card, 
HistoryEntry entry) {
+    public void onFeedRemovePageFromList(@NonNull FeaturedArticleCardView view,
+                                         @NonNull HistoryEntry entry) {
         FeedbackUtil.showMessage(getActivity(),
                 getString(R.string.reading_list_item_deleted, 
entry.getTitle().getDisplayText()));
-        fragment.notifyItemChanged(card);
+        view.updateFooter();
     }
 
     @Override public void onFeedSharePage(HistoryEntry entry) {
diff --git a/app/src/main/java/org/wikipedia/random/RandomActivity.java 
b/app/src/main/java/org/wikipedia/random/RandomActivity.java
new file mode 100644
index 0000000..b2249b9
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/random/RandomActivity.java
@@ -0,0 +1,25 @@
+package org.wikipedia.random;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+
+import org.wikipedia.activity.SingleFragmentActivity;
+
+public class RandomActivity extends SingleFragmentActivity<RandomFragment> {
+    public static Intent newIntent(@NonNull Context context) {
+        return new Intent(context, RandomActivity.class);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getSupportActionBar().setElevation(0f);
+    }
+
+    @Override
+    public RandomFragment createFragment() {
+        return RandomFragment.newInstance();
+    }
+}
diff --git 
a/app/src/main/java/org/wikipedia/random/RandomArticleRequestHandler.java 
b/app/src/main/java/org/wikipedia/random/RandomArticleRequestHandler.java
index 919abbd..ac305eb 100644
--- a/app/src/main/java/org/wikipedia/random/RandomArticleRequestHandler.java
+++ b/app/src/main/java/org/wikipedia/random/RandomArticleRequestHandler.java
@@ -22,7 +22,8 @@
     public static void getRandomPage(@NonNull final Callback cb) {
         new 
RandomSummaryClient().request(WikipediaApp.getInstance().getWikiSite(), new 
RandomSummaryClient.Callback() {
             @Override
-            public void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull 
PageTitle title) {
+            public void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull 
RbPageSummary pageSummary) {
+                PageTitle title = new PageTitle(null, pageSummary.getTitle(), 
WikipediaApp.getInstance().getWikiSite());
                 cb.onSuccess(title);
             }
 
diff --git a/app/src/main/java/org/wikipedia/random/RandomFragment.java 
b/app/src/main/java/org/wikipedia/random/RandomFragment.java
new file mode 100644
index 0000000..91e1999
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/random/RandomFragment.java
@@ -0,0 +1,219 @@
+package org.wikipedia.random;
+
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.util.LruCache;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import com.yuyakaido.android.cardstackview.CardStackView;
+import com.yuyakaido.android.cardstackview.SwipeDirection;
+
+import org.wikipedia.R;
+import org.wikipedia.WikipediaApp;
+import org.wikipedia.dataclient.restbase.page.RbPageSummary;
+import org.wikipedia.history.HistoryEntry;
+import org.wikipedia.page.ExclusiveBottomSheetPresenter;
+import org.wikipedia.page.PageActivity;
+import org.wikipedia.page.PageTitle;
+import org.wikipedia.readinglist.AddToReadingListDialog;
+import org.wikipedia.util.FeedbackUtil;
+import org.wikipedia.util.log.L;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import butterknife.Unbinder;
+import retrofit2.Call;
+
+public class RandomFragment extends Fragment {
+    private static final String ITEM_VIEW_TAG = "randomItemViewTag";
+    private static final String CURRENT_ITEM_PARAM = "currentItem";
+    private static final int MAX_CACHE_ITEMS = 16;
+
+    @BindView(R.id.random_item_pager)
+    CardStackView randomPager;
+    @BindView(R.id.random_next_button) View nextButton;
+    @BindView(R.id.random_back_button) View backButton;
+    @BindView(R.id.random_save_button) View saveButton;
+    private Unbinder unbinder;
+
+    private LruCache<Integer, RbPageSummary> summaryCache = new 
LruCache<>(MAX_CACHE_ITEMS);
+    private List<Integer> inProgressPositions = new ArrayList<>();
+    private RandomArrayAdapter adapter = new RandomArrayAdapter();
+    private ExclusiveBottomSheetPresenter bottomSheetPresenter = new 
ExclusiveBottomSheetPresenter();
+
+    @NonNull
+    public static RandomFragment newInstance() {
+        return new RandomFragment();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setRetainInstance(true);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
Bundle savedInstanceState) {
+        super.onCreateView(inflater, container, savedInstanceState);
+        View view = inflater.inflate(R.layout.fragment_random, container, 
false);
+        unbinder = ButterKnife.bind(this, view);
+        FeedbackUtil.setToolbarButtonLongPressToast(nextButton);
+
+        randomPager.setAdapter(adapter);
+        randomPager.setCardEventListener(new CardStackView.CardEventListener() 
{
+            @Override
+            public void onCardDragging(float percentX, float percentY) {
+            }
+
+            @Override
+            public void onCardSwiped(SwipeDirection direction) {
+            }
+
+            @Override
+            public void onCardReversed() {
+            }
+
+            @Override
+            public void onCardMovedToOrigin() {
+            }
+
+            @Override
+            public void onCardClicked(int index) {
+                RandomItemView view = 
randomPager.getTopView().getContentContainer()
+                        .findViewWithTag(ITEM_VIEW_TAG);
+                if (view.getTitle() != null) {
+                    
startActivity(PageActivity.newIntentForNewTab(getActivity(),
+                            new HistoryEntry(view.getTitle(), 
HistoryEntry.SOURCE_RANDOM), view.getTitle()));
+                }
+            }
+        });
+
+        if (savedInstanceState != null) {
+            //randomPager.
+        }
+
+        return view;
+    }
+
+    public void onSaveInstanceState(Bundle outState) {
+        outState.putInt(CURRENT_ITEM_PARAM, randomPager.getTopIndex());
+    }
+
+    @Override
+    public void onDestroyView() {
+        unbinder.unbind();
+        unbinder = null;
+        super.onDestroyView();
+    }
+
+    @SuppressWarnings("checkstyle:magicnumber")
+    @OnClick(R.id.random_next_button) void onNextClick() {
+        View target = randomPager.getTopView();
+        ValueAnimator rotation = ObjectAnimator.ofPropertyValuesHolder(
+                target, PropertyValuesHolder.ofFloat("rotation", -30f));
+        rotation.setDuration(250);
+        ValueAnimator translateX = ObjectAnimator.ofPropertyValuesHolder(
+                target, PropertyValuesHolder.ofFloat("translationX", 0f, 
-2000f));
+        translateX.setDuration(250);
+        AnimatorSet set = new AnimatorSet();
+        set.playTogether(rotation, translateX);
+        randomPager.swipe(SwipeDirection.Left, set);
+    }
+
+    @OnClick(R.id.random_back_button) void onBackClick() {
+        randomPager.reverse();
+    }
+
+    @OnClick(R.id.random_save_button) void onSaveClick() {
+        RandomItemView view = randomPager.getTopView().getContentContainer()
+                .findViewWithTag(ITEM_VIEW_TAG);
+        if (view.getTitle() == null) {
+            return;
+        }
+        bottomSheetPresenter.show(getChildFragmentManager(),
+                AddToReadingListDialog.newInstance(view.getTitle(),
+                        AddToReadingListDialog.InvokeSource.RANDOM_ACTIVITY,
+                        new DialogInterface.OnDismissListener() {
+                            @Override
+                            public void onDismiss(DialogInterface 
dialogInterface) {
+                                // TODO: update reading list icon
+                            }
+                        }));
+    }
+
+    public void onRemovePageFromList(@NonNull PageTitle title) {
+        FeedbackUtil.showMessage(getActivity(),
+                getString(R.string.reading_list_item_deleted, 
title.getDisplayText()));
+        // TODO: update reading list icon
+    }
+
+
+    private void requestNewSummary(final int position) {
+        if (inProgressPositions.contains(position)) {
+            return;
+        }
+        inProgressPositions.add(position);
+        new 
RandomSummaryClient().request(WikipediaApp.getInstance().getWikiSite(), new 
RandomSummaryClient.Callback() {
+            @Override
+            public void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull 
RbPageSummary pageSummary) {
+                if (!isAdded()) {
+                    return;
+                }
+                inProgressPositions.remove((Integer) position);
+                summaryCache.put(position, pageSummary);
+                adapter.notifyDataSetChanged();
+            }
+
+            @Override
+            public void onError(@NonNull Call<RbPageSummary> call, @NonNull 
Throwable t) {
+                inProgressPositions.remove((Integer) position);
+                // TODO: show error.
+            }
+        });
+    }
+
+    private class RandomArrayAdapter extends BaseAdapter {
+        @Override public int getCount() {
+            return Integer.MAX_VALUE;
+        }
+
+        @Override @Nullable public Object getItem(int position) {
+            return position;
+        }
+
+        @Override public long getItemId(int position) {
+            return 0;
+        }
+
+        @NonNull
+        @Override
+        public View getView(int position, View contentView, @NonNull ViewGroup 
parent) {
+            L.d(">>>> getting view for position " + position);
+            if (contentView == null) {
+                contentView = new RandomItemView(getActivity());
+                contentView.setTag(ITEM_VIEW_TAG);
+            }
+            @Nullable RbPageSummary summary = summaryCache.get(position);
+            if (summary == null) {
+                requestNewSummary(position);
+            }
+            ((RandomItemView) contentView).setContents(summary);
+            return contentView;
+        }
+    }
+}
diff --git a/app/src/main/java/org/wikipedia/random/RandomItemView.java 
b/app/src/main/java/org/wikipedia/random/RandomItemView.java
new file mode 100644
index 0000000..22a5d91
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/random/RandomItemView.java
@@ -0,0 +1,61 @@
+package org.wikipedia.random;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import org.wikipedia.R;
+import org.wikipedia.WikipediaApp;
+import org.wikipedia.dataclient.restbase.page.RbPageSummary;
+import org.wikipedia.page.PageTitle;
+import org.wikipedia.views.FaceAndColorDetectImageView;
+import org.wikipedia.views.GoneIfEmptyTextView;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+public class RandomItemView extends FrameLayout {
+    @BindView(R.id.random_item_container) ViewGroup containerView;
+    @BindView(R.id.random_item_progress) View progressBar;
+    @BindView(R.id.view_featured_article_card_image) 
FaceAndColorDetectImageView imageView;
+    @BindView(R.id.view_featured_article_card_article_title) TextView 
articleTitleView;
+    @BindView(R.id.view_featured_article_card_article_subtitle) 
GoneIfEmptyTextView articleSubtitleView;
+    @BindView(R.id.view_featured_article_card_extract) TextView extractView;
+
+    @Nullable private RbPageSummary summary;
+
+    public RandomItemView(@NonNull Context context) {
+        super(context);
+        inflate(getContext(), R.layout.view_random_item, this);
+        ButterKnife.bind(this);
+        imageView.setLegacyVisibilityHandlingEnabled(true);
+    }
+
+    @Nullable public PageTitle getTitle() {
+        return summary == null ? null
+                : new PageTitle(summary.getTitle(), 
WikipediaApp.getInstance().getWikiSite());
+    }
+
+    public void setContents(@Nullable RbPageSummary pageSummary) {
+        containerView.setVisibility(pageSummary == null ? GONE : VISIBLE);
+        progressBar.setVisibility(pageSummary == null ? VISIBLE : GONE);
+        if (summary == pageSummary) {
+            return;
+        }
+        summary = pageSummary;
+        if (summary == null) {
+            return;
+        }
+        articleTitleView.setText(summary.getNormalizedTitle());
+        articleSubtitleView.setText(summary.getDescription());
+        extractView.setText(summary.getExtract());
+        imageView.loadImage(TextUtils.isEmpty(summary.getThumbnailUrl()) ? null
+                : Uri.parse(summary.getThumbnailUrl()));
+    }
+}
diff --git a/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java 
b/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java
index a8b794f..3a3f267 100644
--- a/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java
+++ b/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java
@@ -9,7 +9,6 @@
 import org.wikipedia.dataclient.restbase.page.RbPageSummary;
 import org.wikipedia.dataclient.retrofit.RbCachedService;
 import org.wikipedia.dataclient.retrofit.WikiCachedService;
-import org.wikipedia.page.PageTitle;
 import org.wikipedia.util.log.L;
 
 import retrofit2.Call;
@@ -24,11 +23,10 @@
             = new RbCachedService<>(Service.class);
 
     public Call<RbPageSummary> request(@NonNull WikiSite wiki, @NonNull 
Callback cb) {
-        return request(cachedService.service(wiki), wiki, cb);
+        return request(cachedService.service(wiki), cb);
     }
 
     @VisibleForTesting Call<RbPageSummary> request(@NonNull Service service,
-                                                   @NonNull final WikiSite 
wiki,
                                                    @NonNull final Callback cb) 
{
         Call<RbPageSummary> call = service.get();
         call.enqueue(new retrofit2.Callback<RbPageSummary>() {
@@ -39,9 +37,7 @@
                     cb.onError(call, new JsonParseException("Response missing 
required field(s)"));
                     return;
                 }
-                RbPageSummary item = response.body();
-                PageTitle title = new PageTitle(null, item.getTitle(), wiki);
-                cb.onSuccess(call, title);
+                cb.onSuccess(call, response.body());
             }
 
             @Override
@@ -60,7 +56,7 @@
     }
 
     public interface Callback {
-        void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull PageTitle 
title);
+        void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull 
RbPageSummary pageSummary);
         void onError(@NonNull Call<RbPageSummary> call, @NonNull Throwable t);
     }
 }
diff --git 
a/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java 
b/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
index 4f169f3..aef367c 100644
--- a/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
+++ b/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
@@ -43,7 +43,8 @@
         FEED(4),
         NEWS_ACTIVITY(5),
         READING_LIST_ACTIVITY(6),
-        MOST_READ_ACTIVITY(7);
+        MOST_READ_ACTIVITY(7),
+        RANDOM_ACTIVITY(8);
 
         private static final EnumCodeMap<InvokeSource> MAP = new 
EnumCodeMap<>(InvokeSource.class);
 
diff --git a/app/src/main/res/drawable/background_random.png 
b/app/src/main/res/drawable/background_random.png
new file mode 100644
index 0000000..0b93ae8
--- /dev/null
+++ b/app/src/main/res/drawable/background_random.png
Binary files differ
diff --git a/app/src/main/res/drawable/ic_replay_black_24dp.xml 
b/app/src/main/res/drawable/ic_replay_black_24dp.xml
new file mode 100644
index 0000000..5d2fd07
--- /dev/null
+++ b/app/src/main/res/drawable/ic_replay_black_24dp.xml
@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="24dp"
+    android:viewportHeight="24.0" android:viewportWidth="24.0"
+    android:width="24dp" 
xmlns:android="http://schemas.android.com/apk/res/android";>
+    <path android:fillColor="#FF000000" 
android:pathData="M12,5V1L7,6l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6 -6,-2.69 
-6,-6H4c0,4.42 3.58,8 8,8s8,-3.58 8,-8 -3.58,-8 -8,-8z"/>
+</vector>
diff --git a/app/src/main/res/drawable/ic_today_24dp.xml 
b/app/src/main/res/drawable/ic_today_24dp.xml
new file mode 100644
index 0000000..a87d09b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_today_24dp.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="m3.521,3.581 l16.959,0 0,0.771 -16.959,0 
0,-0.771zM2.75,5.123 L21.25,5.123 21.25,20.54 2.75,20.54 
2.75,5.123zM6.99,12.832a2.698,2.698 0,0 0,0 -5.396,2.698 2.698,0 1,0 
0,5.396zM11.229,7.436 L19.708,7.436 19.708,8.977 11.229,8.977 
11.229,7.436zM11.229,10.519 L19.708,10.519 19.708,12.061 11.229,12.061 
11.229,10.519zM11.229,13.602 L19.708,13.602 19.708,15.144 11.229,15.144 
11.229,13.602zM11.229,16.686 L19.708,16.686 19.708,18.227 11.229,18.227 
11.229,16.686z"
+        android:fillType="evenOdd"
+        android:fillColor="#ffffff"/>
+</vector>
diff --git a/app/src/main/res/drawable/icon_feed_random.xml 
b/app/src/main/res/drawable/icon_feed_random.xml
deleted file mode 100644
index 16acb5a..0000000
--- a/app/src/main/res/drawable/icon_feed_random.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android";
-    android:width="28dp"
-    android:height="29dp"
-    android:viewportWidth="28"
-    android:viewportHeight="29">
-
-    <path
-        android:fillColor="#2e6ee5"
-        android:strokeWidth="2.0999999"
-        android:strokeLineJoin="round"
-        android:pathData="M14.0318,0.626785 
C21.6959,0.626785,27.9089,6.83977,27.9089,14.5039
-C27.9089,22.168,21.6959,28.3809,14.0318,28.3809
-C6.36774,28.3809,0.154762,22.168,0.154762,14.5039
-C0.154762,6.83977,6.36774,0.626785,14.0318,0.626785 Z" />
-    <path
-        android:strokeWidth="1"
-        android:pathData="M-0.456283,0.00800657 L28.611,0.00800657 
L28.611,29.0753 L-0.456283,29.0753
-L-0.456283,0.00800657 Z" />
-    <path
-        android:fillColor="#ffffff"
-        android:strokeWidth="1"
-        android:pathData="M22.0859,17.0711 L18.9203,7.75586
-C18.6336,6.92689,17.8675,6.36648,17.0121,6.36648
-C16.7864,6.36648,16.5603,6.40327,16.3469,6.48135 L7.25892,9.72771
-C6.74807,9.90961,6.33811,10.2816,6.10602,10.7815
-C5.86794,11.2814,5.83843,11.8418,6.01749,12.3638 L9.18268,21.679
-C9.46781,22.508,10.2343,23.0668,11.0897,23.0668
-C11.3154,23.0668,11.5411,23.03,11.7545,22.9515 L20.8429,19.7072
-C21.3537,19.5253,21.7633,19.1529,21.9954,18.6534
-C22.2275,18.1551,22.257,17.5947,22.0859,17.0711 L22.0859,17.0711 Z
-M18.7652,16.143 C18.7652,17.767,16.3896,17.767,16.3896,16.143
-C16.3896,14.519,18.7652,14.519,18.7652,16.143 L18.7652,16.143 Z 
M13.8573,18.3462
-C13.8573,19.9702,11.4817,19.9702,11.4817,18.3462
-C11.4817,16.7242,13.8573,16.7242,13.8573,18.3462 L13.8573,18.3462 Z
-M16.6217,11.0883 C16.6217,12.7123,14.2445,12.7123,14.2445,11.0883
-C14.2445,9.4647,16.6217,9.4647,16.6217,11.0883 L16.6217,11.0883 Z
-M11.7058,13.2919 C11.7058,14.9159,9.3302,14.9159,9.3302,13.2919
-C9.3302,11.6679,11.7058,11.6679,11.7058,13.2919 L11.7058,13.2919 Z" />
-</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/icon_feed_today.xml 
b/app/src/main/res/drawable/icon_feed_today.xml
deleted file mode 100644
index 5c21a32..0000000
--- a/app/src/main/res/drawable/icon_feed_today.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector xmlns:android="http://schemas.android.com/apk/res/android";
-    android:width="25dp"
-    android:height="23dp"
-    android:viewportWidth="25"
-    android:viewportHeight="23">
-
-    <path
-        android:fillColor="#00af89"
-        android:strokeWidth="0.2"
-        android:strokeLineJoin="round"
-        android:pathData="M12.6875,0.125 
C19.0043,0.125,24.125,5.24574,24.125,11.5625
-C24.125,17.8793,19.0043,23,12.6875,23 C6.37074,23,1.25,17.8793,1.25,11.5625
-C1.25,5.24574,6.37074,0.125,12.6875,0.125 Z" />
-    <path
-        android:fillColor="#ffffff"
-        android:strokeWidth="1"
-        android:pathData="M6.68718,7.22093 L18.9602,7.22093 L18.9602,17.4484 
L6.68718,17.4484
-L6.68718,7.22093 L6.68718,7.22093 Z M9.75543,11.9938 
C10.6968,11.9938,11.46,11.2306,11.46,10.2892
-C11.46,9.34776,10.6968,8.58459,9.75543,8.58459
-C8.81401,8.58459,8.05085,9.34776,8.05085,10.2892
-C8.05085,11.2306,8.81401,11.9938,9.75543,11.9938 L9.75543,11.9938 Z" />
-    <path
-        android:fillColor="#00af89"
-        android:strokeWidth="1"
-        android:pathData="M12.327,11.3119 L17.5965,11.3119
-L17.5965,11.9938 L12.327,11.9938 L12.327,11.3119 L12.327,11.3119 Z
-M17.5965,9.94826 L17.5965,10.6301 L12.327,10.6301 L12.327,9.94826
-L17.5965,9.94826 Z M12.327,8.58459 L17.5965,8.58459 L17.5965,9.26642
-L12.327,9.26642 L12.327,8.58459 L12.327,8.58459 Z M12.327,12.6756
-L17.5965,12.6756 L17.5965,13.3574 L12.327,13.3574 L12.327,12.6756
-L12.327,12.6756 Z M12.327,14.0392 L17.5965,14.0392 L17.5965,14.7211
-L12.327,14.7211 L12.327,14.0392 L12.327,14.0392 Z M12.327,15.4029
-L17.5965,15.4029 L17.5965,16.0847 L12.327,16.0847 L12.327,15.4029
-L12.327,15.4029 Z" />
-    <path
-        android:fillColor="#ffffff"
-        android:strokeWidth="1"
-        android:pathData="M7.36902,5.98511 L18.2783,5.98511 L18.2783,6.66694 
L7.36902,6.66694 Z" />
-</vector>
\ No newline at end of file
diff --git a/app/src/main/res/layout-land/fragment_random.xml 
b/app/src/main/res/layout-land/fragment_random.xml
new file mode 100644
index 0000000..ca2d1db
--- /dev/null
+++ b/app/src/main/res/layout-land/fragment_random.xml
@@ -0,0 +1,73 @@
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android";
+    xmlns:app="http://schemas.android.com/apk/res-auto";
+    xmlns:tools="http://schemas.android.com/tools";
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="?attr/main_toolbar_color"
+    android:transitionName="@string/transition_random_activity"
+    android:orientation="horizontal">
+
+    <com.yuyakaido.android.cardstackview.CardStackView
+        android:id="@+id/random_item_pager"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        app:stackFrom="bottom"
+        app:swipeEnabled="true"
+        app:swipeDirection="horizontal" />
+
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="16dp"
+            android:orientation="vertical"
+            android:layout_gravity="center_vertical"
+            android:gravity="center_horizontal">
+
+            <ImageView
+                android:id="@+id/random_back_button"
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                android:padding="4dp"
+                android:focusable="true"
+                android:clickable="true"
+                android:background="?attr/selectableItemBackgroundBorderless"
+                app:srcCompat="@drawable/ic_replay_black_24dp"
+                android:tint="@android:color/white"
+                
android:contentDescription="@string/button_add_to_reading_list"/>
+
+            <android.support.design.widget.FloatingActionButton
+                android:id="@+id/random_next_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="32dp"
+                android:layout_marginBottom="32dp"
+                android:contentDescription="@string/view_next_random_article"
+                app:backgroundTint="@android:color/white"
+                app:borderWidth="0dp"
+                app:elevation="4dp"
+                app:srcCompat="@drawable/ic_casino_accent50_24dp"
+                android:tint="?attr/main_toolbar_color"/>
+
+            <ImageView
+                android:id="@+id/random_save_button"
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                android:padding="4dp"
+                android:focusable="true"
+                android:clickable="true"
+                android:background="?attr/selectableItemBackgroundBorderless"
+                app:srcCompat="@drawable/ic_bookmark_border_white_24dp"
+                android:tint="@android:color/white"
+                
android:contentDescription="@string/button_add_to_reading_list"/>
+
+        </LinearLayout>
+
+    </FrameLayout>
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/fragment_random.xml 
b/app/src/main/res/layout/fragment_random.xml
new file mode 100644
index 0000000..cb9861f
--- /dev/null
+++ b/app/src/main/res/layout/fragment_random.xml
@@ -0,0 +1,72 @@
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android";
+    xmlns:app="http://schemas.android.com/apk/res-auto";
+    xmlns:tools="http://schemas.android.com/tools";
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="?attr/main_toolbar_color"
+    android:transitionName="@string/transition_random_activity"
+    android:orientation="vertical">
+
+    <com.yuyakaido.android.cardstackview.CardStackView
+        android:id="@+id/random_item_pager"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        app:stackFrom="bottom"
+        app:swipeEnabled="true"
+        app:swipeDirection="horizontal" />
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="16dp"
+            android:layout_gravity="center_horizontal"
+            android:gravity="center_vertical">
+
+            <ImageView
+                android:id="@+id/random_back_button"
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                android:padding="4dp"
+                android:focusable="true"
+                android:clickable="true"
+                android:background="?attr/selectableItemBackgroundBorderless"
+                app:srcCompat="@drawable/ic_replay_black_24dp"
+                android:tint="@android:color/white"
+                
android:contentDescription="@string/button_add_to_reading_list"/>
+
+            <android.support.design.widget.FloatingActionButton
+                android:id="@+id/random_next_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="32dp"
+                android:layout_marginEnd="32dp"
+                android:contentDescription="@string/view_next_random_article"
+                app:backgroundTint="@android:color/white"
+                app:borderWidth="0dp"
+                app:elevation="4dp"
+                app:srcCompat="@drawable/ic_casino_accent50_24dp"
+                android:tint="?attr/main_toolbar_color"/>
+
+            <ImageView
+                android:id="@+id/random_save_button"
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                android:padding="4dp"
+                android:focusable="true"
+                android:clickable="true"
+                android:background="?attr/selectableItemBackgroundBorderless"
+                app:srcCompat="@drawable/ic_bookmark_border_white_24dp"
+                android:tint="@android:color/white"
+                
android:contentDescription="@string/button_add_to_reading_list"/>
+
+        </LinearLayout>
+
+    </FrameLayout>
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/view_random_item.xml 
b/app/src/main/res/layout/view_random_item.xml
new file mode 100644
index 0000000..179c15e
--- /dev/null
+++ b/app/src/main/res/layout/view_random_item.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android";
+    xmlns:app="http://schemas.android.com/apk/res-auto";
+    xmlns:tools="http://schemas.android.com/tools";
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.v7.widget.CardView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_margin="8dp"
+        app:cardBackgroundColor="?attr/paper_color"
+        app:cardUseCompatPadding="true">
+
+        <ProgressBar
+            android:id="@+id/random_item_progress"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="64dp"
+            android:layout_marginBottom="64dp"
+            android:background="?attr/paper_color"
+            android:layout_gravity="center"/>
+
+        <LinearLayout
+            android:id="@+id/random_item_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <org.wikipedia.views.FaceAndColorDetectImageView
+                style="@style/SimpleDraweeViewPlaceholder"
+                android:id="@+id/view_featured_article_card_image"
+                android:layout_width="match_parent"
+                android:layout_height="192dp"
+                app:fadeDuration="0"
+                app:actualImageScaleType="focusCrop" />
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:background="?attr/material_theme_border_color"/>
+
+            <LinearLayout
+                android:id="@+id/view_featured_article_card_text_container"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:paddingLeft="16dp"
+                android:paddingRight="16dp"
+                android:background="?attr/selectableItemBackground">
+
+                <TextView
+                    style="@style/RtlAwareTextView"
+                    android:id="@+id/view_featured_article_card_article_title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingTop="12dp"
+                    android:paddingBottom="4dp"
+                    android:textSize="24sp"
+                    android:fontFamily="serif"
+                    android:textColor="?attr/primary_text_color"
+                    android:lineSpacingMultiplier="0.9"
+                    android:maxLines="3"
+                    android:ellipsize="end"
+                    tools:text="Lorem ipsum"/>
+
+                <org.wikipedia.views.GoneIfEmptyTextView
+                    style="@style/RtlAwareTextView"
+                    
android:id="@+id/view_featured_article_card_article_subtitle"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:textColor="?attr/secondary_text_color"
+                    android:paddingTop="4dp"
+                    android:paddingBottom="4dp"
+                    android:textSize="12sp"
+                    android:maxLines="3"
+                    android:ellipsize="end"
+                    tools:text="Lorem ipsum"/>
+
+                <TextView
+                    style="@style/RtlAwareTextView"
+                    android:id="@+id/view_featured_article_card_extract"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingTop="8dp"
+                    android:paddingBottom="16dp"
+                    android:maxLines="4"
+                    android:ellipsize="end"
+                    android:lineSpacingMultiplier="1.4"
+                    android:textSize="14sp"
+                    android:textColor="?attr/primary_text_color"
+                    tools:text="Lorem ipsum"/>
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+    </android.support.v7.widget.CardView>
+
+</FrameLayout>
diff --git a/app/src/main/res/layout/view_static_card.xml 
b/app/src/main/res/layout/view_static_card.xml
index 0517736..a961742 100644
--- a/app/src/main/res/layout/view_static_card.xml
+++ b/app/src/main/res/layout/view_static_card.xml
@@ -2,62 +2,63 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android";
     xmlns:tools="http://schemas.android.com/tools";
+    android:id="@+id/view_static_card_container"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="?attr/selectableItemBackground">
+    android:foreground="?attr/selectableItemBackground">
+
+    <FrameLayout
+        android:layout_width="80dp"
+        android:layout_height="80dp"
+        android:layout_gravity="end|center_vertical">
+
+        <ImageView
+            android:id="@+id/view_static_card_icon"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:padding="16dp"
+            
android:contentDescription="@string/view_static_card_icon_content_description"
+            android:tint="@android:color/white"
+            tools:src="@drawable/ic_casino_accent50_24dp"/>
+
+        <ProgressBar
+            android:id="@+id/view_static_card_progress"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"/>
+
+    </FrameLayout>
 
     <LinearLayout
-        android:id="@+id/view_static_card_text_holder"
         android:layout_width="0dp"
-        android:layout_height="wrap_content"
+        android:layout_height="match_parent"
         android:layout_weight="1"
-        android:layout_gravity="center_vertical"
-        android:padding="16dp"
+        android:gravity="center_vertical"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
         android:orientation="vertical">
 
         <TextView
             android:id="@+id/view_static_card_title"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="2dp"
             android:fontFamily="sans-serif-medium"
             android:textSize="14sp"
-            android:textColor="?attr/section_title_color"
+            android:textColor="@android:color/white"
             tools:text="Title of card"/>
 
         <TextView
             android:id="@+id/view_static_card_subtitle"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="2dp"
             android:textSize="12sp"
-            android:textColor="?attr/secondary_text_color"
+            android:textColor="@android:color/white"
             android:alpha="0.87"
+            android:lineSpacingExtra="2dp"
             tools:text="Subtitle of card"/>
 
     </LinearLayout>
-
-    <FrameLayout
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:layout_gravity="end|center_vertical"
-        android:layout_marginTop="12dp"
-        android:layout_marginBottom="12dp"
-        android:layout_marginLeft="16dp"
-        android:layout_marginRight="16dp">
-
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:id="@+id/view_static_card_icon"
-            
android:contentDescription="@string/view_static_card_icon_content_description"
-            tools:src="@drawable/icon_feed_today"/>
-
-        <ProgressBar
-            android:id="@+id/view_static_card_progress"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent" />
-
-    </FrameLayout>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index 8fd8c41..5c76491 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -408,7 +408,7 @@
     <string name="view_continue_reading_card_title">Continue reading</string>
     <string name="view_because_you_read_card_title">Because you read</string>
     <string name="view_random_card_title">Randomizer</string>
-    <string name="view_random_card_subtitle">Read a random article from 
Wikipedia</string>
+    <string name="view_random_card_subtitle">Roll the dice! Tap to generate 
random articles to read from Wikipedia.</string>
     <string name="view_next_random_article">Load another random 
article</string>
     <string name="view_main_page_card_title">Today on Wikipedia</string>
     <string name="view_main_page_card_subtitle">Main page on %s</string>
diff --git a/app/src/main/res/values/strings_no_translate.xml 
b/app/src/main/res/values/strings_no_translate.xml
index fe42dce..19db219 100644
--- a/app/src/main/res/values/strings_no_translate.xml
+++ b/app/src/main/res/values/strings_no_translate.xml
@@ -103,6 +103,7 @@
 
     <!-- Transition names -->
     <string name="transition_news_item">newsItemTransition</string>
+    <string name="transition_random_activity">randomActivityTransition</string>
 
     <!-- Miscellaneous -->
     <string name="text_size_percent">%d%%</string>
diff --git 
a/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java 
b/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java
index bf845ad..0438d92 100644
--- a/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java
+++ b/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java
@@ -1,14 +1,11 @@
 package org.wikipedia.random;
 
-
 import android.support.annotation.NonNull;
 
 import com.google.gson.JsonParseException;
 
 import org.junit.Test;
-import org.wikipedia.dataclient.WikiSite;
 import org.wikipedia.dataclient.restbase.page.RbPageSummary;
-import org.wikipedia.page.PageTitle;
 import org.wikipedia.random.RandomSummaryClient.Callback;
 import org.wikipedia.random.RandomSummaryClient.Service;
 import org.wikipedia.test.MockWebServerTest;
@@ -59,12 +56,12 @@
     }
 
     @NonNull private Call<RbPageSummary> request(@NonNull Callback cb) {
-        return client.request(service(Service.class), 
WikiSite.forLanguageCode("test"), cb);
+        return client.request(service(Service.class), cb);
     }
 
     private void assertCallbackSuccess(@NonNull Call<RbPageSummary> call,
                                        @NonNull Callback cb) {
-        verify(cb).onSuccess(eq(call), any(PageTitle.class));
+        verify(cb).onSuccess(eq(call), any(RbPageSummary.class));
         //noinspection unchecked
         verify(cb, never()).onError(any(Call.class), any(Throwable.class));
     }
@@ -73,7 +70,7 @@
                                        @NonNull Callback cb,
                                        @NonNull Class<? extends Throwable> 
expectedThrowable) {
         //noinspection unchecked
-        verify(cb, never()).onSuccess(any(Call.class), any(PageTitle.class));
+        verify(cb, never()).onSuccess(any(Call.class), 
any(RbPageSummary.class));
         verify(cb).onError(eq(call), isA(expectedThrowable));
     }
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/389564
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I852dd46323258cfab4d89ddbdcbc4fefb9ed5734
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to