Inflate dismissal background instead of drawing while swiping
- Only swipe the foreground out to have the background revealed. - Inflate dismissal_swipe_background.xml while swiping. - Fix the fly-in transition. - Fix the overlapping problem. Bug: 129742618 Test: robotests Change-Id: I5311e50332d0ea0437d1693d075d5c3a2176a443
This commit is contained in:
46
res/layout/dismissal_swipe_background.xml
Normal file
46
res/layout/dismissal_swipe_background.xml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/dismissal_swipe_background"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/homepage_card_dismissal_background">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dismissal_icon_start"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_delete"
|
||||||
|
android:layout_gravity="start|center_vertical"
|
||||||
|
android:layout_marginStart="@dimen/homepage_card_dismissal_side_margin"/>
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dismissal_icon_end"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_delete"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
|
android:layout_marginEnd="@dimen/homepage_card_dismissal_side_margin"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@@ -21,6 +21,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/ContextualCardStyle">
|
style="@style/ContextualCardStyle">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<include layout="@layout/dismissal_swipe_background"/>
|
||||||
|
|
||||||
<ViewFlipper
|
<ViewFlipper
|
||||||
android:id="@+id/view_flipper"
|
android:id="@+id/view_flipper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -33,6 +39,7 @@
|
|||||||
android:paddingEnd="@dimen/homepage_card_padding_end"
|
android:paddingEnd="@dimen/homepage_card_padding_end"
|
||||||
android:paddingTop="@dimen/homepage_half_card_padding_top"
|
android:paddingTop="@dimen/homepage_half_card_padding_top"
|
||||||
android:paddingBottom="@dimen/homepage_half_card_padding_bottom"
|
android:paddingBottom="@dimen/homepage_half_card_padding_bottom"
|
||||||
|
android:background="@color/contextual_card_background"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@@ -58,4 +65,5 @@
|
|||||||
<include layout="@layout/homepage_dismissal_view"/>
|
<include layout="@layout/homepage_dismissal_view"/>
|
||||||
|
|
||||||
</ViewFlipper>
|
</ViewFlipper>
|
||||||
|
</FrameLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
@@ -21,11 +21,23 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/ContextualCardStyle">
|
style="@style/ContextualCardStyle">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<include layout="@layout/dismissal_swipe_background"/>
|
||||||
|
|
||||||
<ViewFlipper
|
<ViewFlipper
|
||||||
android:id="@+id/view_flipper"
|
android:id="@+id/view_flipper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/slice_view_wrapper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/contextual_card_background">
|
||||||
|
|
||||||
<androidx.slice.widget.SliceView
|
<androidx.slice.widget.SliceView
|
||||||
android:id="@+id/slice_view"
|
android:id="@+id/slice_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -33,9 +45,11 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
style="@style/SliceViewStyle"/>
|
style="@style/SliceViewStyle"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<!--dismissal view-->
|
<!--dismissal view-->
|
||||||
<include layout="@layout/homepage_dismissal_view"/>
|
<include layout="@layout/homepage_dismissal_view"/>
|
||||||
|
|
||||||
</ViewFlipper>
|
</ViewFlipper>
|
||||||
|
</FrameLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
@@ -492,6 +492,7 @@
|
|||||||
<item name="android:paddingEnd">8dp</item>
|
<item name="android:paddingEnd">8dp</item>
|
||||||
|
|
||||||
<item name="rowStyle">@style/SliceRowStyle</item>
|
<item name="rowStyle">@style/SliceRowStyle</item>
|
||||||
|
<item name="android:background">@color/contextual_card_background</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="SliceRowStyle">
|
<style name="SliceRowStyle">
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.homepage.contextualcards.slices;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.slice.Slice;
|
import androidx.slice.Slice;
|
||||||
@@ -70,10 +71,12 @@ class SliceFullCardRendererHelper {
|
|||||||
|
|
||||||
static class SliceViewHolder extends RecyclerView.ViewHolder {
|
static class SliceViewHolder extends RecyclerView.ViewHolder {
|
||||||
public final SliceView sliceView;
|
public final SliceView sliceView;
|
||||||
|
public final LinearLayout sliceViewWrapper;
|
||||||
|
|
||||||
public SliceViewHolder(View view) {
|
public SliceViewHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
sliceView = view.findViewById(R.id.slice_view);
|
sliceView = view.findViewById(R.id.slice_view);
|
||||||
|
sliceViewWrapper = view.findViewById(R.id.slice_view_wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,6 @@ package com.android.settings.homepage.contextualcards.slices;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ViewFlipper;
|
import android.widget.ViewFlipper;
|
||||||
|
|
||||||
@@ -41,18 +38,10 @@ public class SwipeDismissalDelegate extends ItemTouchHelper.Callback {
|
|||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final SwipeDismissalDelegate.Listener mListener;
|
private final SwipeDismissalDelegate.Listener mListener;
|
||||||
private final Drawable mIconDelete;
|
|
||||||
private final Paint mBgPaint;
|
|
||||||
private final int mBgCornerRadius;
|
|
||||||
|
|
||||||
public SwipeDismissalDelegate(Context context, SwipeDismissalDelegate.Listener listener) {
|
public SwipeDismissalDelegate(Context context, SwipeDismissalDelegate.Listener listener) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mIconDelete = mContext.getDrawable(R.drawable.ic_delete);
|
|
||||||
mBgPaint = new Paint();
|
|
||||||
mBgPaint.setColor(mContext.getColor(R.color.homepage_card_dismissal_background));
|
|
||||||
mBgCornerRadius = mContext.getResources()
|
|
||||||
.getDimensionPixelSize(R.dimen.homepage_card_corner_radius);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,41 +89,49 @@ public class SwipeDismissalDelegate extends ItemTouchHelper.Callback {
|
|||||||
mListener.onSwiped(viewHolder.getAdapterPosition());
|
mListener.onSwiped(viewHolder.getAdapterPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearView(@NonNull RecyclerView recyclerView,
|
||||||
|
@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||||
|
final View view = getSwipeableView(viewHolder);
|
||||||
|
getDefaultUIUtil().clearView(view);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,
|
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,
|
||||||
@NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
|
@NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
|
||||||
boolean isCurrentlyActive) {
|
boolean isCurrentlyActive) {
|
||||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
final View view = getSwipeableView(viewHolder);
|
||||||
|
final View iconStart = viewHolder.itemView.findViewById(R.id.dismissal_icon_start);
|
||||||
|
final View iconEnd = viewHolder.itemView.findViewById(R.id.dismissal_icon_end);
|
||||||
|
|
||||||
final View itemView = viewHolder.itemView;
|
if (dX > 0) {
|
||||||
final int iconMargin = mContext.getResources()
|
iconStart.setVisibility(View.VISIBLE);
|
||||||
.getDimensionPixelSize(R.dimen.homepage_card_dismissal_side_margin);
|
iconEnd.setVisibility(View.GONE);
|
||||||
final int iconTop =
|
|
||||||
itemView.getTop() + (itemView.getHeight() - mIconDelete.getIntrinsicHeight()) / 2;
|
|
||||||
final int iconBottom = iconTop + mIconDelete.getIntrinsicHeight();
|
|
||||||
|
|
||||||
if (dX > 0) { //swipe to the right
|
|
||||||
final int iconLeft = itemView.getLeft() + iconMargin;
|
|
||||||
final int iconRight = iconLeft + mIconDelete.getIntrinsicWidth();
|
|
||||||
final RectF rect = new RectF(itemView.getLeft(), itemView.getTop(),
|
|
||||||
itemView.getLeft() + ((int) dX) + mBgCornerRadius, itemView.getBottom());
|
|
||||||
mIconDelete.setBounds(iconLeft, iconTop, iconRight, iconBottom);
|
|
||||||
c.drawRoundRect(rect, mBgCornerRadius, mBgCornerRadius, mBgPaint);
|
|
||||||
} else if (dX < 0) {
|
} else if (dX < 0) {
|
||||||
final int iconRight = itemView.getRight() - iconMargin;
|
iconStart.setVisibility(View.GONE);
|
||||||
final int iconLeft = iconRight - mIconDelete.getIntrinsicWidth();
|
iconEnd.setVisibility(View.VISIBLE);
|
||||||
final RectF rect = new RectF(itemView.getRight() + ((int) dX), itemView.getTop(),
|
|
||||||
itemView.getRight(), itemView.getBottom());
|
|
||||||
mIconDelete.setBounds(iconLeft, iconTop, iconRight, iconBottom);
|
|
||||||
c.drawRoundRect(rect, mBgCornerRadius, mBgCornerRadius, mBgPaint);
|
|
||||||
}
|
}
|
||||||
mIconDelete.draw(c);
|
getDefaultUIUtil().onDraw(c, recyclerView, view, dX, dY, actionState, isCurrentlyActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getInitialViewId(RecyclerView.ViewHolder viewHolder) {
|
private int getInitialViewId(RecyclerView.ViewHolder viewHolder) {
|
||||||
if (viewHolder.getItemViewType() == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
|
if (viewHolder.getItemViewType() == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
|
||||||
return R.id.content;
|
return R.id.content;
|
||||||
}
|
}
|
||||||
return R.id.slice_view;
|
return R.id.slice_view_wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the foreground view from the {@link android.widget.FrameLayout} as we only swipe
|
||||||
|
* the foreground out in {@link SwipeDismissalDelegate#onChildDraw} and gets the view
|
||||||
|
* beneath revealed.
|
||||||
|
*
|
||||||
|
* @return The foreground view.
|
||||||
|
*/
|
||||||
|
private View getSwipeableView(RecyclerView.ViewHolder viewHolder) {
|
||||||
|
if (viewHolder.getItemViewType() == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
|
||||||
|
return ((SliceHalfCardRendererHelper.HalfCardViewHolder) viewHolder).content;
|
||||||
|
}
|
||||||
|
return ((SliceFullCardRendererHelper.SliceViewHolder) viewHolder).sliceViewWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -149,7 +149,7 @@ public class SliceContextualCardRendererTest {
|
|||||||
|
|
||||||
btnKeep.performClick();
|
btnKeep.performClick();
|
||||||
|
|
||||||
assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
|
assertThat(viewFlipper.getCurrentView().getId()).isEqualTo(R.id.slice_view_wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -204,7 +204,7 @@ public class SliceContextualCardRendererTest {
|
|||||||
|
|
||||||
mRenderer.onStop();
|
mRenderer.onStop();
|
||||||
|
|
||||||
assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class);
|
assertThat(viewFlipper.getCurrentView().getId()).isEqualTo(R.id.slice_view_wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecyclerView.ViewHolder getSliceViewHolder() {
|
private RecyclerView.ViewHolder getSliceViewHolder() {
|
||||||
|
@@ -99,9 +99,9 @@ public class SwipeDismissalDelegateTest {
|
|||||||
final RecyclerView.ViewHolder holder = getSliceViewHolder();
|
final RecyclerView.ViewHolder holder = getSliceViewHolder();
|
||||||
final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
|
final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
|
||||||
viewFlipper.setDisplayedChild(0);
|
viewFlipper.setDisplayedChild(0);
|
||||||
final View sliceView = holder.itemView.findViewById(R.id.slice_view);
|
final View sliceViewWrapper = holder.itemView.findViewById(R.id.slice_view_wrapper);
|
||||||
|
|
||||||
assertThat(viewFlipper.getCurrentView()).isEqualTo(sliceView);
|
assertThat(viewFlipper.getCurrentView()).isEqualTo(sliceViewWrapper);
|
||||||
assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getSliceViewHolder()))
|
assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getSliceViewHolder()))
|
||||||
.isNotEqualTo(0);
|
.isNotEqualTo(0);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user