Add snapToGuide for complications.
snapToGuide lets the ComplicationLayoutEngine choose the proper dimension for a complication. This adjusted dimension is always the one perpendicular to the complication direction. Bug: 216369783 Test: atest ComplicationLayoutEngineTest#testSnapToGuide Change-Id: I20a501bc3ef3274d2f511e2ea5901d1865b0ec24
This commit is contained in:
@@ -20,6 +20,30 @@
|
||||
android:id="@+id/dream_overlay_complications_layer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/complication_top_guide"
|
||||
app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_top_percent"
|
||||
android:orientation="horizontal"/>
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/complication_end_guide"
|
||||
app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_end_percent"
|
||||
android:orientation="vertical"/>
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/complication_bottom_guide"
|
||||
app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_bottom_percent"
|
||||
android:orientation="horizontal"/>
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/complication_start_guide"
|
||||
app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_start_percent"
|
||||
android:orientation="vertical"/>
|
||||
<TextClock
|
||||
android:id="@+id/time_view"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -1343,4 +1343,32 @@
|
||||
<!-- Height of the area at the top of the dream overlay to allow dragging down the notifications
|
||||
shade. -->
|
||||
<dimen name="dream_overlay_notifications_drag_area_height">100dp</dimen>
|
||||
|
||||
<!-- The position of the end guide, which dream overlay complications can align their start with
|
||||
if their end is aligned with the parent end. Represented as the percentage over from the
|
||||
start of the parent container. -->
|
||||
<item name="dream_overlay_complication_guide_end_percent" format="float" type="dimen">
|
||||
0.75
|
||||
</item>
|
||||
|
||||
<!-- The position of the start guide, which dream overlay complications can align their end to
|
||||
if their start is aligned with the parent start. Represented as the percentage over from
|
||||
the start of the parent container. -->
|
||||
<item name="dream_overlay_complication_guide_start_percent" format="float" type="dimen">
|
||||
0.25
|
||||
</item>
|
||||
|
||||
<!-- The position of the bottom guide, which dream overlay complications can align their top to
|
||||
if their bottom is aligned with the parent bottom. Represented as the percentage over from
|
||||
the top of the parent container. -->
|
||||
<item name="dream_overlay_complication_guide_bottom_percent" format="float" type="dimen">
|
||||
0.90
|
||||
</item>
|
||||
|
||||
<!-- The position of the top guide, which dream overlay complications can align their bottom to
|
||||
if their top is aligned with the parent top. Represented as the percentage over from
|
||||
the top of the parent container. -->
|
||||
<item name="dream_overlay_complication_guide_top_percent" format="float" type="dimen">
|
||||
0.10
|
||||
</item>
|
||||
</resources>
|
||||
|
||||
@@ -25,10 +25,13 @@ import android.view.ViewGroup;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.Constraints;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
@@ -102,6 +105,8 @@ public class ComplicationLayoutEngine {
|
||||
|
||||
final int direction = getLayoutParams().getDirection();
|
||||
|
||||
final boolean snapsToGuide = getLayoutParams().snapsToGuide();
|
||||
|
||||
// If no parent, view is the anchor. In this case, it is given the highest priority for
|
||||
// alignment. All alignment preferences are done in relation to the parent container.
|
||||
final boolean isRoot = head == mView;
|
||||
@@ -125,6 +130,11 @@ public class ComplicationLayoutEngine {
|
||||
} else {
|
||||
params.startToEnd = head.getId();
|
||||
}
|
||||
if (snapsToGuide
|
||||
&& (direction == ComplicationLayoutParams.DIRECTION_DOWN
|
||||
|| direction == ComplicationLayoutParams.DIRECTION_UP)) {
|
||||
params.endToStart = R.id.complication_start_guide;
|
||||
}
|
||||
break;
|
||||
case ComplicationLayoutParams.POSITION_TOP:
|
||||
if (isRoot || direction != ComplicationLayoutParams.DIRECTION_DOWN) {
|
||||
@@ -132,6 +142,11 @@ public class ComplicationLayoutEngine {
|
||||
} else {
|
||||
params.topToBottom = head.getId();
|
||||
}
|
||||
if (snapsToGuide
|
||||
&& (direction == ComplicationLayoutParams.DIRECTION_END
|
||||
|| direction == ComplicationLayoutParams.DIRECTION_START)) {
|
||||
params.endToStart = R.id.complication_top_guide;
|
||||
}
|
||||
break;
|
||||
case ComplicationLayoutParams.POSITION_BOTTOM:
|
||||
if (isRoot || direction != ComplicationLayoutParams.DIRECTION_UP) {
|
||||
@@ -139,6 +154,11 @@ public class ComplicationLayoutEngine {
|
||||
} else {
|
||||
params.bottomToTop = head.getId();
|
||||
}
|
||||
if (snapsToGuide
|
||||
&& (direction == ComplicationLayoutParams.DIRECTION_END
|
||||
|| direction == ComplicationLayoutParams.DIRECTION_START)) {
|
||||
params.topToBottom = R.id.complication_bottom_guide;
|
||||
}
|
||||
break;
|
||||
case ComplicationLayoutParams.POSITION_END:
|
||||
if (isRoot || direction != ComplicationLayoutParams.DIRECTION_START) {
|
||||
@@ -146,6 +166,11 @@ public class ComplicationLayoutEngine {
|
||||
} else {
|
||||
params.endToStart = head.getId();
|
||||
}
|
||||
if (snapsToGuide
|
||||
&& (direction == ComplicationLayoutParams.DIRECTION_UP
|
||||
|| direction == ComplicationLayoutParams.DIRECTION_DOWN)) {
|
||||
params.startToEnd = R.id.complication_end_guide;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -153,6 +178,16 @@ public class ComplicationLayoutEngine {
|
||||
mView.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void setGuide(ConstraintLayout.LayoutParams lp, int validDirections,
|
||||
Consumer<ConstraintLayout.LayoutParams> consumer) {
|
||||
final ComplicationLayoutParams layoutParams = getLayoutParams();
|
||||
if (!layoutParams.snapsToGuide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
consumer.accept(lp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the {@link ViewEntry}'s parent entity to remove the {@link ViewEntry} from
|
||||
* being shown further.
|
||||
|
||||
@@ -40,13 +40,13 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
|
||||
@interface Position {}
|
||||
/** Align view with the top of parent or bottom of preceding {@link Complication}. */
|
||||
static final int POSITION_TOP = 1 << 0;
|
||||
public static final int POSITION_TOP = 1 << 0;
|
||||
/** Align view with the bottom of parent or top of preceding {@link Complication}. */
|
||||
static final int POSITION_BOTTOM = 1 << 1;
|
||||
public static final int POSITION_BOTTOM = 1 << 1;
|
||||
/** Align view with the start of parent or end of preceding {@link Complication}. */
|
||||
static final int POSITION_START = 1 << 2;
|
||||
public static final int POSITION_START = 1 << 2;
|
||||
/** Align view with the end of parent or start of preceding {@link Complication}. */
|
||||
static final int POSITION_END = 1 << 3;
|
||||
public static final int POSITION_END = 1 << 3;
|
||||
|
||||
private static final int FIRST_POSITION = POSITION_TOP;
|
||||
private static final int LAST_POSITION = POSITION_END;
|
||||
@@ -61,13 +61,13 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
|
||||
@interface Direction {}
|
||||
/** Position view upward from position. */
|
||||
static final int DIRECTION_UP = 1 << 0;
|
||||
public static final int DIRECTION_UP = 1 << 0;
|
||||
/** Position view downward from position. */
|
||||
static final int DIRECTION_DOWN = 1 << 1;
|
||||
public static final int DIRECTION_DOWN = 1 << 1;
|
||||
/** Position view towards the start of the parent. */
|
||||
static final int DIRECTION_START = 1 << 2;
|
||||
public static final int DIRECTION_START = 1 << 2;
|
||||
/** Position view towards the end of parent. */
|
||||
static final int DIRECTION_END = 1 << 3;
|
||||
public static final int DIRECTION_END = 1 << 3;
|
||||
|
||||
@Position
|
||||
private final int mPosition;
|
||||
@@ -77,6 +77,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
|
||||
private final int mWeight;
|
||||
|
||||
private final boolean mSnapToGuide;
|
||||
|
||||
// Do not allow specifying opposite positions
|
||||
private static final int[] INVALID_POSITIONS =
|
||||
{ POSITION_BOTTOM | POSITION_TOP, POSITION_END | POSITION_START };
|
||||
@@ -104,6 +106,27 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
*/
|
||||
public ComplicationLayoutParams(int width, int height, @Position int position,
|
||||
@Direction int direction, int weight) {
|
||||
this(width, height, position, direction, weight, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link ComplicationLayoutParams}.
|
||||
* @param width The width {@link android.view.View.MeasureSpec} for the view.
|
||||
* @param height The height {@link android.view.View.MeasureSpec} for the view.
|
||||
* @param position The place within the parent container where the view should be positioned.
|
||||
* @param direction The direction the view should be laid out from either the parent container
|
||||
* or preceding view.
|
||||
* @param weight The weight that should be considered for this view when compared to other
|
||||
* views. This has an impact on the placement of the view but not the rendering of
|
||||
* the view.
|
||||
* @param snapToGuide When set to {@code true}, the dimension perpendicular to the direction
|
||||
* will be automatically set to align with a predetermined guide for that
|
||||
* side. For example, if the complication is aligned to the top end and
|
||||
* direction is down, then the width of the complication will be set to span
|
||||
* from the end of the parent to the guide.
|
||||
*/
|
||||
public ComplicationLayoutParams(int width, int height, @Position int position,
|
||||
@Direction int direction, int weight, boolean snapToGuide) {
|
||||
super(width, height);
|
||||
|
||||
if (!validatePosition(position)) {
|
||||
@@ -118,6 +141,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
mDirection = direction;
|
||||
|
||||
mWeight = weight;
|
||||
|
||||
mSnapToGuide = snapToGuide;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,6 +153,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
mPosition = source.mPosition;
|
||||
mDirection = source.mDirection;
|
||||
mWeight = source.mWeight;
|
||||
mSnapToGuide = source.mSnapToGuide;
|
||||
}
|
||||
|
||||
private static boolean validateDirection(@Position int position, @Direction int direction) {
|
||||
@@ -180,7 +206,19 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set weight for the complication. The weight determines ordering a complication
|
||||
* given the same position/direction.
|
||||
*/
|
||||
public int getWeight() {
|
||||
return mWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the complication's dimension perpendicular to direction should be
|
||||
* automatically set.
|
||||
*/
|
||||
public boolean snapsToGuide() {
|
||||
return mSnapToGuide;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.view.View;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -121,6 +122,34 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the engine properly places a view within the {@link ConstraintLayout}.
|
||||
*/
|
||||
@Test
|
||||
public void testSnapToGuide() {
|
||||
final ViewInfo firstViewInfo = new ViewInfo(
|
||||
new ComplicationLayoutParams(
|
||||
100,
|
||||
100,
|
||||
ComplicationLayoutParams.POSITION_TOP
|
||||
| ComplicationLayoutParams.POSITION_END,
|
||||
ComplicationLayoutParams.DIRECTION_DOWN,
|
||||
0,
|
||||
true),
|
||||
Complication.CATEGORY_STANDARD,
|
||||
mLayout);
|
||||
|
||||
final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout);
|
||||
addComplication(engine, firstViewInfo);
|
||||
|
||||
// Ensure the view is added to the top end corner
|
||||
verifyChange(firstViewInfo, true, lp -> {
|
||||
assertThat(lp.topToTop == ConstraintLayout.LayoutParams.PARENT_ID).isTrue();
|
||||
assertThat(lp.endToEnd == ConstraintLayout.LayoutParams.PARENT_ID).isTrue();
|
||||
assertThat(lp.startToEnd == R.id.complication_end_guide).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures layout in a particular direction updates.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user