Made TextDelegate.getText public and updates its docs (#1792)

Fixes #1774
diff --git a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java
index f352c0a..1ae5a6c 100644
--- a/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java
+++ b/lottie/src/main/java/com/airbnb/lottie/TextDelegate.java
@@ -1,16 +1,18 @@
 package com.airbnb.lottie;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
 import androidx.annotation.VisibleForTesting;
 
 import java.util.HashMap;
 import java.util.Map;
 
 /**
- * Extend this class to replace animation text with custom text. This can be useful to handle
- * translations.
+ * To replace static text in an animation at runtime, create an instance of this class and call {@link #setText(String, String)} to
+ * replace the hard coded animation text (input) with the text of your choosing (output).
  * <p>
- * The only method you should have to override is {@link #getText(String)}.
+ * Alternatively, extend this class and override {@link #getText(String)} and if the text hasn't already been set
+ * by {@link #setText(String, String)} then it will call {@link #getText(String)}.
  */
 public class TextDelegate {
 
@@ -43,7 +45,7 @@
    * Override this to replace the animation text with something dynamic. This can be used for
    * translations or custom data.
    */
-  private String getText(String input) {
+  public String getText(String input) {
     return input;
   }
 
@@ -72,13 +74,14 @@
   }
 
   /**
-   * Invalidates all cached strings
+   * Invalidates all cached strings.
    */
   public void invalidateAllText() {
     stringMap.clear();
     invalidate();
   }
 
+  @RestrictTo(RestrictTo.Scope.LIBRARY)
   public final String getTextInternal(String input) {
     if (cacheText && stringMap.containsKey(input)) {
       return stringMap.get(input);
diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/FragmentVisibilityTests.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/FragmentVisibilityTests.kt
index fc338b9..eb4f270 100644
--- a/sample/src/androidTest/java/com/airbnb/lottie/samples/FragmentVisibilityTests.kt
+++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/FragmentVisibilityTests.kt
@@ -168,7 +168,7 @@
     @Test
     fun testRecyclerViewCanAutoPlayInOnBind() {
         class TestFragment : Fragment() {
-            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
                 return RecyclerView(requireContext()).apply {
                     layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
                     adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@@ -300,7 +300,7 @@
         class TestFragment : Fragment() {
             var animationView: LottieAnimationView? = null
 
-            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
                 return RecyclerView(requireContext()).apply {
                     layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
                     adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@@ -361,7 +361,7 @@
 
         class TestFragment : Fragment() {
             var animationView: LottieAnimationView? = null
-            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+            override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
                 return RecyclerView(requireContext()).apply {
                     layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
                     adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@@ -451,7 +451,7 @@
         onView(withId(R.id.animation_view)).check(matches(isAnimating()))
     }
 
-    private fun FragmentScenario<*>.waitForState(desiredState: Lifecycle.State) {
+    private fun <T : Fragment> FragmentScenario<T>.waitForState(desiredState: Lifecycle.State) {
         var isState = false
         while (!isState) {
             onFragment { fragment ->
diff --git a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
index 1fd3424..9d1b1b3 100644
--- a/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
+++ b/sample/src/androidTest/java/com/airbnb/lottie/samples/LottieTest.kt
@@ -860,6 +860,18 @@
             textDelegate.setText("NAME", "Hello World")
         }
 
+        withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Hello World with getText") { animationView ->
+            val textDelegate = object : TextDelegate(animationView) {
+                override fun getText(input: String): String {
+                    return when (input) {
+                        "NAME" -> "Hello World"
+                        else -> input
+                    }
+                }
+            }
+            animationView.setTextDelegate(textDelegate)
+        }
+
         withAnimationView("Tests/DynamicText.json", "Dynamic Text", "Emoji") { animationView ->
             val textDelegate = TextDelegate(animationView)
             animationView.setTextDelegate(textDelegate)