Bug 1288106 - Move history (highlights) into main recyclerview, and eliminated horizontal highlights r=sebastian
Moving all vertically listed items into one RecylerView avoids the layouting issues encountered
with nested RVs. This results in a slightly more complex adapter, however overall this still
seems simpler than having to hack around the RecyclerView height measurements. (This also
makes the layout itself simpler, which hopefully means better performance too.)
MozReview-Commit-ID: HFS9q5JNYpY
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/ActivityStream.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/ActivityStream.java
@@ -1,30 +1,35 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.home.activitystream;
import android.content.Context;
+import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.widget.FrameLayout;
+import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.R;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.home.HomeBanner;
import org.mozilla.gecko.home.HomeFragment;
import org.mozilla.gecko.home.HomeScreen;
+import org.mozilla.gecko.home.SimpleCursorLoader;
public class ActivityStream extends FrameLayout implements HomeScreen {
+ private StreamRecyclerAdapter adapter;
public ActivityStream(Context context, AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.as_content, this);
}
@Override
@@ -60,18 +65,57 @@ public class ActivityStream extends Fram
// TODO: we should probably implement this to show snippets.
}
@Override
public void load(LoaderManager lm, FragmentManager fm, String panelId, Bundle restoreData,
PropertyAnimator animator) {
// Signal to load data from storage as needed, compare with HomePager
RecyclerView rv = (RecyclerView) findViewById(R.id.activity_stream_main_recyclerview);
- rv.setAdapter(new MainRecyclerAdapter(getContext()));
+
+ adapter = new StreamRecyclerAdapter();
+ rv.setAdapter(adapter);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
rv.setHasFixedSize(true);
+
+ lm.initLoader(0, null, new CursorLoaderCallbacks());
}
@Override
public void unload() {
// Signal to clear data that has been loaded, compare with HomePager
}
+
+ /**
+ * This is a temporary cursor loader. We'll probably need a completely new query for AS,
+ * at that time we can switch to the new CursorLoader, as opposed to using our outdated
+ * SimpleCursorLoader.
+ */
+ private static class HistoryLoader extends SimpleCursorLoader {
+ public HistoryLoader(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected Cursor loadCursor() {
+ final Context context = getContext();
+ return GeckoProfile.get(context).getDB()
+ .getRecentHistory(context.getContentResolver(), 10);
+ }
+ }
+
+ private class CursorLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ return new HistoryLoader(getContext());
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ adapter.swapCursor(data);
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ adapter.swapCursor(null);
+ }
+ }
}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/HighlightRecyclerAdapter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.mozilla.gecko.home.activitystream;
-
-
-import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.mozilla.gecko.R;
-
-class HighlightRecyclerAdapter extends RecyclerView.Adapter<HighlightRecyclerAdapter.ViewHolder> {
-
- private final Context context;
- private final String[] items = {
- "What Do The Reviews Have To Say About the New Ghostbusters",
- "The Dark Secrets Of This Now-Empty Island in Maine",
- "How to Prototype a Game in Under 7 Days (2005)",
- "Fuchsia, a new operating system"
- };
- private final String[] items_time = {
- "3h",
- "3h",
- "3h",
- "3h"
- };
-
- HighlightRecyclerAdapter(Context context) {
- this.context = context;
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater
- .from(context)
- .inflate(R.layout.activity_stream_card_highlights_item, parent, false);
- return new ViewHolder(v);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- holder.vLabel.setText(items[position]);
- holder.vTimeSince.setText(items_time[position]);
- int res = context.getResources()
- .getIdentifier("thumb_" + (position + 1), "drawable", context.getPackageName());
- holder.vThumbnail.setImageResource(res);
- }
-
- @Override
- public int getItemCount() {
- return items.length;
- }
-
- static class ViewHolder extends RecyclerView.ViewHolder {
- TextView vLabel;
- TextView vTimeSince;
- ImageView vThumbnail;
-
- public ViewHolder(View itemView) {
- super(itemView);
- vLabel = (TextView) itemView.findViewById(R.id.card_highlights_label);
- vTimeSince = (TextView) itemView.findViewById(R.id.card_highlights_time_since);
- vThumbnail = (ImageView) itemView.findViewById(R.id.card_highlights_thumbnail);
- }
- }
-}
-
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/HistoryRecyclerAdapter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.mozilla.gecko.home.activitystream;
-
-import android.content.Context;
-import android.support.v7.widget.CardView;
-import android.support.v7.widget.RecyclerView;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.mozilla.gecko.R;
-
-class HistoryRecyclerAdapter extends RecyclerView.Adapter<HistoryRecyclerAdapter.ViewHolder> {
-
- private final Context context;
- private final String[] items = {
- "What Do The Reviews Have To Say About the New Ghostbusters",
- "New “Leaf” Is More Efficient Than Natural Photosynthesis",
- "Zero-cost futures in Rust",
- "Indie Hackers: Learn how developers are making money",
- "The fight to cheat death is heating up"
- };
-
- HistoryRecyclerAdapter(Context context) {
- this.context = context;
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View v = LayoutInflater
- .from(context)
- .inflate(R.layout.activity_stream_card_history_item, parent, false);
- return new ViewHolder(v);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- holder.vLabel.setText(items[position]);
- }
-
- @Override
- public int getItemCount() {
- return items.length;
- }
-
- static class ViewHolder extends RecyclerView.ViewHolder {
- TextView vLabel;
- ViewHolder(View itemView) {
- super(itemView);
- vLabel = (TextView) itemView.findViewById(R.id.card_history_label);
- }
- }
-}
-
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/MainRecyclerLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.mozilla.gecko.home.activitystream;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-
-import org.mozilla.gecko.R;
-
-public class MainRecyclerLayout extends LinearLayout {
- public MainRecyclerLayout(Context context) {
- super(context);
- RecyclerView rv = (RecyclerView) findViewById(R.id.activity_stream_main_recyclerview);
- rv.setAdapter(new MainRecyclerAdapter(context));
- rv.setLayoutManager(new LinearLayoutManager(context));
- }
-
- public MainRecyclerLayout(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- public MainRecyclerLayout(Context context, @Nullable AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItem.java
@@ -0,0 +1,88 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.mozilla.gecko.home.activitystream;
+
+import android.database.Cursor;
+import android.support.v7.widget.RecyclerView;
+import android.text.format.DateUtils;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.db.BrowserContract;
+
+public abstract class StreamItem extends RecyclerView.ViewHolder {
+ public StreamItem(View itemView) {
+ super(itemView);
+ }
+
+ public void bind(Cursor cursor) {
+ throw new IllegalStateException("Cannot bind " + this.getClass().getSimpleName());
+ }
+
+ public static class TopPanel extends StreamItem {
+ public static final int LAYOUT_ID = R.layout.activity_stream_main_toppanel;
+
+ public TopPanel(View itemView) {
+ super(itemView);
+ }
+ }
+
+ public static class BottomPanel extends StreamItem {
+ public static final int LAYOUT_ID = R.layout.activity_stream_main_bottompanel;
+
+ public BottomPanel(View itemView) {
+ super(itemView);
+ }
+ }
+
+ public static class CompactItem extends StreamItem {
+ public static final int LAYOUT_ID = R.layout.activity_stream_card_history_item;
+
+ final TextView vLabel;
+ final TextView vTimeSince;
+
+ public CompactItem(View itemView) {
+ super(itemView);
+ vLabel = (TextView) itemView.findViewById(R.id.card_history_label);
+ vTimeSince = (TextView) itemView.findViewById(R.id.card_history_time_since);
+ }
+
+ @Override
+ public void bind(Cursor cursor) {
+ vLabel.setText(cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.History.TITLE)));
+
+ final long timeVisited = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.History.DATE_LAST_VISITED));
+ final String ago = DateUtils.getRelativeTimeSpanString(timeVisited, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, 0).toString();
+ vTimeSince.setText(ago);
+ }
+ }
+
+ public static class HighlightItem extends StreamItem {
+ public static final int LAYOUT_ID = R.layout.activity_stream_card_highlights_item;
+
+ final TextView vLabel;
+ final TextView vTimeSince;
+ final ImageView vThumbnail;
+
+ public HighlightItem(View itemView) {
+ super(itemView);
+ vLabel = (TextView) itemView.findViewById(R.id.card_highlights_label);
+ vTimeSince = (TextView) itemView.findViewById(R.id.card_highlights_time_since);
+ vThumbnail = (ImageView) itemView.findViewById(R.id.card_highlights_thumbnail);
+ }
+
+ @Override
+ public void bind(Cursor cursor) {
+ vLabel.setText(cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.History.TITLE)));
+
+ final long timeVisited = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.History.DATE_LAST_VISITED));
+ final String ago = DateUtils.getRelativeTimeSpanString(timeVisited, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, 0).toString();
+ vTimeSince.setText(ago);
+ }
+ }
+
+}
rename from mobile/android/base/java/org/mozilla/gecko/home/activitystream/MainRecyclerAdapter.java
rename to mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamRecyclerAdapter.java
--- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/MainRecyclerAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamRecyclerAdapter.java
@@ -1,140 +1,94 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.home.activitystream;
-
-import android.content.Context;
-import android.support.v7.widget.LinearLayoutManager;
+import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
-import android.util.TypedValue;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.mozilla.gecko.R;
-import java.util.Arrays;
-import java.util.List;
+import org.mozilla.gecko.home.activitystream.StreamItem.BottomPanel;
+import org.mozilla.gecko.home.activitystream.StreamItem.CompactItem;
+import org.mozilla.gecko.home.activitystream.StreamItem.HighlightItem;
+import org.mozilla.gecko.home.activitystream.StreamItem.TopPanel;
-
-class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder> {
+public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> {
+ private Cursor highlightsCursor;
- private final Context context;
-
- private static final int VIEW_TYPE_TOP_SITES = 0;
- private static final int VIEW_TYPE_HIGHLIGHTS = 1;
- private static final int VIEW_TYPE_HISTORY = 2;
-
- private static final int VIEW_SIZE_TOP_SITES = 115;
- private static final int VIEW_SIZE_HIGHLIGHTS = 220;
- private static final int VIEW_SIZE_HISTORY = 80;
-
- private final List<Item> categories = Arrays.asList(
- new Item("Top Sites"),
- new Item("Highlights"),
- new Item("History")
- );
-
- MainRecyclerAdapter(Context context) {
- this.context = context;
+ @Override
+ public int getItemViewType(int position) {
+ if (position == 0) {
+ return TopPanel.LAYOUT_ID;
+ } else if (position == getItemCount() - 1) {
+ return BottomPanel.LAYOUT_ID;
+ } else {
+ // TODO: in future we'll want to create different items for some results, tbc?
+ // For now let's show a detailed view for these two positions...
+ if (position == 2 || position == 6) {
+ return HighlightItem.LAYOUT_ID;
+ }
+ return CompactItem.LAYOUT_ID;
+ }
}
@Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View itemView = LayoutInflater
- .from(context)
- .inflate(R.layout.activity_stream_category, parent, false);
- return new ViewHolder(itemView);
+ public StreamItem onCreateViewHolder(ViewGroup parent, final int type) {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+
+ if (type == TopPanel.LAYOUT_ID) {
+ return new TopPanel(inflater.inflate(type, parent, false));
+ } else if (type == BottomPanel.LAYOUT_ID) {
+ return new BottomPanel(inflater.inflate(type, parent, false));
+ } else if (type == CompactItem.LAYOUT_ID) {
+ return new CompactItem(inflater.inflate(type, parent, false));
+ } else if (type == HighlightItem.LAYOUT_ID) {
+ return new HighlightItem(inflater.inflate(type, parent, false));
+ } else {
+ throw new IllegalStateException("Missing inflation for ViewType " + type);
+ }
+ }
+
+ private int translatePositionToCursor(int position) {
+ if (position == 0 ||
+ position == getItemCount() - 1) {
+ throw new IllegalArgumentException("Requested cursor position for invalid item");
+ }
+
+ // We have one blank panel at the top, hence remove that to obtain the cursor position
+ return position - 1;
}
@Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- LinearLayoutManager llm = new LinearLayoutManager(context);
- if (position == VIEW_TYPE_TOP_SITES) {
- holder.vCategoryRv.setAdapter(new TopSitesRecyclerAdapter(context));
- setCorrectedLayoutOrientation(llm, LinearLayoutManager.HORIZONTAL);
- setCorrectedLayoutHeight(context, VIEW_SIZE_TOP_SITES, holder, llm);
- } else if (position == VIEW_TYPE_HIGHLIGHTS) {
- holder.vCategoryRv.setAdapter(new HighlightRecyclerAdapter(context));
- setCorrectedLayoutOrientation(llm, LinearLayoutManager.HORIZONTAL);
- setCorrectedLayoutHeight(context, VIEW_SIZE_HIGHLIGHTS, holder, llm);
- } else if (position == VIEW_TYPE_HISTORY) {
- holder.vCategoryRv.setAdapter(new HistoryRecyclerAdapter(context));
- setCorrectedLayoutOrientation(llm, LinearLayoutManager.VERTICAL);
- setCorrectedLayoutHeight(context, VIEW_SIZE_HISTORY, holder, llm);
- }
+ public void onBindViewHolder(StreamItem holder, int position) {
+ int type = getItemViewType(position);
- holder.vCategoryRv.setLayoutManager(llm);
+ if (type == CompactItem.LAYOUT_ID ||
+ type == HighlightItem.LAYOUT_ID) {
- if (position != VIEW_TYPE_HISTORY) {
- holder.vTitle.setText(categories.get(position).getLabel());
- holder.vMore.setVisibility(View.VISIBLE);
+ final int cursorPosition = translatePositionToCursor(position);
+
+ highlightsCursor.moveToPosition(cursorPosition);
+ holder.bind(highlightsCursor);
}
}
@Override
public int getItemCount() {
- return categories.size();
- }
-
- private void setCorrectedLayoutHeight(final Context context,
- final int height,
- final ViewHolder holder,
- final LinearLayoutManager llm) {
- int correctedHeight = height;
- if (isHistoryView(llm)) {
- int holderItemCount;
- holderItemCount = holder.vCategoryRv.getAdapter().getItemCount();
- correctedHeight = height * holderItemCount;
+ final int highlightsCount;
+ if (highlightsCursor != null) {
+ highlightsCount = highlightsCursor.getCount();
+ } else {
+ highlightsCount = 0;
}
- setHolderRecyclerViewHeight(holder,
- getActualPixelValue(context, correctedHeight));
- }
- private static int getActualPixelValue(Context context, int height) {
- return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height,
- context.getResources().getDisplayMetrics());
- }
-
- private static void setHolderRecyclerViewHeight(ViewHolder holder, int height) {
- holder.vCategoryRv.setLayoutParams(new LinearLayout.LayoutParams(
- holder.vCategoryRv.getLayoutParams().width, height));
- }
-
- private static boolean isHistoryView(LinearLayoutManager llm) {
- return llm.getOrientation() == LinearLayoutManager.VERTICAL;
+ return 2 + highlightsCount;
}
- private void setCorrectedLayoutOrientation(final LinearLayoutManager lm,
- final int orientation) {
- lm.setOrientation(orientation);
- }
-
- static class ViewHolder extends RecyclerView.ViewHolder {
- TextView vTitle;
- TextView vMore;
- RecyclerView vCategoryRv;
- ViewHolder(View itemView) {
- super(itemView);
- vTitle = (TextView) itemView.findViewById(R.id.category_title);
- vMore = (TextView) itemView.findViewById(R.id.category_more_link);
- vCategoryRv = (RecyclerView) itemView.findViewById(R.id.recycler_category);
- }
- }
+ public void swapCursor(Cursor cursor) {
+ highlightsCursor = cursor;
- static class Item {
- String label;
-
- Item(String label) {
- setLabel(label);
- }
-
- public void setLabel(String label) {
- this.label = label;
- }
-
- public String getLabel() {
- return label;
- }
+ notifyDataSetChanged();
}
-}
\ No newline at end of file
+}
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -826,8 +826,13 @@ just addresses the organization to follo
<!ENTITY helper_first_offline_bookmark_title "Read offline">
<!ENTITY helper_first_offline_bookmark_message "Find your Reader View items in Bookmarks, even offline.">
<!ENTITY helper_first_offline_bookmark_button "Go to Bookmarks">
<!ENTITY helper_triple_readerview_open_title "Available offline">
<!ENTITY helper_triple_readerview_open_message "Bookmark Reader View items to read them offline.">
<!ENTITY helper_triple_readerview_open_button "Add to Bookmarks">
+<!ENTITY activity_stream_topsites "Top Sites">
+<!ENTITY activity_stream_highlights "Highlights">
+<!-- LOCALIZATION NOTE (activity_stream_more): Link that opens the detailed bookmark/history lists
+ when pressed. -->
+<!ENTITY activity_stream_more "More">
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -425,20 +425,18 @@ gbjar.sources += ['java/org/mozilla/geck
'GeckoProfilesProvider.java',
'GeckoUpdateReceiver.java',
'GlobalHistory.java',
'GuestSession.java',
'health/HealthRecorder.java',
'health/SessionInformation.java',
'health/StubbedHealthRecorder.java',
'home/activitystream/ActivityStream.java',
- 'home/activitystream/HighlightRecyclerAdapter.java',
- 'home/activitystream/HistoryRecyclerAdapter.java',
- 'home/activitystream/MainRecyclerAdapter.java',
- 'home/activitystream/MainRecyclerLayout.java',
+ 'home/activitystream/StreamItem.java',
+ 'home/activitystream/StreamRecyclerAdapter.java',
'home/activitystream/TopSitesRecyclerAdapter.java',
'home/BookmarkFolderView.java',
'home/BookmarkScreenshotRow.java',
'home/BookmarksListAdapter.java',
'home/BookmarksListView.java',
'home/BookmarksPanel.java',
'home/BrowserSearch.java',
'home/ClientsAdapter.java',
--- a/mobile/android/base/resources/layout/activity_stream_card_highlights_item.xml
+++ b/mobile/android/base/resources/layout/activity_stream_card_highlights_item.xml
@@ -1,22 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
- android:layout_width="180dp"
- android:layout_height="match_parent">
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="vertical">
<FrameLayout
android:background="@color/disabled_grey"
android:layout_width="match_parent"
android:layout_height="140dp">
@@ -25,65 +26,53 @@
android:id="@+id/card_highlights_thumbnail"
android:src="@drawable/favicon_globe"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<RelativeLayout
android:padding="3dp"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="wrap_content">
<TextView
android:id="@+id/card_highlights_label"
android:textSize="10sp"
android:maxLines="3"
android:ellipsize="end"
+ tools:text="FooBar"
android:textColor="@android:color/black"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/card_highlights_time_since"
android:layout_toLeftOf="@+id/card_highlights_time_since"
android:layout_alignParentTop="true"
- android:layout_above="@+id/linearLayout3"/>
+ android:layout_alignBottom="@+id/card_highlights_time_since"/>
<TextView
android:id="@+id/card_highlights_time_since"
- android:text="2h"
+ tools:text="2h"
android:textSize="10sp"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
- <LinearLayout
- android:layout_marginTop="5dp"
- android:orientation="horizontal"
+ <TextView
+ tools:text="Bookmarked"
+ android:textSize="10sp"
+ android:drawableLeft="@drawable/search_icon_active"
+ android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentStart="true"
+ android:layout_below="@+id/card_highlights_label"
android:layout_alignParentLeft="true"
- android:id="@+id/linearLayout3">
-
- <ImageView
- android:src="@drawable/search_icon_active"
- android:alpha="0.5"
- android:layout_width="18dp"
- android:layout_height="18dp"/>
-
- <TextView
- android:text="Bookmarked"
- android:textSize="10sp"
- android:gravity="center_vertical"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"/>
- </LinearLayout>
+ android:layout_alignParentStart="true"/>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
--- a/mobile/android/base/resources/layout/activity_stream_card_history_item.xml
+++ b/mobile/android/base/resources/layout/activity_stream_card_history_item.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="0dp"
android:layout_width="match_parent"
android:layout_height="60dp">
@@ -26,61 +27,51 @@
android:src="@drawable/favicon_globe"
android:scaleType="fitCenter"
android:layout_gravity="center"
android:layout_width="30dp"
android:layout_height="30dp"/>
</FrameLayout>
<FrameLayout
- android:id="@+id/frameLayout2"
- android:layout_toRightOf="@id/frameLayout1"
- android:layout_toEndOf="@id/frameLayout1"
- android:layout_width="50dp"
- android:layout_height="match_parent">
-
- <ImageView
- android:src="@drawable/tab_new"
- android:alpha="0.5"
- android:scaleType="fitCenter"
- android:layout_gravity="center"
- android:layout_width="15dp"
- android:layout_height="15dp"/>
- </FrameLayout>
-
- <FrameLayout
android:id="@+id/frameLayout3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_toRightOf="@id/frameLayout2"
- android:layout_toEndOf="@id/frameLayout2">
+ android:layout_toRightOf="@+id/imageView"
+ android:layout_toLeftOf="@+id/card_history_time_since">
<TextView
android:id="@+id/card_history_label"
+ tools:text="Descriptive title of a page..."
android:gravity="center_vertical"
android:maxLines="2"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
- <LinearLayout
- android:id="@+id/linearLayout5"
- android:orientation="vertical"
+ <TextView
+ android:id="@+id/card_history_time_since"
+ tools:text="20m"
+ android:textSize="12sp"
+ android:gravity="bottom|right"
+ android:paddingRight="4dp"
+ android:paddingEnd="4dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
- android:layout_width="40dp"
- android:layout_height="match_parent">
+ android:layout_alignParentTop="false"/>
- <TextView
- android:id="@+id/card_history_time_since"
- android:text="20m"
- android:textSize="12sp"
- android:gravity="bottom|right"
- android:paddingRight="4dp"
- android:paddingEnd="4dp"
- android:layout_margin="4dp"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- </LinearLayout>
+ <ImageView
+ android:src="@drawable/tab_new"
+ android:alpha="0.5"
+ android:scaleType="fitCenter"
+ android:layout_gravity="center"
+ android:layout_width="50dp"
+ android:layout_height="15dp"
+ android:layout_centerVertical="true"
+ android:layout_toRightOf="@+id/frameLayout1"
+ android:layout_toEndOf="@+id/frameLayout1"
+ android:id="@+id/imageView"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
--- a/mobile/android/base/resources/layout/activity_stream_card_top_sites_item.xml
+++ b/mobile/android/base/resources/layout/activity_stream_card_top_sites_item.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:orientation="vertical"
android:layout_width="90dp"
android:layout_height="match_parent">
@@ -29,17 +30,17 @@
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/card_row_label"
- android:text="Firefox"
+ tools:text="Firefox"
android:textSize="10sp"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
deleted file mode 100644
--- a/mobile/android/base/resources/layout/activity_stream_category.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="match_parent">
-
- <RelativeLayout
- android:orientation="horizontal"
- android:layout_marginRight="12dp"
- android:layout_marginEnd="12dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <TextView
- android:id="@+id/category_title"
- android:textStyle="bold"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"/>
-
- <TextView
- android:id="@+id/category_more_link"
- android:text="More"
- android:visibility="invisible"
- android:textAllCaps="true"
- android:textSize="14sp"
- android:textColor="@android:color/holo_orange_dark"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignParentEnd="true"/>
-
- </RelativeLayout>
-
- <android.support.v7.widget.RecyclerView
- android:id="@+id/recycler_category"
- android:layout_marginTop="5dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
-</LinearLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout/activity_stream_main_bottompanel.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+</LinearLayout>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout/activity_stream_main_toppanel.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+
+ <TextView
+ android:id="@+id/title_topsites"
+ android:text="@string/activity_stream_topsites"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:textStyle="bold"
+ android:layout_alignParentTop="true"
+ android:layout_toLeftOf="@+id/more_topsites"
+ android:layout_toStartOf="@+id/more_topsites"/>
+
+ <TextView
+ android:id="@+id/more_topsites"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:textAllCaps="true"
+ android:textColor="@android:color/holo_orange_dark"
+ android:textSize="14sp"
+ android:text="@string/activity_stream_more"
+ tools:text="More"
+ android:layout_alignBottom="@+id/title_topsites"/>
+
+ <android.support.v7.widget.RecyclerView
+ android:layout_width="match_parent"
+ android:layout_height="115dp"
+ android:id="@+id/android.support.v7.widget.RecyclerView"
+ android:layout_below="@+id/title_topsites"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"/>
+
+ <TextView
+ android:id="@+id/title_highlights"
+ android:text="@string/activity_stream_highlights"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textStyle="bold"
+ android:layout_below="@+id/android.support.v7.widget.RecyclerView"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_toLeftOf="@+id/more_highlights"
+ android:layout_toStartOf="@+id/more_highlights"/>
+
+ <TextView
+ android:id="@+id/more_highlights"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAllCaps="true"
+ android:textColor="@android:color/holo_orange_dark"
+ android:textSize="14sp"
+ android:text="@string/activity_stream_more"
+ android:layout_alignTop="@+id/title_highlights"
+ android:layout_alignLeft="@+id/more_topsites"
+ android:layout_alignStart="@+id/more_topsites"/>
+
+
+</RelativeLayout>
\ No newline at end of file
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -629,9 +629,12 @@
<string name="helper_first_offline_bookmark_title">&helper_first_offline_bookmark_title;</string>
<string name="helper_first_offline_bookmark_message">&helper_first_offline_bookmark_message;</string>
<string name="helper_first_offline_bookmark_button">&helper_first_offline_bookmark_button;</string>
<string name="helper_triple_readerview_open_title">&helper_triple_readerview_open_title;</string>
<string name="helper_triple_readerview_open_message">&helper_triple_readerview_open_message;</string>
<string name="helper_triple_readerview_open_button">&helper_triple_readerview_open_button;</string>
+ <string name="activity_stream_topsites">&activity_stream_topsites;</string>
+ <string name="activity_stream_highlights">&activity_stream_highlights;</string>
+ <string name="activity_stream_more">&activity_stream_more;</string>
</resources>