Bug 1377819 - Use ViewStub and give a default implementation of TabsLayout instead of puting an interface in layout xml.
As per comment 1, and I can't find a STR for onCreateView not being called, I try to use ViewStub to swap TabLayout for different layout/orientation.
And for portrait mode, I give a default implementation (i.e. AutoFitTabsGridLayout) since compact tab is now by default.
The problem for View Stub is that I can't set custom attribute to it.(i.e gecko:tabs="tabs_private).
So I need to add extra tabs_panel_private for it. This seems to be redundant but I can't think of a better way to make this change smaller.
Maybe set isPrivate for TabsLayout programmatically, but this will also need to move tabsAdapter out from constructor... that may be a future enhancement.
I haven't decided if I should do the enhancement now, and I'll be super busy next week. So if any one is intrested in it, feel free to continue the work.
MozReview-Commit-ID: 5Ht0Rxhpew6
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/src/main/res/layout-land/tabs_panel_normal.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<org.mozilla.gecko.tabs.AutoFitTabsGridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:gecko="http://schemas.android.com/apk/res-auto"
+ style="@style/TabsLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ gecko:tabs="tabs_normal">
+
+</org.mozilla.gecko.tabs.AutoFitTabsGridLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/src/main/res/layout-land/tabs_panel_private.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<org.mozilla.gecko.tabs.AutoFitTabsGridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:gecko="http://schemas.android.com/apk/res-auto"
+ style="@style/TabsLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ gecko:tabs="tabs_private">
+
+</org.mozilla.gecko.tabs.AutoFitTabsGridLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/src/main/res/layout-large/tabs_panel_normal.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<org.mozilla.gecko.tabs.AutoFitTabsGridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:gecko="http://schemas.android.com/apk/res-auto"
+ style="@style/TabsLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ gecko:tabs="tabs_normal">
+
+</org.mozilla.gecko.tabs.AutoFitTabsGridLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/src/main/res/layout-large/tabs_panel_private.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<org.mozilla.gecko.tabs.AutoFitTabsGridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:gecko="http://schemas.android.com/apk/res-auto"
+ style="@style/TabsLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ gecko:tabs="tabs_private">
+
+</org.mozilla.gecko.tabs.AutoFitTabsGridLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/src/main/res/layout-port/tabs_panel_normal.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<org.mozilla.gecko.tabs.CompactTabsGridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:gecko="http://schemas.android.com/apk/res-auto"
+ style="@style/TabsLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ gecko:tabs="tabs_normal">
+
+</org.mozilla.gecko.tabs.CompactTabsGridLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/src/main/res/layout-port/tabs_panel_private.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<org.mozilla.gecko.tabs.CompactTabsGridLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:gecko="http://schemas.android.com/apk/res-auto"
+ style="@style/TabsLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ gecko:tabs="tabs_private">
+
+</org.mozilla.gecko.tabs.CompactTabsGridLayout>
--- a/mobile/android/app/src/main/res/layout/tabs_panel_default.xml
+++ b/mobile/android/app/src/main/res/layout/tabs_panel_default.xml
@@ -79,23 +79,22 @@
</RelativeLayout>
<FrameLayout
android:id="@+id/tabs_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <view class="org.mozilla.gecko.tabs.TabsPanel$TabsLayout"
- android:id="@+id/normal_tabs"
- style="@style/TabsLayout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- gecko:tabs="tabs_normal"/>
+ <ViewStub
+ android:id="@+id/normal_tabs"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout="@layout/tabs_panel_normal"
+ android:visibility="gone"/>
<org.mozilla.gecko.tabs.PrivateTabsPanel
android:id="@+id/private_tabs_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</FrameLayout>
--- a/mobile/android/app/src/photon/res/layout/private_tabs_panel.xml
+++ b/mobile/android/app/src/photon/res/layout/private_tabs_panel.xml
@@ -65,18 +65,16 @@
android:textColor="@color/link_blue"/>
</LinearLayout>
</ScrollView>
<!-- Note: for an unknown reason, scrolling in the TabsLayout
does not work unless it is laid out after the empty view. -->
- <view
+ <ViewStub
android:id="@+id/private_tabs_layout"
- style="@style/TabsLayout"
- class="org.mozilla.gecko.tabs.TabsPanel$TabsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="gone"
- gecko:tabs="tabs_private"/>
+ android:layout="@layout/tabs_panel_private"
+ android:visibility="gone"/>
</merge>
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -75,16 +75,17 @@ import org.mozilla.gecko.reader.SavedRea
import org.mozilla.gecko.reader.ReaderModeUtils;
import org.mozilla.gecko.reader.ReadingListHelper;
import org.mozilla.gecko.restrictions.Restrictable;
import org.mozilla.gecko.restrictions.Restrictions;
import org.mozilla.gecko.search.SearchEngineManager;
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
import org.mozilla.gecko.tabqueue.TabQueueHelper;
import org.mozilla.gecko.tabqueue.TabQueuePrompt;
+import org.mozilla.gecko.tabs.CompactTabsGridLayout;
import org.mozilla.gecko.tabs.TabHistoryController;
import org.mozilla.gecko.tabs.TabHistoryController.OnShowTabHistory;
import org.mozilla.gecko.tabs.TabHistoryFragment;
import org.mozilla.gecko.tabs.TabHistoryPage;
import org.mozilla.gecko.tabs.TabsPanel;
import org.mozilla.gecko.telemetry.TelemetryUploadService;
import org.mozilla.gecko.telemetry.TelemetryCorePingDelegate;
import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
@@ -349,17 +350,17 @@ public class BrowserApp extends GeckoApp
private boolean mHasResumed;
@Override
public View onCreateView(final String name, final Context context, final AttributeSet attrs) {
final View view;
if (BrowserToolbar.class.getName().equals(name)) {
view = BrowserToolbar.create(context, attrs);
- } else if (TabsPanel.TabsLayout.class.getName().equals(name)) {
+ } else if (CompactTabsGridLayout.class.getName().equals(name)) {
view = TabsPanel.createTabsLayout(context, attrs);
} else {
view = super.onCreateView(name, context, attrs);
}
return view;
}
@Override
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/AutoFitTabsGridLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/AutoFitTabsGridLayout.java
@@ -9,26 +9,26 @@ import org.mozilla.gecko.R;
import org.mozilla.gecko.widget.GridSpacingDecoration;
import android.content.Context;
import android.content.res.Resources;
import android.support.v7.widget.GridLayoutManager;
import android.util.AttributeSet;
import android.util.Log;
-class AutoFitTabsGridLayout extends TabsGridLayout {
+public class AutoFitTabsGridLayout extends TabsGridLayout {
private static final String LOGTAG = "Gecko" + AutoFitTabsGridLayout.class.getSimpleName();
private GridSpacingDecoration spacingDecoration;
private final int desiredItemWidth;
private final int desiredHorizontalItemSpacing;
private final int minHorizontalItemSpacing;
private final int verticalItemPadding;
- AutoFitTabsGridLayout(Context context, AttributeSet attrs) {
+ public AutoFitTabsGridLayout(Context context, AttributeSet attrs) {
super(context, attrs, 1);
final Resources resources = context.getResources();
desiredItemWidth = resources.getDimensionPixelSize(R.dimen.tab_panel_item_width_autofit);
desiredHorizontalItemSpacing = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_item_hpadding_autofit);
minHorizontalItemSpacing = resources.getDimensionPixelOffset(R.dimen.tab_panel_grid_min_item_hspacing_autofit);
verticalItemPadding = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_item_vpadding_autofit);
final int viewPaddingVertical = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_vpadding_autofit);
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/CompactTabsGridLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/CompactTabsGridLayout.java
@@ -7,17 +7,17 @@ package org.mozilla.gecko.tabs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.widget.GridSpacingDecoration;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
-class CompactTabsGridLayout extends TabsGridLayout {
+public class CompactTabsGridLayout extends TabsGridLayout {
CompactTabsGridLayout(Context context, AttributeSet attrs) {
super(context, attrs, 2);
final Resources resources = context.getResources();
final int desiredHorizontalItemSpacing = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_hpadding_compact);
final int viewPaddingVertical = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_vpadding_compact);
setPadding(desiredHorizontalItemSpacing, viewPaddingVertical, desiredHorizontalItemSpacing, viewPaddingVertical);
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/PrivateTabsPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/PrivateTabsPanel.java
@@ -12,38 +12,40 @@ import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.tabs.TabsPanel.CloseAllPanelView;
import org.mozilla.gecko.tabs.TabsPanel.TabsLayout;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewStub;
import android.widget.RelativeLayout;
import android.widget.TextView;
import static org.mozilla.gecko.Tabs.LOADURL_NEW_TAB;
import static org.mozilla.gecko.Tabs.LOADURL_PRIVATE;
/**
* A container that wraps the private tabs {@link android.widget.AdapterView} and empty
* {@link android.view.View} to manage both of their visibility states by changing the visibility of
* this container as calling {@link android.widget.AdapterView#setVisibility} does not affect the
* empty View's visibility.
*/
-class PrivateTabsPanel extends RelativeLayout implements CloseAllPanelView {
+public class PrivateTabsPanel extends RelativeLayout implements CloseAllPanelView {
private final static String PRIVATE_BROWSING_URL = "https://support.mozilla.org/kb/private-browsing-firefox-android";
private final TabsLayout tabsLayout;
public PrivateTabsPanel(final Context context, final AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.private_tabs_panel, this);
- tabsLayout = (TabsLayout) findViewById(R.id.private_tabs_layout);
+ final ViewStub viewStub = (ViewStub) findViewById(R.id.private_tabs_layout);
+ tabsLayout = (TabsLayout) viewStub.inflate();
final View emptyTabsFrame = findViewById(R.id.private_tabs_empty);
tabsLayout.setEmptyView(emptyTabsFrame);
final TextView learnMoreView = (TextView) findViewById(R.id.learn_more_link);
learnMoreView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
@@ -35,16 +35,17 @@ import android.support.v4.content.Contex
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewStub;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import org.mozilla.gecko.switchboard.SwitchBoard;
@@ -82,26 +83,25 @@ public class TabsPanel extends LinearLay
}
private static boolean tabletOrLandscapeMode(Context context) {
return HardwareUtils.isTablet() ||
context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
public static View createTabsLayout(final Context context, final AttributeSet attrs) {
- if (tabletOrLandscapeMode(context)) {
- return new AutoFitTabsGridLayout(context, attrs);
- } else {
+ if (!tabletOrLandscapeMode(context)) {
// Phone in portrait mode.
if (GeckoSharedPrefs.forApp(context).getBoolean(GeckoPreferences.PREFS_COMPACT_TABS, true)) {
return new CompactTabsGridLayout(context, attrs);
} else {
return new TabsListLayout(context, attrs);
}
}
+ return null;
}
private final Context mContext;
private final GeckoApp mActivity;
private final LightweightTheme mTheme;
private RelativeLayout mHeader;
private FrameLayout mTabsContainer;
private PanelView mPanel;
@@ -143,17 +143,18 @@ public class TabsPanel extends LinearLay
private void inflateLayout(Context context) {
LayoutInflater.from(context).inflate(R.layout.tabs_panel_default, this);
}
private void initialize() {
mHeader = (RelativeLayout) findViewById(R.id.tabs_panel_header);
mTabsContainer = (FrameLayout) findViewById(R.id.tabs_container);
- mPanelNormal = (PanelView) findViewById(R.id.normal_tabs);
+ final ViewStub stub = (ViewStub) findViewById(R.id.normal_tabs);
+ mPanelNormal = (PanelView) stub.inflate();
mPanelNormal.setTabsPanel(this);
mPanelPrivate = (PanelView) findViewById(R.id.private_tabs_panel);
mPanelPrivate.setTabsPanel(this);
mAddTab = (ImageButton) findViewById(R.id.add_tab);
mAddTab.setOnClickListener(new Button.OnClickListener() {
@Override