diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2475e2cf3dd80..d04b07c13b415 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9922,7 +9922,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* - It should only be called when content capture is enabled for the view.
*
- It must call viewAppeared() before viewDisappeared()
- *
- viewAppearead() can only be called when the view is visible and laidout
+ *
- viewAppeared() can only be called when the view is visible and laid out
*
- It should not call the same event twice.
*
*/
@@ -9999,6 +9999,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
Log.v(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on disappeared for " + this);
}
}
+
+ // We reset any translation state as views may be re-used (e.g., as in ListView and
+ // RecyclerView). We only need to do this for views important for content capture since
+ // views unimportant for content capture won't be translated anyway.
+ clearTranslationState();
}
}
@@ -12718,6 +12723,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
== PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE;
}
+ /**
+ * @hide
+ */
+ public void clearTranslationState() {
+ if (mViewTranslationCallback != null) {
+ mViewTranslationCallback.onClearTranslation(this);
+ }
+ clearViewTranslationCallback();
+ clearViewTranslationResponse();
+ if (hasTranslationTransientState()) {
+ setHasTransientState(false);
+ setHasTranslationTransientState(false);
+ }
+ }
+
/**
* Returns true if this view is currently attached to a window.
*/
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index 8cf032bc03cb0..6bf2474beb173 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -158,12 +158,7 @@ public class UiTranslationController implements Dumpable {
case STATE_UI_TRANSLATION_FINISHED:
destroyTranslators();
runForEachView((view, callback) -> {
- callback.onClearTranslation(view);
- view.clearViewTranslationResponse();
- if (view.hasTranslationTransientState()) {
- view.setHasTransientState(false);
- view.setHasTranslationTransientState(false);
- }
+ view.clearTranslationState();
});
notifyTranslationFinished(/* activityDestroyed= */ false);
synchronized (mLock) {