Merge "Don't trigger full relayout if DateTimeView doesn't change" into tm-dev am: 06ac74c54f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17606881

Change-Id: Ie68d1391a95dc32d57b43807665134bed139753b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Lucas Dupin
2022-04-22 15:28:10 +00:00
committed by Automerger Merge Worker
2 changed files with 61 additions and 3 deletions

View File

@@ -32,6 +32,7 @@ import android.content.res.TypedArray;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.PluralsMessageFormatter; import android.util.PluralsMessageFormatter;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
@@ -230,7 +231,7 @@ public class DateTimeView extends TextView {
// Set the text // Set the text
String text = format.format(new Date(time)); String text = format.format(new Date(time));
setText(text); maybeSetText(text);
// Schedule the next update // Schedule the next update
if (display == SHOW_TIME) { if (display == SHOW_TIME) {
@@ -258,7 +259,7 @@ public class DateTimeView extends TextView {
boolean past = (now >= mTimeMillis); boolean past = (now >= mTimeMillis);
String result; String result;
if (duration < MINUTE_IN_MILLIS) { if (duration < MINUTE_IN_MILLIS) {
setText(mNowText); maybeSetText(mNowText);
mUpdateTimeMillis = mTimeMillis + MINUTE_IN_MILLIS + 1; mUpdateTimeMillis = mTimeMillis + MINUTE_IN_MILLIS + 1;
return; return;
} else if (duration < HOUR_IN_MILLIS) { } else if (duration < HOUR_IN_MILLIS) {
@@ -308,7 +309,19 @@ public class DateTimeView extends TextView {
mUpdateTimeMillis = mTimeMillis - millisIncrease * count + 1; mUpdateTimeMillis = mTimeMillis - millisIncrease * count + 1;
} }
} }
setText(result); maybeSetText(result);
}
/**
* Sets text only if the text has actually changed. This prevents needles relayouts of this
* view when set to wrap_content.
*/
private void maybeSetText(String text) {
if (TextUtils.equals(getText(), text)) {
return;
}
setText(text);
} }
/** /**

View File

@@ -16,14 +16,20 @@
package android.widget; package android.widget;
import android.view.View;
import android.view.ViewGroup;
import androidx.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.time.Duration;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
public class DateTimeViewTest { public class DateTimeViewTest {
@@ -39,7 +45,33 @@ public class DateTimeViewTest {
dateTimeView.detachedFromWindow(); dateTimeView.detachedFromWindow();
} }
@UiThreadTest
@Test
public void noChangeInRelativeText_doesNotTriggerRelayout() {
// Week in the future is chosen because it'll result in a stable string during this test
// run. This should be improved once the class is refactored to be more testable in
// respect of clock retrieval.
final long weekInTheFuture = System.currentTimeMillis() + Duration.ofDays(7).toMillis();
final TestDateTimeView dateTimeView = new TestDateTimeView();
dateTimeView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
dateTimeView.setShowRelativeTime(true);
dateTimeView.setTime(weekInTheFuture);
// View needs to be measured to request layout, skipping this would make this test pass
// always.
dateTimeView.measure(View.MeasureSpec.makeMeasureSpec(200, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.UNSPECIFIED));
dateTimeView.reset();
// This should not change the text content and thus no relayout is expected.
dateTimeView.setTime(weekInTheFuture + 1000);
Assert.assertFalse(dateTimeView.wasLayoutRequested());
}
private static class TestDateTimeView extends DateTimeView { private static class TestDateTimeView extends DateTimeView {
private boolean mRequestedLayout = false;
TestDateTimeView() { TestDateTimeView() {
super(InstrumentationRegistry.getContext()); super(InstrumentationRegistry.getContext());
} }
@@ -51,5 +83,18 @@ public class DateTimeViewTest {
void detachedFromWindow() { void detachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
} }
public void requestLayout() {
super.requestLayout();
mRequestedLayout = true;
}
public boolean wasLayoutRequested() {
return mRequestedLayout;
}
public void reset() {
mRequestedLayout = false;
}
} }
} }