Browse Source

Experience Registration Activity got a makeover, as well as other minor changes/refactoring

Víctor Hernández 3 years ago
parent
commit
24c10cd946

+ 45
- 51
app/src/main/java/uprrp/tania/SendActivateExperienceToServer.java View File

@@ -1,12 +1,5 @@
1
-/*************************************************************
2
- * By: Coralys Cubero Rivera
3
- * Date: 2019
4
- *************************************************************/
5
-
6 1
 package uprrp.tania;
7 2
 
8
-import android.content.Context;
9
-import android.content.Intent;
10 3
 import android.os.AsyncTask;
11 4
 import android.util.Log;
12 5
 
@@ -15,87 +8,88 @@ import java.io.InputStreamReader;
15 8
 import java.io.OutputStreamWriter;
16 9
 import java.io.UnsupportedEncodingException;
17 10
 import java.net.URL;
18
-import java.net.URLConnection;
19 11
 import java.net.URLEncoder;
20 12
 
21
-import uprrp.tania.activities.MainActivity;
13
+import javax.net.ssl.HttpsURLConnection;
22 14
 
23
-public class SendActivateExperienceToServer extends AsyncTask <String, String, String> {
15
+public class SendActivateExperienceToServer extends AsyncTask<String, String, String> {
24 16
 
25
-    private Context context;
17
+    private final String TAG = "SendActivateExperience";
18
+    private final URLEventListener myCallBack;
19
+    private URLEventListener myCallback;
26 20
 
27
-    public SendActivateExperienceToServer(Context context){
28
-        this.context = context.getApplicationContext();
21
+    public SendActivateExperienceToServer(URLEventListener callback) {
22
+        this.myCallBack = callback;
29 23
     }
30 24
 
31 25
     @Override
32 26
     protected String doInBackground(String... strings) {
33
-        String jsonActivateExperience  = "";
34 27
 
35
-        try {
36
-            jsonActivateExperience = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(strings[0], "UTF-8");
28
+        String experienceRegistrationJSON = strings[0]; // array will only ever contain a single element
29
+        String jsonActivateExperience = "";
37 30
 
31
+        // Encode data
32
+        try {
33
+            jsonActivateExperience = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(experienceRegistrationJSON, "UTF-8");
38 34
         } catch (UnsupportedEncodingException e) {
35
+            Log.e(TAG, "Couldn't encode the following JSON: " + experienceRegistrationJSON);
39 36
             e.printStackTrace();
37
+            return null;
40 38
         }
41 39
 
42
-        String serverReply = "";
43
-        BufferedReader serverReader;
44
-
45 40
         // Send data
46
-        try
47
-        {
48
-            // Defined URL  where to send data
49
-            URL url = new URL("https://tania.uprrp.edu/inscripcionExperiencia.php");
41
+        try {
50 42
 
51 43
             // Send POST data request
52
-            URLConnection conn = url.openConnection();
44
+            URL url = new URL("https://tania.uprrp.edu/inscripcionExperiencia.php"); // TODO: extract URL into @string/activateExperienceURL
45
+            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
53 46
             conn.setDoOutput(true);
54 47
             OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
55 48
             wr.write(jsonActivateExperience);
56 49
             wr.flush();
57 50
 
58 51
             // Get the server response
59
-            serverReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
52
+            BufferedReader serverReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
60 53
             StringBuilder serverResponse = new StringBuilder();
61
-            String serverResponseLine;
62 54
 
63
-            // Read Server Response
64
-            while((serverResponseLine = serverReader.readLine()) != null)
65
-            {
66
-                // Append server response in string
67
-                serverResponse.append(serverResponseLine);
55
+            String line = "";
56
+            while(line != null) {
57
+                serverResponse.append(line);
58
+                line = serverReader.readLine();
68 59
             }
69 60
 
70
-            serverReply = serverResponse.toString();
71
-        }
72
-        catch(Exception ex) {
73
-            Log.e("ERROR ACTIVATING EXPERIENCE FOR THE USER", ex.getMessage());
61
+            String response = serverResponse.toString();
62
+            if(response.startsWith("Success")) {
63
+                return response;
64
+            } else {
65
+                return null;
66
+            }
67
+
68
+
69
+        } catch(Exception e) {
70
+            Log.e("Couldn't communicate with server while activating experience!", e.getMessage());
74 71
         }
75 72
 
76
-        return serverReply;
73
+        return null;
74
+
77 75
     }
78 76
 
79 77
     @Override
80
-    protected void onPostExecute(String s) {
81
-        Log.d("ACTIVATE EXPERIENCE RESPOND", "The server's response is: " + s);
82
-
83
-        String ss = s.substring(0,6);
84
-        String se = s.substring(0,7);
85
-        if (ss.equals("Succes")){
86
-
87
-            try {
88
-                Intent intent = new Intent(context, MainActivity.class);
89
-                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
90
-                context.startActivity(intent);
91
-            }
92
-            catch (Exception e){
93
-                Log.d("ACTIVATE EXP TO MAIN", e.getMessage());
94
-            }
78
+    protected void onPostExecute(String response) {
95 79
 
80
+        if(this.myCallBack == null) {
81
+            this.myCallBack.onFailure(new Exception("Callback wasn't initialized first!"));
82
+            return;
83
+        }
96 84
 
85
+        if(response == null) {
86
+            this.myCallback.onFailure(new Exception("Error occurred during transaction!"));
87
+            return;
97 88
         }
98 89
 
90
+        Log.d("ACTIVATE EXPERIENCE RESPONSE", "The server's response is: " + response);
91
+        this.myCallBack.onSuccess();
92
+
99 93
     }
100 94
 
101 95
 }

+ 1
- 0
app/src/main/java/uprrp/tania/URLEventListener.java View File

@@ -4,6 +4,7 @@ import uprrp.tania.models.AssessmentModel;
4 4
 import uprrp.tania.models.UserStatusModel;
5 5
 
6 6
 public class URLEventListener {
7
+    public void onSuccess() {};
7 8
     public void onSuccess(AssessmentModel assessment) {};
8 9
     public void onSuccess(UserStatusModel userStatus) {};
9 10
     public void onFailure(Exception e) {};

+ 102
- 39
app/src/main/java/uprrp/tania/activities/ExperienceRegistrationActivity.java View File

@@ -1,13 +1,11 @@
1
-/*************************************************************
2
- * By: Coralys Cubero Rivera
3
- * Date: 2019
4
- *************************************************************/
5
-
6 1
 package uprrp.tania.activities;
7 2
 
3
+import android.app.ProgressDialog;
4
+import android.content.Context;
8 5
 import android.content.Intent;
9 6
 import android.net.Uri;
10 7
 import android.os.Bundle;
8
+import android.os.Handler;
11 9
 import android.util.Log;
12 10
 import android.view.View;
13 11
 import android.widget.Button;
@@ -20,62 +18,127 @@ import com.google.android.gms.tasks.OnSuccessListener;
20 18
 import com.google.firebase.iid.FirebaseInstanceId;
21 19
 import com.google.firebase.iid.InstanceIdResult;
22 20
 
21
+import org.json.JSONException;
23 22
 import org.json.JSONObject;
24 23
 
25 24
 import uprrp.tania.R;
26 25
 import uprrp.tania.SendActivateExperienceToServer;
26
+import uprrp.tania.URLEventListener;
27 27
 
28 28
 public class ExperienceRegistrationActivity  extends AppCompatActivity {
29 29
 
30
-    String device_token;
31
-    String id_experience;
30
+    private final String TAG = "ExperienceRegistrationActivity";
31
+    private String device_token;
32
+    private String id_experience;
33
+
32 34
     @Override
33 35
     protected void onCreate(@Nullable Bundle savedInstanceState) {
36
+
37
+        // Start constructor and fetch UI components
34 38
         super.onCreate(savedInstanceState);
35 39
         setContentView(R.layout.activity_experience_registration);
40
+        final Button experienceRegistrationButton = findViewById(R.id.buttonEnterExperience);
36 41
 
37
-        //Let's get the device's token
42
+        // Change all caps text to normal capitalization
43
+        // TODO: this is a workaround I found, any other acceptable solution is welcome
44
+        experienceRegistrationButton.setTransformationMethod(null);
45
+
46
+        // Request to Firebase...
38 47
         FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
39 48
             @Override
40 49
             public void onSuccess(InstanceIdResult instanceIdResult) {
41
-                device_token = instanceIdResult.getToken();
50
+
51
+            // Get device's token
52
+            device_token = instanceIdResult.getToken();
53
+
54
+            // Set onClick listener on button
55
+            experienceRegistrationButton.setOnClickListener(new View.OnClickListener() {
56
+                @Override
57
+                public void onClick(View v) {
58
+
59
+                    // Initiate progress dialog
60
+                    // TODO: find substitute for this deprecated dialog box
61
+                    final ProgressDialog progressDialog = ProgressDialog.show(ExperienceRegistrationActivity.this,
62
+                            "Registering in Experience",
63
+                            "This shouldn't take long");
64
+
65
+                    if(!id_experience.equals("") && id_experience != null) {
66
+                        try {
67
+
68
+                            // Create JSON with details we'll send
69
+                            JSONObject experienceCodeJSON = new JSONObject();
70
+                            experienceCodeJSON.put("token", device_token);
71
+                            experienceCodeJSON.put("id_experiencia", id_experience);
72
+                            Log.d("EXPERIENCE CODE JSON", experienceCodeJSON.toString());
73
+
74
+                            // Send registration request to server
75
+                            SendActivateExperienceToServer experienceRegistrationTask = new SendActivateExperienceToServer(new URLEventListener() {
76
+                                @Override
77
+                                public void onSuccess() {
78
+                                    progressDialog.dismiss();
79
+                                    Context context = ExperienceRegistrationActivity.this;
80
+                                    Intent intent = new Intent(context, MainActivity.class);
81
+                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
82
+                                    context.startActivity(intent);
83
+                                    Toast.makeText(getApplicationContext(), "You have been registered!", Toast.LENGTH_LONG).show();
84
+                                }
85
+
86
+                                @Override
87
+                                public void onFailure(Exception e) {
88
+                                    progressDialog.dismiss();
89
+                                    // TODO: restrict double registration (maybe in backend?)
90
+                                    Toast.makeText(ExperienceRegistrationActivity.this, "Oops! Something went wrong...", Toast.LENGTH_LONG).show();
91
+                                    Log.e(TAG, "Error occurred while sending registration request to server...");
92
+                                    e.printStackTrace();
93
+                                }
94
+                            });
95
+
96
+                            experienceRegistrationTask.execute(experienceCodeJSON.toString());
97
+
98
+                            // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
99
+                            /*
100
+                            Handler handler = new Handler();
101
+                            handler.postDelayed(new Runnable() {
102
+                                public void run() {
103
+                                    progressDialog.dismiss();
104
+                                    if(false) { // Imitate success
105
+                                        Context context = ExperienceRegistrationActivity.this;
106
+                                        Intent intent = new Intent(context, MainActivity.class);
107
+                                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
108
+                                        context.startActivity(intent);
109
+                                        Toast.makeText(getApplicationContext(), "You have been registered!", Toast.LENGTH_LONG).show();
110
+                                    } else { // Imitate failure
111
+                                        Toast.makeText(ExperienceRegistrationActivity.this, "Oops! Something went wrong...", Toast.LENGTH_LONG).show();
112
+                                    }
113
+                                }
114
+                            }, 5000);
115
+                            */
116
+                            // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
117
+
118
+                        } catch (JSONException e) {
119
+                            progressDialog.dismiss();
120
+                            Toast.makeText(ExperienceRegistrationActivity.this, "Oops! Something went wrong...", Toast.LENGTH_LONG).show();
121
+                            Log.e(TAG, "Error occurred while preparing JSON for server");
122
+                            e.printStackTrace();
123
+                        }
124
+                    } else {
125
+                        progressDialog.dismiss();
126
+                        Toast.makeText(ExperienceRegistrationActivity.this, "Invalid URL!", Toast.LENGTH_LONG).show();
127
+                        Log.d(TAG, "Invalid query parameter found (" + id_experience + ")");
128
+                    }
129
+                }
130
+            });
42 131
             }
43 132
         });
44 133
 
134
+        // Fetch experience ID from URL (only if we launched this Activity from Browser)
45 135
         Intent intent = getIntent();
46
-        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
136
+        if(Intent.ACTION_VIEW.equals(intent.getAction())) {
47 137
             Uri uri = intent.getData();
48
-            assert uri != null;
138
+            assert uri != null; // TODO: figure out if this causes crashes...
49 139
             id_experience = uri.getQueryParameter("id");
50 140
         }
51 141
 
52
-        final JSONObject experienceCodeJSON = new JSONObject();
53
-
54
-        final Button enterExperience = findViewById(R.id.buttonEnterExperience);
55
-        enterExperience.setOnClickListener(new View.OnClickListener() {
56
-            @Override
57
-            public void onClick(View v) {
58
-                try {
59
-                    if (!id_experience.equals("")){
60
-                        experienceCodeJSON.put("token", device_token);
61
-                        experienceCodeJSON.put("id_experiencia", id_experience);
62
-
63
-
64
-                        Log.d("EXPERIENCE CODE JSON", experienceCodeJSON.toString());
65
-
66
-                        SendActivateExperienceToServer sendActivateExperienceToServer = new SendActivateExperienceToServer(getApplicationContext());
67
-                        sendActivateExperienceToServer.execute(experienceCodeJSON.toString());
68
-
69
-                    }
70
-                    else{
71
-                        Toast.makeText(ExperienceRegistrationActivity.this, "The password and confirmation must match!", Toast.LENGTH_LONG).show();
72
-                    }
73
-
74
-
75
-                } catch (Exception e) {
76
-                    e.printStackTrace();
77
-                }
78
-            }
79
-        });
80 142
     }
143
+
81 144
 }

+ 9
- 14
app/src/main/java/uprrp/tania/fragments/AssessmentsFragment.java View File

@@ -62,9 +62,9 @@ public class AssessmentsFragment extends Fragment {
62 62
     @Override
63 63
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
64 64
 
65
-        // Get reference for this fragment
65
+        // Get reference for this fragment and other components
66 66
         final View thisFragment = inflater.inflate(R.layout.fragment_assessments, container, false);
67
-        final AppCompatButton surveyButton = thisFragment.findViewById(R.id.survey_button);
67
+        final AppCompatButton surveyButton = thisFragment.findViewById(R.id.surveyButton);
68 68
         final Button refreshButton = thisFragment.findViewById(R.id.refreshButton); // TODO: check Button vs. AppCompatButton
69 69
 
70 70
         // Change all caps text to normal capitalization
@@ -113,7 +113,7 @@ public class AssessmentsFragment extends Fragment {
113 113
         // Get text fields and initialize other stuff
114 114
         final TextView statusTextView = thisFragment.findViewById(R.id.statusTextView);
115 115
         final TextView nextSurveyTextView = thisFragment.findViewById(R.id.nextSurveyTextView);
116
-        final Button surveyButton = thisFragment.findViewById(R.id.survey_button);
116
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
117 117
         final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
118 118
 
119 119
         // Change UI to indicate loading is happening
@@ -132,13 +132,16 @@ public class AssessmentsFragment extends Fragment {
132 132
                     nextSurveyTextView.setText(userStatus.getTimeToNext());
133 133
                     nextSurveyTextView.setVisibility(View.VISIBLE);
134 134
 
135
-                    // If a survey is available, show "Answer" button (else, show "Refresh" button)
135
+                    // Hide refresh button (it only refreshes user status, anyways so...)
136
+                    refreshButton.setVisibility(View.GONE);
137
+
138
+                    // Toggle "Answer" button visibility depending on survey availability
139
+                    // TODO: Decide whether to show the button regardless of anything,
140
+                    //  since this may be optional functionally, but important for UX
136 141
                     if(userStatus.surveyAvailable()) {
137
-                        refreshButton.setVisibility(View.GONE);
138 142
                         surveyButton.setVisibility(View.VISIBLE);
139 143
                     } else {
140 144
                         surveyButton.setVisibility(View.GONE);
141
-                        refreshButton.setVisibility(View.VISIBLE);
142 145
                     }
143 146
 
144 147
                 } else {
@@ -215,19 +218,11 @@ public class AssessmentsFragment extends Fragment {
215 218
     }
216 219
 
217 220
     private void launchSurvey(AssessmentModel assessment) {
218
-
219
-        // Set id_subquestionnair
220 221
         this.id_subquestionnair = assessment.getID();
221
-
222 222
         List<Step> allSteps = this.prepareSurveySteps(assessment);
223
-
224
-        // Create a task wrapping the steps
225 223
         OrderedTask task = new OrderedTask(SAMPLE_SURVEY, allSteps);
226
-
227
-        // Create an activity using the task and set a delegate
228 224
         Intent intent = ViewTaskActivity.newIntent(getContext(), task);
229 225
         startActivityForResult(intent, REQUEST_SURVEY);
230
-
231 226
     }
232 227
 
233 228
     private void processSurveyResult(TaskResult result) {

+ 6
- 9
app/src/main/java/uprrp/tania/models/UserStatusModel.java View File

@@ -12,27 +12,24 @@ public class UserStatusModel {
12 12
     private int surveys_completed;
13 13
     private int surveys_sent;
14 14
     private String time_to_next;
15
+    private boolean available_now;
15 16
 
16 17
     public boolean isEnrolled() {
17 18
         return true;
18 19
     }
19 20
 
20 21
     public boolean surveyAvailable() {
21
-        // WARNING: Condition might change in the future. Don't change if statement for clarity.
22
-        if(this.time_to_next.equals("::") || this.time_to_next.equals("0:0:0")) {
23
-            return true;
24
-        } else { // TODO: add comparison to null, which signifies experience has ran out of moments
25
-            return false;
26
-        }
22
+        return this.available_now;
27 23
     }
28 24
 
29 25
     public boolean ranOutOfMoments() {
30
-        return this.time_to_next == null; // TODO: confirm this is going to be used
26
+        // NOTE: null signifies experience has ran out of moments
27
+        return this.time_to_next == null;
31 28
     }
32 29
 
33 30
     public String getTimeToNext() {
34 31
         if(this.ranOutOfMoments()) {
35
-            return "No surveys for now. Come back later!";
32
+            return "No more surveys for now.\nCome back later!";
36 33
         } else if(this.surveyAvailable()) {
37 34
             return "Survey available!";
38 35
         } else {
@@ -42,7 +39,7 @@ public class UserStatusModel {
42 39
 
43 40
     private String formatTimeToNext() {
44 41
 
45
-        // Format is DD:HH:MM
42
+        // Format is DD:HH:MM (can be negative if survey can be answered)
46 43
         String[] parts = this.time_to_next.split(":");
47 44
         int days = Integer.parseInt(parts[0]);
48 45
         int hours = Integer.parseInt(parts[1]);

+ 2
- 1
app/src/main/java/uprrp/tania/networking/FetchAssessment.java View File

@@ -37,7 +37,8 @@ public class FetchAssessment extends AsyncTask<String, Void, JSONObject> {
37 37
         String deviceToken = deviceTokenArray[0]; // array will only ever contain a single element
38 38
 
39 39
         try {
40
-            String getMomentsBaseURL = "https://tania.uprrp.edu/getSubQ2.php?tk=";  // TODO: extract URL into @string/getMomentsBaseURL
40
+
41
+            String getMomentsBaseURL = "https://tania.uprrp.edu/getSubQ2.php?tk="; // TODO: extract URL into @string/getMomentsBaseURL
41 42
             URL url = new URL(getMomentsBaseURL + deviceToken);
42 43
             Log.d(TAG, "token:" + deviceToken); // log
43 44
             Log.d(TAG, "url:" + url.toString()); // log

+ 3
- 3
app/src/main/res/layout/activity_consent_pdf_viewer.xml View File

@@ -2,7 +2,7 @@
2 2
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 3
     xmlns:app="http://schemas.android.com/apk/res-auto"
4 4
     xmlns:tools="http://schemas.android.com/tools"
5
-    android:id="@+id/coordinatorLayout2"
5
+    android:id="@+id/ConstraintLayout"
6 6
     android:layout_width="match_parent"
7 7
     android:layout_height="match_parent"
8 8
     tools:context="uprrp.tania.activities.ConsentPdfViewerActivity">
@@ -16,12 +16,12 @@
16 16
         app:layout_constraintEnd_toEndOf="parent"
17 17
         app:layout_constraintHorizontal_bias="0.0"
18 18
         app:layout_constraintStart_toStartOf="parent"
19
-        app:layout_constraintTop_toBottomOf="@+id/appBarLayout2">
19
+        app:layout_constraintTop_toBottomOf="@+id/appBarLayout">
20 20
 
21 21
     </com.github.barteksc.pdfviewer.PDFView>
22 22
 
23 23
     <com.google.android.material.appbar.AppBarLayout
24
-        android:id="@+id/appBarLayout2"
24
+        android:id="@+id/appBarLayout"
25 25
         android:layout_width="match_parent"
26 26
         android:layout_height="61dp"
27 27
         android:theme="@style/Theme.MarleApp.AppBarOverlay"

+ 35
- 39
app/src/main/res/layout/activity_experience_registration.xml View File

@@ -3,66 +3,62 @@
3 3
     xmlns:app="http://schemas.android.com/apk/res-auto"
4 4
     xmlns:tools="http://schemas.android.com/tools"
5 5
     android:layout_width="match_parent"
6
-    android:layout_height="match_parent"
7
-    android:background="@color/colorPrimary">
6
+    android:layout_height="match_parent">
8 7
 
9 8
     <TextView
10 9
         android:id="@+id/textViewActivateExperience"
11
-        android:layout_width="312dp"
12
-        android:layout_height="46dp"
13
-        android:background="@color/textColor1"
14
-        android:fontFamily="@font/acme"
15
-        android:text="Activate Experience"
10
+        android:layout_width="0dp"
11
+        android:layout_height="wrap_content"
12
+        android:layout_marginStart="@dimen/horizontalMargin"
13
+        android:layout_marginTop="@dimen/verticalMargin"
14
+        android:layout_marginEnd="@dimen/horizontalMargin"
15
+        android:layout_marginBottom="16dp"
16
+        android:fontFamily="@font/cabin"
17
+        android:text="@string/experienceRegistrationTitleText"
16 18
         android:textAlignment="center"
17 19
         android:textColor="@color/textColor2"
18
-        android:textSize="30sp"
20
+        android:textSize="@dimen/sectionTitleTextSize"
19 21
         android:textStyle="bold"
20
-        app:layout_constraintBottom_toBottomOf="parent"
22
+        app:layout_constraintBottom_toTopOf="@id/buttonEnterExperience"
21 23
         app:layout_constraintEnd_toEndOf="parent"
22
-        app:layout_constraintHorizontal_bias="0.494"
23 24
         app:layout_constraintStart_toStartOf="parent"
24
-        app:layout_constraintTop_toTopOf="@+id/guideline5"
25
-        app:layout_constraintVertical_bias="0.177" />
26
-
27
-    <androidx.constraintlayout.widget.Guideline
28
-        android:id="@+id/guideline5"
29
-        android:layout_width="wrap_content"
30
-        android:layout_height="wrap_content"
31
-        android:orientation="horizontal"
32
-        app:layout_constraintGuide_begin="75dp" />
25
+        app:layout_constraintTop_toTopOf="parent" />
33 26
 
34 27
     <TextView
35 28
         android:id="@+id/textViewConfirmMessage"
36
-        android:layout_width="317dp"
37
-        android:layout_height="64dp"
38
-        android:background="@color/textColor1"
39
-        android:fontFamily="@font/acme"
29
+        android:layout_width="0dp"
30
+        android:layout_height="wrap_content"
31
+        android:layout_marginStart="@dimen/horizontalMargin"
32
+        android:layout_marginTop="16dp"
33
+        android:layout_marginEnd="@dimen/horizontalMargin"
34
+        android:fontFamily="sans-serif"
40 35
         android:gravity="center"
41
-        android:text="Click the button below to enter the research experience you are participating in."
36
+        android:text="@string/experienceRegistrationDescriptionText"
42 37
         android:textAlignment="center"
43
-        android:textColor="@color/textColor2"
44 38
         android:textSize="18sp"
45
-        app:layout_constraintBottom_toBottomOf="parent"
46 39
         app:layout_constraintEnd_toEndOf="parent"
47
-        app:layout_constraintHorizontal_bias="0.496"
48 40
         app:layout_constraintStart_toStartOf="parent"
49
-        app:layout_constraintTop_toBottomOf="@+id/textViewActivateExperience"
50
-        app:layout_constraintVertical_bias="0.058" />
41
+        app:layout_constraintTop_toBottomOf="@+id/textViewActivateExperience" />
51 42
 
52 43
     <Button
53 44
         android:id="@+id/buttonEnterExperience"
54
-        android:layout_width="314dp"
55
-        android:layout_height="43dp"
56
-        android:background="@color/colorAccent"
57
-        android:fontFamily="@font/acme"
58
-        android:text="ENTER "
59
-        android:textColor="@color/textColor2"
60
-        android:textSize="18sp"
45
+        android:layout_width="0dp"
46
+        android:layout_height="wrap_content"
47
+        android:layout_marginStart="@dimen/horizontalMargin"
48
+        android:layout_marginEnd="@dimen/horizontalMargin"
49
+        android:layout_marginBottom="@dimen/verticalMargin"
50
+        android:background="@drawable/button_background"
51
+        android:fontFamily="sans-serif-black"
52
+        android:paddingHorizontal="@dimen/buttonHorizontalPadding"
53
+        android:paddingVertical="@dimen/buttonVerticalPadding"
54
+        android:text="@string/experienceRegistrationButtonText"
55
+        android:textColor="@android:color/white"
56
+        android:textSize="@dimen/buttonTextSize"
57
+        android:textStyle="bold"
61 58
         app:layout_constraintBottom_toBottomOf="parent"
62 59
         app:layout_constraintEnd_toEndOf="parent"
63
-        app:layout_constraintHorizontal_bias="0.494"
60
+        app:layout_constraintHeight_max="@dimen/buttonMaxHeight"
64 61
         app:layout_constraintStart_toStartOf="parent"
65
-        app:layout_constraintTop_toBottomOf="@+id/textViewConfirmMessage"
66
-        app:layout_constraintVertical_bias="0.07" />
62
+        app:layout_constraintTop_toBottomOf="@id/textViewActivateExperience" />
67 63
 
68 64
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1
- 2
app/src/main/res/layout/activity_main.xml View File

@@ -12,7 +12,7 @@
12 12
     <androidx.appcompat.widget.Toolbar
13 13
         android:id="@+id/toolbar"
14 14
         android:layout_width="match_parent"
15
-        android:layout_height="54dp"
15
+        android:layout_height="@dimen/mainActivityToolbarHeight"
16 16
         android:background="@color/colorPrimary"
17 17
         android:minHeight="?attr/actionBarSize"
18 18
         android:theme="?attr/actionBarTheme"
@@ -47,7 +47,6 @@
47 47
         app:itemIconTint="@color/bottom_nav_selector"
48 48
         app:itemTextColor="@color/bottom_nav_selector"
49 49
         app:layout_constraintBottom_toBottomOf="parent"
50
-        app:layout_constraintHorizontal_bias="1.0"
51 50
         app:layout_constraintLeft_toLeftOf="parent"
52 51
         app:layout_constraintRight_toRightOf="parent"
53 52
         app:menu="@menu/bottom_navigation" />

+ 4
- 5
app/src/main/res/layout/fragment_assessments.xml View File

@@ -8,7 +8,7 @@
8 8
     <androidx.appcompat.widget.AppCompatButton
9 9
         android:id="@+id/refreshButton"
10 10
         android:layout_width="0dp"
11
-        android:layout_height="0dp"
11
+        android:layout_height="wrap_content"
12 12
         android:layout_gravity="center"
13 13
         android:layout_marginStart="@dimen/horizontalMargin"
14 14
         android:layout_marginEnd="@dimen/horizontalMargin"
@@ -24,15 +24,14 @@
24 24
         app:layout_constraintBottom_toBottomOf="parent"
25 25
         app:layout_constraintEnd_toEndOf="parent"
26 26
         app:layout_constraintHeight_max="@dimen/buttonMaxHeight"
27
-        app:layout_constraintHorizontal_bias="0.0"
28 27
         app:layout_constraintStart_toStartOf="parent"
29 28
         app:layout_constraintTop_toBottomOf="@id/statusTextView"
30 29
         tools:visibility="gone" />
31 30
 
32 31
     <androidx.appcompat.widget.AppCompatButton
33
-        android:id="@+id/survey_button"
32
+        android:id="@+id/surveyButton"
34 33
         android:layout_width="0dp"
35
-        android:layout_height="0dp"
34
+        android:layout_height="wrap_content"
36 35
         android:layout_gravity="center"
37 36
         android:layout_marginStart="@dimen/horizontalMargin"
38 37
         android:layout_marginEnd="@dimen/horizontalMargin"
@@ -78,7 +77,7 @@
78 77
         android:textSize="18sp"
79 78
         android:textStyle="bold"
80 79
         android:visibility="gone"
81
-        app:layout_constraintBottom_toTopOf="@+id/survey_button"
80
+        app:layout_constraintBottom_toTopOf="@+id/surveyButton"
82 81
         app:layout_constraintEnd_toEndOf="parent"
83 82
         app:layout_constraintHorizontal_bias="0.5"
84 83
         app:layout_constraintStart_toStartOf="parent"

+ 1
- 1
app/src/main/res/layout/fragment_withdrawal.xml View File

@@ -40,7 +40,7 @@
40 40
     <Button
41 41
         android:id="@+id/withdrawButton"
42 42
         android:layout_width="0dp"
43
-        android:layout_height="0dp"
43
+        android:layout_height="wrap_content"
44 44
         android:layout_marginStart="@dimen/horizontalMargin"
45 45
         android:layout_marginEnd="@dimen/horizontalMargin"
46 46
         android:layout_marginBottom="@dimen/verticalMargin"

+ 1
- 0
app/src/main/res/values/dimens.xml View File

@@ -12,4 +12,5 @@
12 12
     <dimen name="sectionTitleTextSize">32sp</dimen>
13 13
     <dimen name="sectionDescriptionTextSize">20sp</dimen>
14 14
     <dimen name="buttonTextSize">24sp</dimen>
15
+    <dimen name="mainActivityToolbarHeight">54dp</dimen>
15 16
 </resources>

+ 4
- 0
app/src/main/res/values/strings.xml View File

@@ -34,4 +34,8 @@
34 34
     <string name="withdrawTitleText">Withdraw from Study</string>
35 35
     <string name="withdrawButtonText">Withdraw</string>
36 36
     <string name="withdrawing_text">If you no longer want to participate in this research study, you can choose to withdraw. By withdrawing, you understand that your decision is final and your account on TANIA will be removed without any chance of recovery.</string>
37
+    <!--  Experience Registration Activity  -->
38
+    <string name="experienceRegistrationTitleText">Activate Experience</string>
39
+    <string name="experienceRegistrationDescriptionText">Click the button below to enter the research experience you are participating in.</string>
40
+    <string name="experienceRegistrationButtonText">Enter</string>
37 41
 </resources>