diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index e828e2898e6..4211a1acc35 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,5 +1,8 @@
+
+
+
@@ -10,7 +13,10 @@
+
+
+
@@ -34,6 +40,7 @@
+
@@ -46,7 +53,6 @@
xmlns:android
-
^$
@@ -57,7 +63,6 @@
xmlns:.*
-
^$
@@ -69,7 +74,6 @@
.*:id
-
http://schemas.android.com/apk/res/android
@@ -80,7 +84,6 @@
.*:name
-
http://schemas.android.com/apk/res/android
@@ -91,7 +94,6 @@
name
-
^$
@@ -102,7 +104,6 @@
style
-
^$
@@ -113,7 +114,6 @@
.*
-
^$
@@ -125,7 +125,6 @@
.*
-
http://schemas.android.com/apk/res/android
@@ -137,7 +136,6 @@
.*
-
.*
@@ -159,4 +157,4 @@
-
\ No newline at end of file
+
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
index 80e519c3aa2..78ea4beff08 100644
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8b199f77525..f321884c914 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,8 @@
-
+ package="org.oppia.app">
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+ android:theme="@style/SplashScreenTheme">
+
diff --git a/app/src/main/java/org/oppia/app/activity/InputInteractionViewTestActivity.kt b/app/src/main/java/org/oppia/app/activity/InputInteractionViewTestActivity.kt
new file mode 100644
index 00000000000..a46f7b01a08
--- /dev/null
+++ b/app/src/main/java/org/oppia/app/activity/InputInteractionViewTestActivity.kt
@@ -0,0 +1,17 @@
+package org.oppia.app.activity
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import org.oppia.app.R
+import org.oppia.app.customview.interaction.NumericInputInteractionView
+
+/**
+ * This is a dummy activity to test input interaction views.
+ * It contains [NumericInputInteractionView] .
+ */
+class InputInteractionViewTestActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_numeric_input_interaction_view_test)
+ }
+}
diff --git a/app/src/main/java/org/oppia/app/customview/interaction/InteractionAnswerRetriever.kt b/app/src/main/java/org/oppia/app/customview/interaction/InteractionAnswerRetriever.kt
new file mode 100644
index 00000000000..5d41b7e5833
--- /dev/null
+++ b/app/src/main/java/org/oppia/app/customview/interaction/InteractionAnswerRetriever.kt
@@ -0,0 +1,8 @@
+package org.oppia.app.customview.interaction
+
+import org.oppia.app.model.InteractionObject
+
+/** This interface helps to get answer from input interaction views as [InteractionObject]. */
+interface InteractionAnswerRetriever {
+ fun getPendingAnswer(): InteractionObject
+}
diff --git a/app/src/main/java/org/oppia/app/customview/interaction/NumericInputInteractionView.kt b/app/src/main/java/org/oppia/app/customview/interaction/NumericInputInteractionView.kt
new file mode 100644
index 00000000000..ebad8a5c729
--- /dev/null
+++ b/app/src/main/java/org/oppia/app/customview/interaction/NumericInputInteractionView.kt
@@ -0,0 +1,29 @@
+package org.oppia.app.customview.interaction
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.EditText
+import org.oppia.app.model.InteractionObject
+
+// TODO(#249): These are the attributes which should be defined in XML, that are required for this interaction view to work correctly
+// digits="0123456789."
+// hint="Write the digit here."
+// inputType="numberDecimal"
+// background="@drawable/edit_text_background"
+// maxLength="200".
+
+/** The custom EditText class for numeric input interaction view. */
+class NumericInputInteractionView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyle: Int = android.R.attr.editTextStyle
+) : EditText(context, attrs, defStyle), InteractionAnswerRetriever {
+
+ override fun getPendingAnswer(): InteractionObject {
+ val interactionObjectBuilder = InteractionObject.newBuilder()
+ if (!text.isNullOrEmpty()) {
+ interactionObjectBuilder.setReal(text.toString().toDouble())
+ }
+ return interactionObjectBuilder.build()
+ }
+}
diff --git a/app/src/main/res/layout/activity_numeric_input_interaction_view_test.xml b/app/src/main/res/layout/activity_numeric_input_interaction_view_test.xml
new file mode 100644
index 00000000000..c53db5bff2c
--- /dev/null
+++ b/app/src/main/res/layout/activity_numeric_input_interaction_view_test.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 35f1efabe12..c96810de821 100755
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -7,5 +7,4 @@
32dp
24dp
4dp
- 8dp
diff --git a/app/src/sharedTest/java/org/oppia/app/activity/InputInteractionViewTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/app/activity/InputInteractionViewTestActivityTest.kt
new file mode 100644
index 00000000000..477d5a702fc
--- /dev/null
+++ b/app/src/sharedTest/java/org/oppia/app/activity/InputInteractionViewTestActivityTest.kt
@@ -0,0 +1,92 @@
+package org.oppia.app.activity
+
+import android.app.Activity
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.res.Configuration
+import android.os.SystemClock
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.rule.ActivityTestRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.app.R
+import org.oppia.app.model.InteractionObject
+import androidx.test.core.app.ActivityScenario
+import androidx.test.espresso.action.ViewActions
+import androidx.test.espresso.action.ViewActions.typeText
+import androidx.test.espresso.assertion.ViewAssertions
+import androidx.test.espresso.intent.Intents
+import androidx.test.espresso.matcher.ViewMatchers
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.oppia.app.customview.interaction.NumericInputInteractionView
+
+/** Tests for [InputInteractionViewTestActivity]. */
+@RunWith(AndroidJUnit4::class)
+class InputInteractionViewTestActivityTest {
+ @get:Rule
+ var activityTestRule: ActivityTestRule = ActivityTestRule(
+ InputInteractionViewTestActivity::class.java, /* initialTouchMode= */ true, /* launchActivity= */ false
+ )
+ private lateinit var activityScenario: ActivityScenario
+
+ @Before
+ fun setUp() {
+ activityScenario = ActivityScenario.launch(InputInteractionViewTestActivity::class.java)
+ Intents.init()
+ }
+
+ @Test
+ fun testNumericInputInteractionView_withNoInputText_hasCorrectPendingAnswerType() {
+ activityScenario.onActivity { activity ->
+ val textAnswerRetriever =
+ activity.findViewById(R.id.test_number_input_interaction_view) as NumericInputInteractionView
+ assertThat(textAnswerRetriever.getPendingAnswer()).isInstanceOf(InteractionObject::class.java)
+ assertThat(textAnswerRetriever.getPendingAnswer().real).isWithin(1e-5).of(0.0)
+ }
+ }
+
+ @Test
+ fun testNumericInputInteractionView_withInputtedText_hasCorrectPendingAnswer() {
+ onView(withId(R.id.test_number_input_interaction_view)).perform(typeText("9"))
+ activityScenario.onActivity { activity ->
+ val textAnswerRetriever =
+ activity.findViewById(R.id.test_number_input_interaction_view) as NumericInputInteractionView
+ assertThat(textAnswerRetriever.getPendingAnswer()).isInstanceOf(InteractionObject::class.java)
+ assertThat(textAnswerRetriever.getPendingAnswer().objectTypeCase).isEqualTo(InteractionObject.ObjectTypeCase.REAL)
+ assertThat(textAnswerRetriever.getPendingAnswer().real).isEqualTo(9.0)
+ }
+ }
+
+ @Test
+ fun testNumericInputInteractionView_withInputtedText_hasCorrectPendingAnswerWithDecimalValues() {
+ onView(withId(R.id.test_number_input_interaction_view)).perform(typeText("9.5"))
+ activityScenario.onActivity { activity ->
+ val textAnswerRetriever =
+ activity.findViewById(R.id.test_number_input_interaction_view) as NumericInputInteractionView
+ assertThat(textAnswerRetriever.getPendingAnswer().objectTypeCase).isEqualTo(InteractionObject.ObjectTypeCase.REAL)
+ assertThat(textAnswerRetriever.getPendingAnswer().real).isEqualTo(9.5)
+ }
+ }
+
+ @Test
+ fun testTextInputInteractionView_withInputtedText_onConfigurationChange_hasCorrectPendingAnswer() {
+ onView(withId(R.id.test_number_input_interaction_view)).perform(typeText("9"))
+ activityScenario.onActivity { activity ->
+ activity.requestedOrientation = Configuration.ORIENTATION_LANDSCAPE
+ }
+ onView(withId(R.id.test_number_input_interaction_view)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
+ .check(
+ ViewAssertions.matches(ViewMatchers.withText("9"))
+ )
+ activityScenario.recreate()
+ onView(withId(R.id.test_number_input_interaction_view)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
+ .check(
+ ViewAssertions.matches(ViewMatchers.withText("9"))
+ )
+ }
+}