Commit a1e1a4b7 authored by Christian Dullweber's avatar Christian Dullweber Committed by Commit Bot

Animate PageInfo subpage transition

Create "fade-through" animation to switch between main page and subpage.
Remove animation for page-info rows.

Video: https://crbug.com/1077766#c42
Bug: 1077766
Change-Id: I330b57b79a0e6dbd421b1d10ac897f16246f2f6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2418373Reviewed-by: default avatarEhimare Okoyomon <eokoyomon@chromium.org>
Commit-Queue: Christian Dullweber <dullweber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808358}
parent 6d6f83a8
......@@ -19,8 +19,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:ellipsize="end"
android:layout_marginVertical="16dp"
android:ellipsize="end"
android:lineSpacingExtra="6dp"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.TextLarge.Primary" />
......@@ -33,27 +33,33 @@
android:ellipsize="end"
android:lineSpacingExtra="6dp"
android:paddingVertical="16dp"
android:visibility="gone"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.TextLarge.Primary" />
android:textAppearance="@style/TextAppearance.TextLarge.Primary"
android:visibility="gone" />
<LinearLayout
android:id="@+id/page_info_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/page_info_subpage_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingHorizontal="16dp"
android:id="@+id/page_info_subpage_header">
android:orientation="horizontal"
android:paddingHorizontal="16dp">
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/subpage_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="-12dp"
android:minHeight="@dimen/min_touch_target_size"
android:minWidth="@dimen/min_touch_target_size"
android:layout_marginEnd="20dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:minWidth="@dimen/min_touch_target_size"
android:minHeight="@dimen/min_touch_target_size"
android:src="@drawable/ic_arrow_back_white_24dp"
app:tint="@color/default_icon_color" />
......@@ -69,6 +75,7 @@
<FrameLayout
android:id="@+id/page_info_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
......@@ -8,6 +8,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
......@@ -17,6 +18,10 @@ import org.chromium.ui.widget.ChromeImageButton;
* Represents the url, a sub page header and container for page info content.
*/
public class PageInfoContainer extends FrameLayout {
public static final float sScale = 0.92f;
public static final int sOutDuration = 90;
public static final int sInDuration = 210;
/** Parameters to configure the view of page info subpage. */
public static class Params {
// Whether the URL title should be shown.
......@@ -35,16 +40,20 @@ public class PageInfoContainer extends FrameLayout {
private PageInfoView.ElidedUrlTextView mUrlTitle;
private TextView mTruncatedUrlTitle;
private final ViewGroup mWrapper;
private final ViewGroup mContent;
private View mCurrentView;
private final View mSubpageHeader;
private TextView mSubpageTitle;
private final FrameLayout mContent;
private final TextView mSubpageTitle;
public PageInfoContainer(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.page_info_container, this, true);
mWrapper = findViewById(R.id.page_info_wrapper);
mContent = findViewById(R.id.page_info_content);
mSubpageHeader = findViewById(R.id.page_info_subpage_header);
mSubpageTitle = findViewById(R.id.page_info_subpage_title);
mContent = findViewById(R.id.page_info_content);
}
public void setParams(Params params) {
......@@ -94,10 +103,37 @@ public class PageInfoContainer extends FrameLayout {
mTruncatedUrlTitle.setCompoundDrawablesRelative(favicon, null, null, null);
}
public void showPage(View view, CharSequence title, boolean isMainPage) {
public void showPage(View view, CharSequence subPageTitle, Runnable onPreviousPageRemoved) {
if (mCurrentView == null) {
// Don't animate if there is no current view.
assert onPreviousPageRemoved == null;
replaceContentView(view, subPageTitle);
return;
}
// Create "fade-through" animation.
// TODO(crbug.com/1077766): Animate height change and set correct interpolator.
mWrapper.animate().setDuration(sOutDuration).alpha(0).withEndAction(() -> {
replaceContentView(view, subPageTitle);
mWrapper.setScaleX(sScale);
mWrapper.setScaleY(sScale);
mWrapper.setAlpha(0);
mWrapper.animate()
.setDuration(sInDuration)
.scaleX(1)
.scaleY(1)
.alpha(1)
.withEndAction(onPreviousPageRemoved);
});
}
/**
* Replaces the current view with |view| and configures the subpage header.
*/
private void replaceContentView(View view, CharSequence subPageTitle) {
mContent.removeAllViews();
mCurrentView = view;
mSubpageHeader.setVisibility(subPageTitle != null ? VISIBLE : GONE);
mSubpageTitle.setText(subPageTitle);
mContent.addView(view);
mSubpageHeader.setVisibility(isMainPage ? GONE : VISIBLE);
mSubpageTitle.setText(title);
}
}
......@@ -264,7 +264,7 @@ public class PageInfoController implements PageInfoMainController, ModalDialogPr
containerParams.urlTitleLongClickCallback = viewParams.urlTitleLongClickCallback;
containerParams.urlTitleShown = viewParams.urlTitleShown;
mContainer.setParams(containerParams);
mContainer.showPage(mView, "", true);
mContainer.showPage(mView, null, null);
PageInfoViewV2 view2 = (PageInfoViewV2) mView;
mConnectionController = new PageInfoConnectionController(
this, view2.getConnectionRowView(), mWebContents, mDelegate.getVrHandler());
......@@ -580,17 +580,23 @@ public class PageInfoController implements PageInfoMainController, ModalDialogPr
*/
@Override
public void launchSubpage(PageInfoSubpageController controller) {
if (mSubpageController != null) return;
mSubpageController = controller;
CharSequence title = mSubpageController.getSubpageTitle();
View subview = mSubpageController.createViewForSubpage(mContainer);
mContainer.showPage(subview, title, false);
mContainer.showPage(subview, title, null);
controller.onSubPageAttached();
}
/**
* Exits the subpage of the current controller.
*/
@Override
public void exitSubpage() {
mContainer.showPage(mView, "", true);
if (mSubpageController == null) return;
mContainer.showPage(mView, null, () -> {
mSubpageController.onSubpageRemoved();
mSubpageController = null;
});
}
}
......@@ -75,7 +75,7 @@ public class PageInfoCookiesController
mSubPage.setParams(params);
AppCompatActivity host = (AppCompatActivity) mRowView.getContext();
host.getSupportFragmentManager().beginTransaction().add(mSubPage, "FOO").commitNow();
host.getSupportFragmentManager().beginTransaction().add(mSubPage, null).commitNow();
return mSubPage.requireView();
}
......@@ -99,6 +99,7 @@ public class PageInfoCookiesController
@Override
public void onSubpageRemoved() {
assert mSubPage != null;
AppCompatActivity host = (AppCompatActivity) mRowView.getContext();
host.getSupportFragmentManager().beginTransaction().remove(mSubPage).commitNow();
mSubPage = null;
......
......@@ -64,6 +64,7 @@ public class PageInfoPermissionsController implements PageInfoSubpageController
@Override
public void onSubpageRemoved() {
assert mSubpageFragment != null;
AppCompatActivity host = (AppCompatActivity) mRowView.getContext();
host.getSupportFragmentManager().beginTransaction().remove(mSubpageFragment).commitNow();
mSubpageFragment = null;
......
......@@ -261,18 +261,17 @@ public class PageInfoView extends FrameLayout implements OnClickListener {
return true;
});
}
initializePageInfoViewChild(
mUrlTitle, params.urlTitleShown, 0f, params.urlTitleClickCallback);
initializePageInfoViewChild(mUrlTitle, params.urlTitleShown, params.urlTitleClickCallback);
}
protected void initPreview(PageInfoViewParams params) {
mPreviewMessage = findViewById(R.id.page_info_preview_message);
mPreviewLoadOriginal = findViewById(R.id.page_info_preview_load_original);
mPreviewSeparator = findViewById(R.id.page_info_preview_separator);
initializePageInfoViewChild(mPreviewMessage, params.previewUIShown, 0f, null);
initializePageInfoViewChild(mPreviewLoadOriginal, params.previewUIShown, 0f,
initializePageInfoViewChild(mPreviewMessage, params.previewUIShown, null);
initializePageInfoViewChild(mPreviewLoadOriginal, params.previewUIShown,
params.previewShowOriginalClickCallback);
initializePageInfoViewChild(mPreviewSeparator, params.previewSeparatorShown, 0f, null);
initializePageInfoViewChild(mPreviewSeparator, params.previewSeparatorShown, null);
mPreviewLoadOriginal.setText(params.previewLoadOriginalMessage);
}
......@@ -280,21 +279,21 @@ public class PageInfoView extends FrameLayout implements OnClickListener {
mConnectionSummary = findViewById(R.id.page_info_connection_summary);
mConnectionMessage = findViewById(R.id.page_info_connection_message);
// Hide the connection summary until its text is set.
initializePageInfoViewChild(mConnectionSummary, false, 0f, null);
initializePageInfoViewChild(mConnectionMessage, params.connectionMessageShown, 0f, null);
initializePageInfoViewChild(mConnectionSummary, false, null);
initializePageInfoViewChild(mConnectionMessage, params.connectionMessageShown, null);
}
protected void initPerformance(PageInfoViewParams params) {
mPerformanceSummary = findViewById(R.id.page_info_performance_summary);
mPerformanceMessage = findViewById(R.id.page_info_performance_message);
initializePageInfoViewChild(mPerformanceSummary, false, 0f, null);
initializePageInfoViewChild(mPerformanceMessage, false, 0f, null);
initializePageInfoViewChild(mPerformanceSummary, false, null);
initializePageInfoViewChild(mPerformanceMessage, false, null);
}
protected void initHttpsImageCompression(PageInfoViewParams params) {
mHttpsImageCompressionMessage =
findViewById(R.id.page_info_lite_mode_https_image_compression_message);
initializePageInfoViewChild(mHttpsImageCompressionMessage, false, 0f, null);
initializePageInfoViewChild(mHttpsImageCompressionMessage, false, null);
}
protected void initPermissions(PageInfoViewParams params) {
......@@ -302,35 +301,35 @@ public class PageInfoView extends FrameLayout implements OnClickListener {
mPermissionsSeparator = findViewById(R.id.page_info_permissions_separator);
mPermissionsList = findViewById(R.id.page_info_permissions_list);
// Hide the permissions list for sites with no permissions.
initializePageInfoViewChild(mPermissionsTitle, false, 0f, null);
initializePageInfoViewChild(mPermissionsSeparator, false, 0f, null);
initializePageInfoViewChild(mPermissionsList, false, 1f, null);
initializePageInfoViewChild(mPermissionsTitle, false, null);
initializePageInfoViewChild(mPermissionsSeparator, false, null);
initializePageInfoViewChild(mPermissionsList, false, null);
}
protected void initCookies(PageInfoViewParams params) {
mCookieControlsSeparator = findViewById(R.id.page_info_cookie_controls_separator);
mCookieControlsView = findViewById(R.id.page_info_cookie_controls_view);
initializePageInfoViewChild(mCookieControlsSeparator, params.cookieControlsShown, 0f, null);
initializePageInfoViewChild(mCookieControlsView, params.cookieControlsShown, 0f, null);
initializePageInfoViewChild(mCookieControlsSeparator, params.cookieControlsShown, null);
initializePageInfoViewChild(mCookieControlsView, params.cookieControlsShown, null);
mOnUiClosingCallback = params.onUiClosingCallback;
}
protected void initInstantApp(PageInfoViewParams params) {
mInstantAppButton = findViewById(R.id.page_info_instant_app_button);
initializePageInfoViewChild(mInstantAppButton, params.instantAppButtonShown, 0f,
initializePageInfoViewChild(mInstantAppButton, params.instantAppButtonShown,
params.instantAppButtonClickCallback);
}
protected void initSiteSettings(PageInfoViewParams params) {
mSiteSettingsButton = findViewById(R.id.page_info_site_settings_button);
initializePageInfoViewChild(mSiteSettingsButton, params.siteSettingsButtonShown, 0f,
initializePageInfoViewChild(mSiteSettingsButton, params.siteSettingsButtonShown,
params.siteSettingsButtonClickCallback);
}
protected void initOpenOnline(PageInfoViewParams params) {
mOpenOnlineButton = findViewById(R.id.page_info_open_online_button);
// The open online button should not fade in.
initializePageInfoViewChild(mOpenOnlineButton, params.openOnlineButtonShown, 1f,
initializePageInfoViewChild(mOpenOnlineButton, params.openOnlineButtonShown,
params.openOnlineButtonClickCallback);
}
......@@ -411,10 +410,7 @@ public class PageInfoView extends FrameLayout implements OnClickListener {
clickCallback.run();
}
protected void initializePageInfoViewChild(
View child, boolean shown, float alpha, Runnable clickCallback) {
// Make all subviews transparent until the page info view is faded in.
child.setAlpha(alpha);
protected void initializePageInfoViewChild(View child, boolean shown, Runnable clickCallback) {
child.setVisibility(shown ? View.VISIBLE : View.GONE);
child.setTag(R.id.page_info_click_callback, clickCallback);
if (clickCallback == null) return;
......
......@@ -9,7 +9,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
......@@ -32,7 +32,7 @@ public class PageInfoViewV2 extends PageInfoView {
protected void init(PageInfoView.PageInfoViewParams params) {
super.init(params);
mRowWrapper = findViewById(R.id.page_info_row_wrapper);
initializePageInfoViewChild(mRowWrapper, true, 0f, null);
initializePageInfoViewChild(mRowWrapper, true, null);
}
@Override
......@@ -81,13 +81,8 @@ public class PageInfoViewV2 extends PageInfoView {
throw new RuntimeException();
}
/**
* Create a list of all the views which we want to individually fade in.
*/
@Override
protected List<View> collectAnimatableViews() {
// TODO(crbug.com/1077766): Sort and use rows instead of the rowWrapper.
return Arrays.asList(mPreviewMessage, mPreviewLoadOriginal, mPreviewSeparator,
mInstantAppButton, mRowWrapper, mSiteSettingsButton);
return Collections.emptyList();
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment