AbsSeekBar: Fix growRect computation
Fixes an issue with the growRectTo computation where if the difference between the current and target size wasn't an even number, the resulting rect would not actually have the correct size. Also, asserts using the thumb bounds, rather than the view bounds in case the thumb is not perfectly centered within the view due to rounding errors on odd densities. Fixes: 173872859 Test: atest AbsSeekBarTest Change-Id: Ib2b81a91ba8feeb6743a4e4a588d6116d231eb8d
This commit is contained in:
@@ -39,6 +39,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.inspector.InspectableProperty;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -776,17 +777,23 @@ public abstract class AbsSeekBar extends ProgressBar {
|
||||
|
||||
/**
|
||||
* Grows {@code r} from its center such that each dimension is at least {@code minimumSize}.
|
||||
*
|
||||
* The result will still have the same {@link Rect#centerX()} and {@link Rect#centerY()} as the
|
||||
* input.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
private void growRectTo(Rect r, int minimumSize) {
|
||||
int dy = (minimumSize - r.height()) / 2;
|
||||
@VisibleForTesting
|
||||
public void growRectTo(Rect r, int minimumSize) {
|
||||
int dy = minimumSize - r.height();
|
||||
if (dy > 0) {
|
||||
r.top -= dy;
|
||||
r.bottom += dy;
|
||||
r.top -= (dy + 1) / 2;
|
||||
r.bottom += dy / 2;
|
||||
}
|
||||
int dx = (minimumSize - r.width()) / 2;
|
||||
int dx = minimumSize - r.width();
|
||||
if (dx > 0) {
|
||||
r.left -= dx;
|
||||
r.right += dx;
|
||||
r.left -= (dx + 1) / 2;
|
||||
r.right += dx / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.graphics.Rect;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.RectShape;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
@@ -48,6 +47,7 @@ import java.util.List;
|
||||
@Presubmit
|
||||
public class AbsSeekBarTest {
|
||||
|
||||
public static final int PADDING = 10;
|
||||
private Context mContext;
|
||||
private AbsSeekBar mBar;
|
||||
|
||||
@@ -59,34 +59,42 @@ public class AbsSeekBarTest {
|
||||
|
||||
@Test
|
||||
public void testExclusionForThumb_limitedTo48dp() {
|
||||
mBar.setPadding(10, 10, 10, 10);
|
||||
mBar.setPadding(PADDING, PADDING, PADDING, PADDING);
|
||||
mBar.setThumb(newThumb(dpToPxSize(20)));
|
||||
mBar.setMin(0);
|
||||
mBar.setMax(100);
|
||||
mBar.setProgress(50);
|
||||
|
||||
final int thumbOffset = mBar.getThumbOffset();
|
||||
|
||||
measureAndLayout(dpToPxSize(200), dpToPxSize(100));
|
||||
List<Rect> exclusions = mBar.getSystemGestureExclusionRects();
|
||||
|
||||
assertEquals("exclusions should be size 1, but was " + exclusions, 1, exclusions.size());
|
||||
assertEquals("exclusion should be centered on thumb",
|
||||
center(mBar), center(exclusions.get(0)));
|
||||
center(offset(mBar.getThumb().getBounds(), PADDING - thumbOffset, PADDING)),
|
||||
center(exclusions.get(0)));
|
||||
assertEquals("exclusion should be 48dp high", dpToPxSize(48), exclusions.get(0).height());
|
||||
assertEquals("exclusion should be 48dp wide", dpToPxSize(48), exclusions.get(0).width());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExclusionForThumb_limitedToHeight() {
|
||||
mBar.setPadding(10, 10, 10, 10);
|
||||
mBar.setPadding(PADDING, PADDING, PADDING, PADDING);
|
||||
mBar.setThumb(newThumb(dpToPxSize(20)));
|
||||
mBar.setMin(0);
|
||||
mBar.setMax(100);
|
||||
mBar.setProgress(50);
|
||||
|
||||
final int thumbOffset = mBar.getThumbOffset();
|
||||
|
||||
measureAndLayout(dpToPxSize(200), dpToPxSize(32));
|
||||
List<Rect> exclusions = mBar.getSystemGestureExclusionRects();
|
||||
|
||||
assertEquals("exclusions should be size 1, but was " + exclusions, 1, exclusions.size());
|
||||
assertEquals("exclusion should be centered on thumb",
|
||||
center(mBar), center(exclusions.get(0)));
|
||||
center(offset(mBar.getThumb().getBounds(), PADDING - thumbOffset, PADDING)),
|
||||
center(exclusions.get(0)));
|
||||
assertEquals("exclusion should be 32dp high", dpToPxSize(32), exclusions.get(0).height());
|
||||
assertEquals("exclusion should be 32dp wide", dpToPxSize(32), exclusions.get(0).width());
|
||||
}
|
||||
@@ -95,7 +103,7 @@ public class AbsSeekBarTest {
|
||||
public void testExclusionForThumb_passesThroughUserExclusions() {
|
||||
mBar.setSystemGestureExclusionRects(Arrays.asList(new Rect(1, 2, 3, 4)));
|
||||
|
||||
mBar.setPadding(10, 10, 10, 10);
|
||||
mBar.setPadding(PADDING, PADDING, PADDING, PADDING);
|
||||
mBar.setThumb(newThumb(dpToPxSize(20)));
|
||||
mBar.setMin(0);
|
||||
mBar.setMax(100);
|
||||
@@ -110,12 +118,37 @@ public class AbsSeekBarTest {
|
||||
assertThat(mBar.getSystemGestureExclusionRects(), hasSize(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrowRectTo_evenInitialDifference() {
|
||||
doGrowRectTest(new Rect(0, 0, 0, 0), 10, new Rect(-5, -5, 5, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrowRectTo_unevenInitialDifference() {
|
||||
doGrowRectTest(new Rect(0, 0, 1, 1), 10, new Rect(-5, -5, 5, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrowRectTo_unevenInitialDifference_unevenSize() {
|
||||
doGrowRectTest(new Rect(0, 0, 0, 0), 9, new Rect(-5, -5, 4, 4));
|
||||
}
|
||||
|
||||
public void doGrowRectTest(Rect in, int minimumSize, Rect expected) {
|
||||
Rect result = new Rect(in);
|
||||
mBar.growRectTo(result, minimumSize);
|
||||
|
||||
assertEquals("grown rect", expected, result);
|
||||
assertEquals("grown rect center point", center(expected), center(result));
|
||||
}
|
||||
|
||||
private Point center(Rect rect) {
|
||||
return new Point(rect.centerX(), rect.centerY());
|
||||
}
|
||||
|
||||
private Point center(View view) {
|
||||
return center(new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
|
||||
private Rect offset(Rect rect, int dx, int dy) {
|
||||
Rect result = new Rect(rect);
|
||||
result.offset(dx, dy);
|
||||
return result;
|
||||
}
|
||||
|
||||
private ShapeDrawable newThumb(int size) {
|
||||
|
||||
Reference in New Issue
Block a user