Merge "Fix Chooser enter transition animation" into tm-dev
This commit is contained in:
@@ -300,6 +300,8 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected ChooserMultiProfilePagerAdapter mChooserMultiProfilePagerAdapter;
|
protected ChooserMultiProfilePagerAdapter mChooserMultiProfilePagerAdapter;
|
||||||
|
private final EnterTransitionAnimationDelegate mEnterTransitionAnimationDelegate =
|
||||||
|
new EnterTransitionAnimationDelegate();
|
||||||
|
|
||||||
private boolean mRemoveSharedElements = false;
|
private boolean mRemoveSharedElements = false;
|
||||||
|
|
||||||
@@ -383,7 +385,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
// transition animation.
|
// transition animation.
|
||||||
getWindow().setWindowAnimations(0);
|
getWindow().setWindowAnimations(0);
|
||||||
}
|
}
|
||||||
startPostponedEnterTransition();
|
mEnterTransitionAnimationDelegate.markImagePreviewReady();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -431,7 +433,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
mHideParentOnFail = false;
|
mHideParentOnFail = false;
|
||||||
}
|
}
|
||||||
mRemoveSharedElements = true;
|
mRemoveSharedElements = true;
|
||||||
startPostponedEnterTransition();
|
mEnterTransitionAnimationDelegate.markImagePreviewReady();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,7 +726,7 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
mRemoveSharedElements = false;
|
mRemoveSharedElements = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
postponeEnterTransition();
|
mEnterTransitionAnimationDelegate.postponeTransition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1242,6 +1244,9 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
if (layout != null) {
|
if (layout != null) {
|
||||||
adjustPreviewWidth(getResources().getConfiguration().orientation, layout);
|
adjustPreviewWidth(getResources().getConfiguration().orientation, layout);
|
||||||
}
|
}
|
||||||
|
if (previewType != CONTENT_PREVIEW_IMAGE) {
|
||||||
|
mEnterTransitionAnimationDelegate.markImagePreviewReady();
|
||||||
|
}
|
||||||
|
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
@@ -2514,90 +2519,96 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
if (mResolverDrawerLayout == null || gridAdapter == null) {
|
if (mResolverDrawerLayout == null || gridAdapter == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int offset = calculateDrawerOffset(top, bottom, recyclerView, gridAdapter);
|
||||||
final int bottomInset = mSystemWindowInsets != null
|
mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
|
||||||
? mSystemWindowInsets.bottom : 0;
|
mEnterTransitionAnimationDelegate.markOffsetCalculated();
|
||||||
int offset = bottomInset;
|
|
||||||
int rowsToShow = gridAdapter.getSystemRowCount()
|
|
||||||
+ gridAdapter.getProfileRowCount()
|
|
||||||
+ gridAdapter.getServiceTargetRowCount()
|
|
||||||
+ gridAdapter.getCallerAndRankedTargetRowCount();
|
|
||||||
|
|
||||||
// then this is most likely not a SEND_* action, so check
|
|
||||||
// the app target count
|
|
||||||
if (rowsToShow == 0) {
|
|
||||||
rowsToShow = gridAdapter.getRowCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
// still zero? then use a default height and leave, which
|
|
||||||
// can happen when there are no targets to show
|
|
||||||
if (rowsToShow == 0 && !shouldShowStickyContentPreview()) {
|
|
||||||
offset += getResources().getDimensionPixelSize(
|
|
||||||
R.dimen.chooser_max_collapsed_height);
|
|
||||||
mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
View stickyContentPreview = findViewById(R.id.content_preview_container);
|
|
||||||
if (shouldShowStickyContentPreview() && isStickyContentPreviewShowing()) {
|
|
||||||
offset += stickyContentPreview.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldShowTabs()) {
|
|
||||||
offset += findViewById(R.id.tabs).getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recyclerView.getVisibility() == View.VISIBLE) {
|
|
||||||
int directShareHeight = 0;
|
|
||||||
rowsToShow = Math.min(4, rowsToShow);
|
|
||||||
boolean shouldShowExtraRow = shouldShowExtraRow(rowsToShow);
|
|
||||||
mLastNumberOfChildren = recyclerView.getChildCount();
|
|
||||||
for (int i = 0, childCount = recyclerView.getChildCount();
|
|
||||||
i < childCount && rowsToShow > 0; i++) {
|
|
||||||
View child = recyclerView.getChildAt(i);
|
|
||||||
if (((GridLayoutManager.LayoutParams)
|
|
||||||
child.getLayoutParams()).getSpanIndex() != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int height = child.getHeight();
|
|
||||||
offset += height;
|
|
||||||
if (shouldShowExtraRow) {
|
|
||||||
offset += height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gridAdapter.getTargetType(
|
|
||||||
recyclerView.getChildAdapterPosition(child))
|
|
||||||
== ChooserListAdapter.TARGET_SERVICE) {
|
|
||||||
directShareHeight = height;
|
|
||||||
}
|
|
||||||
rowsToShow--;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isExpandable = getResources().getConfiguration().orientation
|
|
||||||
== Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
|
|
||||||
if (directShareHeight != 0 && isSendAction(getTargetIntent())
|
|
||||||
&& isExpandable) {
|
|
||||||
// make sure to leave room for direct share 4->8 expansion
|
|
||||||
int requiredExpansionHeight =
|
|
||||||
(int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
|
|
||||||
int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
|
|
||||||
int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
|
|
||||||
- requiredExpansionHeight - topInset - bottomInset;
|
|
||||||
|
|
||||||
offset = Math.min(offset, minHeight);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ViewGroup currentEmptyStateView = getActiveEmptyStateView();
|
|
||||||
if (currentEmptyStateView.getVisibility() == View.VISIBLE) {
|
|
||||||
offset += currentEmptyStateView.getHeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mResolverDrawerLayout.setCollapsibleHeightReserved(Math.min(offset, bottom - top));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int calculateDrawerOffset(
|
||||||
|
int top, int bottom, RecyclerView recyclerView, ChooserGridAdapter gridAdapter) {
|
||||||
|
|
||||||
|
final int bottomInset = mSystemWindowInsets != null
|
||||||
|
? mSystemWindowInsets.bottom : 0;
|
||||||
|
int offset = bottomInset;
|
||||||
|
int rowsToShow = gridAdapter.getSystemRowCount()
|
||||||
|
+ gridAdapter.getProfileRowCount()
|
||||||
|
+ gridAdapter.getServiceTargetRowCount()
|
||||||
|
+ gridAdapter.getCallerAndRankedTargetRowCount();
|
||||||
|
|
||||||
|
// then this is most likely not a SEND_* action, so check
|
||||||
|
// the app target count
|
||||||
|
if (rowsToShow == 0) {
|
||||||
|
rowsToShow = gridAdapter.getRowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// still zero? then use a default height and leave, which
|
||||||
|
// can happen when there are no targets to show
|
||||||
|
if (rowsToShow == 0 && !shouldShowStickyContentPreview()) {
|
||||||
|
offset += getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.chooser_max_collapsed_height);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
View stickyContentPreview = findViewById(R.id.content_preview_container);
|
||||||
|
if (shouldShowStickyContentPreview() && isStickyContentPreviewShowing()) {
|
||||||
|
offset += stickyContentPreview.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldShowTabs()) {
|
||||||
|
offset += findViewById(R.id.tabs).getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recyclerView.getVisibility() == View.VISIBLE) {
|
||||||
|
int directShareHeight = 0;
|
||||||
|
rowsToShow = Math.min(4, rowsToShow);
|
||||||
|
boolean shouldShowExtraRow = shouldShowExtraRow(rowsToShow);
|
||||||
|
mLastNumberOfChildren = recyclerView.getChildCount();
|
||||||
|
for (int i = 0, childCount = recyclerView.getChildCount();
|
||||||
|
i < childCount && rowsToShow > 0; i++) {
|
||||||
|
View child = recyclerView.getChildAt(i);
|
||||||
|
if (((GridLayoutManager.LayoutParams)
|
||||||
|
child.getLayoutParams()).getSpanIndex() != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int height = child.getHeight();
|
||||||
|
offset += height;
|
||||||
|
if (shouldShowExtraRow) {
|
||||||
|
offset += height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gridAdapter.getTargetType(
|
||||||
|
recyclerView.getChildAdapterPosition(child))
|
||||||
|
== ChooserListAdapter.TARGET_SERVICE) {
|
||||||
|
directShareHeight = height;
|
||||||
|
}
|
||||||
|
rowsToShow--;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isExpandable = getResources().getConfiguration().orientation
|
||||||
|
== Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
|
||||||
|
if (directShareHeight != 0 && isSendAction(getTargetIntent())
|
||||||
|
&& isExpandable) {
|
||||||
|
// make sure to leave room for direct share 4->8 expansion
|
||||||
|
int requiredExpansionHeight =
|
||||||
|
(int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
|
||||||
|
int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
|
||||||
|
int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
|
||||||
|
- requiredExpansionHeight - topInset - bottomInset;
|
||||||
|
|
||||||
|
offset = Math.min(offset, minHeight);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ViewGroup currentEmptyStateView = getActiveEmptyStateView();
|
||||||
|
if (currentEmptyStateView.getVisibility() == View.VISIBLE) {
|
||||||
|
offset += currentEmptyStateView.getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.min(offset, bottom - top);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we have a tabbed view and are showing 1 row in the current profile and an empty
|
* If we have a tabbed view and are showing 1 row in the current profile and an empty
|
||||||
* state screen in the other profile, to prevent cropping of the empty state screen we show
|
* state screen in the other profile, to prevent cropping of the empty state screen we show
|
||||||
@@ -3930,6 +3941,51 @@ public class ChooserActivity extends ResolverActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class to track app's readiness for the scene transition animation.
|
||||||
|
* The app is ready when both the image is laid out and the drawer offset is calculated.
|
||||||
|
*/
|
||||||
|
private class EnterTransitionAnimationDelegate implements View.OnLayoutChangeListener {
|
||||||
|
private boolean mPreviewReady = false;
|
||||||
|
private boolean mOffsetCalculated = false;
|
||||||
|
|
||||||
|
void postponeTransition() {
|
||||||
|
postponeEnterTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void markImagePreviewReady() {
|
||||||
|
if (!mPreviewReady) {
|
||||||
|
mPreviewReady = true;
|
||||||
|
maybeStartListenForLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void markOffsetCalculated() {
|
||||||
|
if (!mOffsetCalculated) {
|
||||||
|
mOffsetCalculated = true;
|
||||||
|
maybeStartListenForLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeStartListenForLayout() {
|
||||||
|
if (mPreviewReady && mOffsetCalculated && mResolverDrawerLayout != null) {
|
||||||
|
if (mResolverDrawerLayout.isInLayout()) {
|
||||||
|
startPostponedEnterTransition();
|
||||||
|
} else {
|
||||||
|
mResolverDrawerLayout.addOnLayoutChangeListener(this);
|
||||||
|
mResolverDrawerLayout.requestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
|
||||||
|
int oldTop, int oldRight, int oldBottom) {
|
||||||
|
v.removeOnLayoutChangeListener(this);
|
||||||
|
startPostponedEnterTransition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void maybeLogProfileChange() {
|
protected void maybeLogProfileChange() {
|
||||||
getChooserActivityLogger().logShareheetProfileChanged();
|
getChooserActivityLogger().logShareheetProfileChanged();
|
||||||
|
|||||||
Reference in New Issue
Block a user