diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/a1.png b/Week_04_Simple_Views_and_Layouts/.md_images/a1.png
new file mode 100644
index 0000000..9684e93
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/a1.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/a2.png b/Week_04_Simple_Views_and_Layouts/.md_images/a2.png
new file mode 100644
index 0000000..5958b4d
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/a2.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/activity_lifecycle.png b/Week_04_Simple_Views_and_Layouts/.md_images/activity_lifecycle.png
new file mode 100644
index 0000000..879f51f
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/activity_lifecycle.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/basic-lifecycle.png b/Week_04_Simple_Views_and_Layouts/.md_images/basic-lifecycle.png
new file mode 100644
index 0000000..f991787
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/basic-lifecycle.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/bike.jpg b/Week_04_Simple_Views_and_Layouts/.md_images/bike.jpg
new file mode 100644
index 0000000..b2fded0
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/bike.jpg differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/controls.png b/Week_04_Simple_Views_and_Layouts/.md_images/controls.png
new file mode 100644
index 0000000..ed2dc02
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/controls.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/display.png b/Week_04_Simple_Views_and_Layouts/.md_images/display.png
new file mode 100644
index 0000000..cd0ac92
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/display.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/done.png b/Week_04_Simple_Views_and_Layouts/.md_images/done.png
new file mode 100644
index 0000000..5faac4b
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/done.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/download.png b/Week_04_Simple_Views_and_Layouts/.md_images/download.png
new file mode 100644
index 0000000..0d08032
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/download.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/download_finish.png b/Week_04_Simple_Views_and_Layouts/.md_images/download_finish.png
new file mode 100644
index 0000000..ad2d5bc
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/download_finish.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/layout_structure_regions_guidance4.png b/Week_04_Simple_Views_and_Layouts/.md_images/layout_structure_regions_guidance4.png
new file mode 100644
index 0000000..7b850bc
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/layout_structure_regions_guidance4.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/mode_edit.png b/Week_04_Simple_Views_and_Layouts/.md_images/mode_edit.png
new file mode 100644
index 0000000..23be431
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/mode_edit.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/model_view_controller_2x.png b/Week_04_Simple_Views_and_Layouts/.md_images/model_view_controller_2x.png
new file mode 100644
index 0000000..576948a
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/model_view_controller_2x.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/notes.png b/Week_04_Simple_Views_and_Layouts/.md_images/notes.png
new file mode 100644
index 0000000..3d71e13
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/notes.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/show.png b/Week_04_Simple_Views_and_Layouts/.md_images/show.png
new file mode 100644
index 0000000..b6a051a
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/show.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/ui-controls.png b/Week_04_Simple_Views_and_Layouts/.md_images/ui-controls.png
new file mode 100644
index 0000000..13534d3
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/ui-controls.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/.md_images/volvo.png b/Week_04_Simple_Views_and_Layouts/.md_images/volvo.png
new file mode 100644
index 0000000..862e599
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/.md_images/volvo.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.gitignore b/Week_04_Simple_Views_and_Layouts/MyActivity/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/compiler.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/copyright/profiles_settings.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/gradle.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/misc.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/misc.xml
new file mode 100644
index 0000000..44bc9b2
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/modules.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/modules.xml
new file mode 100644
index 0000000..2eabea5
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/runConfigurations.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/.gitignore b/Week_04_Simple_Views_and_Layouts/MyActivity/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/build.gradle b/Week_04_Simple_Views_and_Layouts/MyActivity/app/build.gradle
new file mode 100644
index 0000000..04c05f8
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.yang.myactivity"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ compile 'com.android.support:support-v4:26.+'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/proguard-rules.pro b/Week_04_Simple_Views_and_Layouts/MyActivity/app/proguard-rules.pro
new file mode 100644
index 0000000..3048997
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/yang/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/androidTest/java/com/example/yang/myactivity/ExampleInstrumentedTest.java b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/androidTest/java/com/example/yang/myactivity/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..6c874d4
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/androidTest/java/com/example/yang/myactivity/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.yang.myactivity;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.yang.myactivity", appContext.getPackageName());
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/AndroidManifest.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5ef7b11
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/DispalyActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/DispalyActivity.java
new file mode 100644
index 0000000..0e097de
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/DispalyActivity.java
@@ -0,0 +1,179 @@
+package com.example.yang.myactivity;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * An example full-screen activity that shows and hides the system UI (i.e.
+ * status bar and navigation/system bar) with user interaction.
+ */
+public class DispalyActivity extends AppCompatActivity {
+
+ /**
+ * Whether or not the system UI should be auto-hidden after
+ * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
+ */
+ private static final boolean AUTO_HIDE = true;
+ /**
+ * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
+ * user interaction before hiding the system UI.
+ */
+ private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
+ /**
+ * Some older devices needs a small delay between UI widget updates
+ * and a change of the status and navigation bar.
+ */
+ private static final int UI_ANIMATION_DELAY = 300;
+ private final Handler mHideHandler = new Handler();
+ /**
+ * Touch listener to use for in-layout UI controls to delay hiding the
+ * system UI. This is to prevent the jarring behavior of controls going away
+ * while interacting with activity UI.
+ */
+ private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (AUTO_HIDE) {
+ delayedHide(AUTO_HIDE_DELAY_MILLIS);
+ }
+ return false;
+ }
+ };
+ private TextView textView;
+ private View mContentView;
+ private final Runnable mHidePart2Runnable = new Runnable() {
+ @SuppressLint("InlinedApi")
+ @Override
+ public void run() {
+ // Delayed removal of status and navigation bar
+
+ // Note that some of these constants are new as of API 16 (Jelly Bean)
+ // and API 19 (KitKat). It is safe to use them, as they are inlined
+ // at compile-time and do nothing on earlier devices.
+ mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+ }
+ };
+ private View mControlsView;
+ private final Runnable mShowPart2Runnable = new Runnable() {
+ @Override
+ public void run() {
+ // Delayed display of UI elements
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.show();
+ }
+ mControlsView.setVisibility(View.VISIBLE);
+ }
+ };
+ private boolean mVisible;
+ private final Runnable mHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hide();
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_dispaly);
+
+ mVisible = true;
+ mControlsView = findViewById(R.id.fullscreen_content_controls);
+ mContentView = findViewById(R.id.fullscreen_content);
+
+
+ // Set up the user interaction to manually show or hide the system UI.
+ mContentView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ toggle();
+ }
+ });
+
+ // Upon interacting with UI controls, delay any scheduled hide()
+ // operations to prevent the jarring behavior of controls going away
+ // while interacting with the UI.
+ findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
+
+ textView = (TextView) findViewById(R.id.fullscreen_content);
+ StringBuilder messageFromActivity1 = new StringBuilder();
+ Intent intent = getIntent();
+ Bundle bundle = intent.getExtras();
+ messageFromActivity1.append("Make: " + intent.getStringExtra(MainActivity.KEY_MAKE) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Year: " + intent.getIntExtra(MainActivity.KEY_YEAR, 0) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Color: " + intent.getStringExtra(MainActivity.KEY_COLOR) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Note: " + bundle.getString(MainActivity.KEY_NOTE) + System.getProperty("line.separator"));
+ textView.setText(messageFromActivity1);
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+
+ // Trigger the initial hide() shortly after the activity has been
+ // created, to briefly hint to the user that UI controls
+ // are available.
+ delayedHide(100);
+ }
+
+ private void toggle() {
+ if (mVisible) {
+ hide();
+ } else {
+ show();
+ }
+ }
+
+ private void hide() {
+ // Hide UI first
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+ mControlsView.setVisibility(View.GONE);
+ mVisible = false;
+
+ // Schedule a runnable to remove the status and navigation bar after a delay
+ mHideHandler.removeCallbacks(mShowPart2Runnable);
+ mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
+ }
+
+ @SuppressLint("InlinedApi")
+ private void show() {
+ // Show the system bar
+ mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ mVisible = true;
+
+ // Schedule a runnable to display UI elements after a delay
+ mHideHandler.removeCallbacks(mHidePart2Runnable);
+ mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
+ }
+
+ /**
+ * Schedules a call to hide() in [delay] milliseconds, canceling any
+ * previously scheduled calls.
+ */
+ private void delayedHide(int delayMillis) {
+ mHideHandler.removeCallbacks(mHideRunnable);
+ mHideHandler.postDelayed(mHideRunnable, delayMillis);
+ }
+
+ public void onReturnClick(View v) {
+ finish();
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/MainActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/MainActivity.java
new file mode 100644
index 0000000..3f9b888
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/MainActivity.java
@@ -0,0 +1,95 @@
+package com.example.yang.myactivity;
+
+import android.content.Intent;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+
+public class MainActivity extends AppCompatActivity {
+
+ public static final String KEY_MAKE = "keyMake";
+ public static final String KEY_YEAR = "keyYear";
+ public static final String KEY_COLOR = "keyColor";
+ public static final String KEY_NOTE = "keyNote";
+ private static final int REQUEST_EDIT = 1234;
+ private static final String TAG_LIFECYCLE = "TagLifecycle";
+ private EditText editTextMake;
+ private EditText editTextYear;
+ private EditText editTextColor;
+ private EditText editTextNote;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Log.d(TAG_LIFECYCLE, "In the onCreate() event");
+
+ editTextMake = (EditText) findViewById(R.id.inputMake);
+ editTextYear = (EditText) findViewById(R.id.inputYear);
+ editTextColor = (EditText) findViewById(R.id.inputColor);
+ editTextNote = (EditText) findViewById(R.id.inputNote);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ Log.d(TAG_LIFECYCLE, "In the onStart() event");
+ }
+
+ @Override
+ public void onRestart() {
+ super.onRestart();
+ Log.d(TAG_LIFECYCLE, "In the onRestart() event");
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ Log.d(TAG_LIFECYCLE, "In the onResume() event");
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ Log.d(TAG_LIFECYCLE, "In the onPause() event");
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ Log.d(TAG_LIFECYCLE, "In the onStop() event");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ Log.d(TAG_LIFECYCLE, "In the onDestroy() event");
+ }
+
+ public void goEdit(View v) {
+ Intent intentEdit = new Intent(this, NoteEditingActivity.class);
+ startActivityForResult(intentEdit, REQUEST_EDIT);
+ }
+
+ public void goDisplay(View v) {
+ Intent intentDisplay = new Intent();
+ intentDisplay.setAction("com.example.jianhuayang.myactivities.ThirdActivity");
+ intentDisplay.putExtra(KEY_MAKE, editTextMake.getText().toString());
+ intentDisplay.putExtra(KEY_YEAR, Integer.parseInt(editTextYear.getText().toString()));
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_COLOR, editTextColor.getText().toString());
+ bundle.putString(KEY_NOTE, editTextNote.getText().toString());
+ intentDisplay.putExtras(bundle);
+ startActivity(intentDisplay);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_EDIT && resultCode == RESULT_OK) {
+ editTextNote.setText(data.getData().toString());
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/NoteEditingActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/NoteEditingActivity.java
new file mode 100644
index 0000000..17d221a
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/java/com/example/yang/myactivity/NoteEditingActivity.java
@@ -0,0 +1,28 @@
+package com.example.yang.myactivity;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+
+public class NoteEditingActivity extends AppCompatActivity {
+
+ EditText editText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_note_editing);
+ editText = (EditText) findViewById(R.id.inputNote);
+ }
+
+ public void onDoneClick(View v) {
+ Intent intent = new Intent();
+ Uri uri = Uri.parse(editText.getText().toString());
+ intent.setData(uri);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_dispaly.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_dispaly.xml
new file mode 100644
index 0000000..3f18c24
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_dispaly.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_main.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..b8c21e4
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_note_editing.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_note_editing.xml
new file mode 100644
index 0000000..d284113
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/layout/activity_note_editing.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/attrs.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..7ce840e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/attrs.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/colors.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..227fd33
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/colors.xml
@@ -0,0 +1,8 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
+ #66000000
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/strings.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..63b600f
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+ My Activity
+
+ DispalyActivity
+ Return
+ DUMMY\nCONTENT
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/styles.xml b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..08112f9
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/main/res/values/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/test/java/com/example/yang/myactivity/ExampleUnitTest.java b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/test/java/com/example/yang/myactivity/ExampleUnitTest.java
new file mode 100644
index 0000000..a913885
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/app/src/test/java/com/example/yang/myactivity/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.yang.myactivity;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/build.gradle b/Week_04_Simple_Views_and_Layouts/MyActivity/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/gradle.properties b/Week_04_Simple_Views_and_Layouts/MyActivity/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/gradle/wrapper/gradle-wrapper.jar b/Week_04_Simple_Views_and_Layouts/MyActivity/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/gradle/wrapper/gradle-wrapper.properties b/Week_04_Simple_Views_and_Layouts/MyActivity/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..da2a1b0
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Oct 23 15:26:45 BST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/gradlew b/Week_04_Simple_Views_and_Layouts/MyActivity/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/gradlew.bat b/Week_04_Simple_Views_and_Layouts/MyActivity/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity/settings.gradle b/Week_04_Simple_Views_and_Layouts/MyActivity/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.gitignore b/Week_04_Simple_Views_and_Layouts/MyActivity2/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/compiler.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/copyright/profiles_settings.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/gradle.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/misc.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/misc.xml
new file mode 100644
index 0000000..5d19981
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/modules.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/modules.xml
new file mode 100644
index 0000000..289fc14
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/modules.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/runConfigurations.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/.gitignore b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/build.gradle b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/build.gradle
new file mode 100644
index 0000000..04c05f8
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.yang.myactivity"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ compile 'com.android.support:support-v4:26.+'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/proguard-rules.pro b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/proguard-rules.pro
new file mode 100644
index 0000000..3048997
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/yang/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/androidTest/java/com/example/yang/myactivity/ExampleInstrumentedTest.java b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/androidTest/java/com/example/yang/myactivity/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..6c874d4
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/androidTest/java/com/example/yang/myactivity/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.yang.myactivity;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.yang.myactivity", appContext.getPackageName());
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/AndroidManifest.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b85607e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/DispalyActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/DispalyActivity.java
new file mode 100644
index 0000000..0e097de
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/DispalyActivity.java
@@ -0,0 +1,179 @@
+package com.example.yang.myactivity;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * An example full-screen activity that shows and hides the system UI (i.e.
+ * status bar and navigation/system bar) with user interaction.
+ */
+public class DispalyActivity extends AppCompatActivity {
+
+ /**
+ * Whether or not the system UI should be auto-hidden after
+ * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
+ */
+ private static final boolean AUTO_HIDE = true;
+ /**
+ * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
+ * user interaction before hiding the system UI.
+ */
+ private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
+ /**
+ * Some older devices needs a small delay between UI widget updates
+ * and a change of the status and navigation bar.
+ */
+ private static final int UI_ANIMATION_DELAY = 300;
+ private final Handler mHideHandler = new Handler();
+ /**
+ * Touch listener to use for in-layout UI controls to delay hiding the
+ * system UI. This is to prevent the jarring behavior of controls going away
+ * while interacting with activity UI.
+ */
+ private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (AUTO_HIDE) {
+ delayedHide(AUTO_HIDE_DELAY_MILLIS);
+ }
+ return false;
+ }
+ };
+ private TextView textView;
+ private View mContentView;
+ private final Runnable mHidePart2Runnable = new Runnable() {
+ @SuppressLint("InlinedApi")
+ @Override
+ public void run() {
+ // Delayed removal of status and navigation bar
+
+ // Note that some of these constants are new as of API 16 (Jelly Bean)
+ // and API 19 (KitKat). It is safe to use them, as they are inlined
+ // at compile-time and do nothing on earlier devices.
+ mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+ }
+ };
+ private View mControlsView;
+ private final Runnable mShowPart2Runnable = new Runnable() {
+ @Override
+ public void run() {
+ // Delayed display of UI elements
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.show();
+ }
+ mControlsView.setVisibility(View.VISIBLE);
+ }
+ };
+ private boolean mVisible;
+ private final Runnable mHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hide();
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_dispaly);
+
+ mVisible = true;
+ mControlsView = findViewById(R.id.fullscreen_content_controls);
+ mContentView = findViewById(R.id.fullscreen_content);
+
+
+ // Set up the user interaction to manually show or hide the system UI.
+ mContentView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ toggle();
+ }
+ });
+
+ // Upon interacting with UI controls, delay any scheduled hide()
+ // operations to prevent the jarring behavior of controls going away
+ // while interacting with the UI.
+ findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
+
+ textView = (TextView) findViewById(R.id.fullscreen_content);
+ StringBuilder messageFromActivity1 = new StringBuilder();
+ Intent intent = getIntent();
+ Bundle bundle = intent.getExtras();
+ messageFromActivity1.append("Make: " + intent.getStringExtra(MainActivity.KEY_MAKE) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Year: " + intent.getIntExtra(MainActivity.KEY_YEAR, 0) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Color: " + intent.getStringExtra(MainActivity.KEY_COLOR) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Note: " + bundle.getString(MainActivity.KEY_NOTE) + System.getProperty("line.separator"));
+ textView.setText(messageFromActivity1);
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+
+ // Trigger the initial hide() shortly after the activity has been
+ // created, to briefly hint to the user that UI controls
+ // are available.
+ delayedHide(100);
+ }
+
+ private void toggle() {
+ if (mVisible) {
+ hide();
+ } else {
+ show();
+ }
+ }
+
+ private void hide() {
+ // Hide UI first
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+ mControlsView.setVisibility(View.GONE);
+ mVisible = false;
+
+ // Schedule a runnable to remove the status and navigation bar after a delay
+ mHideHandler.removeCallbacks(mShowPart2Runnable);
+ mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
+ }
+
+ @SuppressLint("InlinedApi")
+ private void show() {
+ // Show the system bar
+ mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+ mVisible = true;
+
+ // Schedule a runnable to display UI elements after a delay
+ mHideHandler.removeCallbacks(mHidePart2Runnable);
+ mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
+ }
+
+ /**
+ * Schedules a call to hide() in [delay] milliseconds, canceling any
+ * previously scheduled calls.
+ */
+ private void delayedHide(int delayMillis) {
+ mHideHandler.removeCallbacks(mHideRunnable);
+ mHideHandler.postDelayed(mHideRunnable, delayMillis);
+ }
+
+ public void onReturnClick(View v) {
+ finish();
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/DownloadActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/DownloadActivity.java
new file mode 100644
index 0000000..86f7f97
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/DownloadActivity.java
@@ -0,0 +1,73 @@
+package com.example.yang.myactivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+public class DownloadActivity extends AppCompatActivity {
+
+ public static final String KEY_DRAWABLE = "keyDrawable";
+
+ private ProgressBar progressBar;
+ private TextView textView;
+ private ImageView imageView;
+ private int progressStatus;
+ private static int staticStatus;
+ private Handler handler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_download);
+
+ progressBar = (ProgressBar) findViewById(R.id.progressBar);
+ textView = (TextView) findViewById(R.id.textView);
+ imageView = (ImageView) findViewById(R.id.imageView);
+ imageView.setVisibility(View.GONE);
+ staticStatus = 0;
+
+ new Thread(new Runnable() {
+ public void run() {
+ while (progressStatus < 100) {
+ progressStatus = doSomeWork();
+ handler.post(new Runnable() {
+ public void run() {
+ progressBar.setProgress(progressStatus);
+ }
+ });
+ }
+ if (progressStatus == 100) {
+ handler.post(new Runnable() {
+ public void run() {
+ progressBar.setVisibility(View.GONE);
+ textView.setVisibility(View.GONE);
+ imageView.setVisibility(View.VISIBLE);
+ imageView.setImageResource(R.drawable.bike);
+ }
+ });
+ }
+ }
+
+ private int doSomeWork() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return ++staticStatus;
+ }
+ }).start();
+ }
+
+ public void onReturnClick(View v) {
+ Intent intent = new Intent();
+ intent.putExtra(KEY_DRAWABLE, R.drawable.bike);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/MainActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/MainActivity.java
new file mode 100644
index 0000000..5188a25
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/MainActivity.java
@@ -0,0 +1,149 @@
+package com.example.yang.myactivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.Spinner;
+import android.widget.Switch;
+
+public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{
+
+ public static final String KEY_MAKE = "keyMake";
+ public static final String KEY_Fuel = "keyFuel";
+ public static final String KEY_YEAR = "keyYear";
+ public static final String KEY_COLOR = "keyColor";
+ public static final String KEY_NEW = "keyNew";
+ public static final String KEY_RIGHT_HAND = "keyRightHand";
+ public static final String KEY_NOTE = "keyNote";
+ private static final String TAG_LIFECYCLE = "TagLifecycle";
+ private static final int REQUEST_EDIT = 1234;
+ private static final int REQUEST_DOWNLOAD = 5678;
+
+ private Spinner spinnerMaker;
+ private Switch switchFuel;
+ private EditText editTextYear;
+ private RadioGroup radioGroupColor;
+ private CheckBox checkBoxNew;
+ private CheckBox checkBoxRightHand;
+ private Button buttonImage;
+ private EditText editTextNote;
+
+ private String[] carMaker;
+ private String make;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Log.d(TAG_LIFECYCLE, "In the onCreate() event");
+
+ spinnerMaker = (Spinner) findViewById(R.id.spinnerMake);
+ switchFuel = (Switch) findViewById(R.id.switchFuel);
+ editTextYear = (EditText) findViewById(R.id.inputYear);
+ radioGroupColor = (RadioGroup) findViewById(R.id.radioColor);
+ checkBoxNew = (CheckBox) findViewById(R.id.isNew);
+ checkBoxRightHand = (CheckBox) findViewById(R.id.isRightHand);
+ buttonImage = (Button) findViewById(R.id.buttonImage);
+ editTextNote = (EditText) findViewById(R.id.inputNote);
+ carMaker = getResources().getStringArray(R.array.car_maker);
+
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
+ R.array.car_maker, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerMaker.setAdapter(adapter);
+ spinnerMaker.setOnItemSelectedListener(this);
+ }
+ @Override
+ public void onStart() {
+ super.onStart();
+ Log.d(TAG_LIFECYCLE, "In the onStart() event");
+ }
+
+ @Override
+ public void onRestart() {
+ super.onRestart();
+ Log.d(TAG_LIFECYCLE, "In the onRestart() event");
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ Log.d(TAG_LIFECYCLE, "In the onResume() event");
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ Log.d(TAG_LIFECYCLE, "In the onPause() event");
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ Log.d(TAG_LIFECYCLE, "In the onStop() event");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ Log.d(TAG_LIFECYCLE, "In the onDestroy() event");
+ }
+
+ public void goEdit(View v) {
+ Intent intentEdit = new Intent(this, NoteEditingActivity.class);
+ startActivityForResult(intentEdit, REQUEST_EDIT);
+ }
+
+ public void goDisplay(View v) {
+ Intent intent = new Intent();
+ intent.setAction("com.example.jianhuayang.myactivities.ThirdActivity");
+ intent.putExtra(KEY_MAKE, make);
+ intent.putExtra(KEY_Fuel, switchFuel.isChecked());
+ intent.putExtra(KEY_YEAR, Integer.parseInt(editTextYear.getText().toString()));
+ Bundle bundle = new Bundle();
+ String color = ((RadioButton) findViewById(radioGroupColor.getCheckedRadioButtonId())).getText().toString();
+ bundle.putString(KEY_COLOR, color);
+ bundle.putBoolean(KEY_NEW, checkBoxNew.isChecked());
+ bundle.putBoolean(KEY_RIGHT_HAND, checkBoxRightHand.isChecked());
+ bundle.putString(KEY_NOTE, editTextNote.getText().toString());
+ intent.putExtras(bundle);
+ startActivity(intent);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_EDIT && resultCode == RESULT_OK) {
+ editTextNote.setText(data.getData().toString());
+ }
+
+ if (requestCode == REQUEST_DOWNLOAD && resultCode == RESULT_OK) {
+ buttonImage.setText("");
+ buttonImage.setBackgroundResource(data.getIntExtra(DownloadActivity.KEY_DRAWABLE, R.mipmap.ic_launcher));
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ make = carMaker[position];
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ make = "No maker selected";
+ }
+
+ public void goDownload(View v) {
+ Intent aIntent = new Intent(this, DownloadActivity.class);
+ startActivityForResult(aIntent, REQUEST_DOWNLOAD);
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/NoteEditingActivity.java b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/NoteEditingActivity.java
new file mode 100644
index 0000000..17d221a
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/java/com/example/yang/myactivity/NoteEditingActivity.java
@@ -0,0 +1,28 @@
+package com.example.yang.myactivity;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+
+public class NoteEditingActivity extends AppCompatActivity {
+
+ EditText editText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_note_editing);
+ editText = (EditText) findViewById(R.id.inputNote);
+ }
+
+ public void onDoneClick(View v) {
+ Intent intent = new Intent();
+ Uri uri = Uri.parse(editText.getText().toString());
+ intent.setData(uri);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-hdpi/ic_mode_edit_black_24dp.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-hdpi/ic_mode_edit_black_24dp.png
new file mode 100644
index 0000000..e531d72
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-hdpi/ic_mode_edit_black_24dp.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-mdpi/ic_mode_edit_black_24dp.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-mdpi/ic_mode_edit_black_24dp.png
new file mode 100644
index 0000000..9efbaae
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-mdpi/ic_mode_edit_black_24dp.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xhdpi/ic_mode_edit_black_24dp.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xhdpi/ic_mode_edit_black_24dp.png
new file mode 100644
index 0000000..87f8de1
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xhdpi/ic_mode_edit_black_24dp.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xxhdpi/ic_mode_edit_black_24dp.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xxhdpi/ic_mode_edit_black_24dp.png
new file mode 100644
index 0000000..4af4ae6
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xxhdpi/ic_mode_edit_black_24dp.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_black_24dp.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_black_24dp.png
new file mode 100644
index 0000000..d6761ba
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_black_24dp.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable/bike.jpg b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable/bike.jpg
new file mode 100644
index 0000000..b2fded0
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/drawable/bike.jpg differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_dispaly.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_dispaly.xml
new file mode 100644
index 0000000..3f18c24
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_dispaly.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_download.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_download.xml
new file mode 100644
index 0000000..1201c64
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_download.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_main.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..0cc23c6
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,266 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_note_editing.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_note_editing.xml
new file mode 100644
index 0000000..d284113
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/layout/activity_note_editing.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/attrs.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..7ce840e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/attrs.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/colors.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..227fd33
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/colors.xml
@@ -0,0 +1,8 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
+ #66000000
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/strings.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..7f8d685
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/strings.xml
@@ -0,0 +1,13 @@
+
+ My Activity
+
+ DispalyActivity
+ Return
+ DUMMY\nCONTENT
+
+
+ Volvo
+ Mini
+ Volkswagen
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/styles.xml b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..08112f9
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/main/res/values/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/test/java/com/example/yang/myactivity/ExampleUnitTest.java b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/test/java/com/example/yang/myactivity/ExampleUnitTest.java
new file mode 100644
index 0000000..a913885
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/app/src/test/java/com/example/yang/myactivity/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.yang.myactivity;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/build.gradle b/Week_04_Simple_Views_and_Layouts/MyActivity2/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle.properties b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle/wrapper/gradle-wrapper.jar b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle/wrapper/gradle-wrapper.properties b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..da2a1b0
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Oct 23 15:26:45 BST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/gradlew b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/gradlew.bat b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_04_Simple_Views_and_Layouts/MyActivity2/settings.gradle b/Week_04_Simple_Views_and_Layouts/MyActivity2/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/MyActivity2/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_04_Simple_Views_and_Layouts/README.md b/Week_04_Simple_Views_and_Layouts/README.md
new file mode 100644
index 0000000..d4b2dff
--- /dev/null
+++ b/Week_04_Simple_Views_and_Layouts/README.md
@@ -0,0 +1,1108 @@
+# Simple Views and Layouts
+
+Apps you created so far are 'single-page applications' - That is an app that runs within a single Activity (capital 'A'). This week, let's look at Activity lifecycle, how to pass data between Activities, and examine some more layouts and widgets.
+
+## Lab 1 UI design
+
+Before having a big picture of what Android has to offer, let's first have a look at a popular design pattern called MVC (Model-View-Controller).
+
+### MVC pattern
+
+The MVC pattern, which plays a vital role in modern application programming, assigns objects in an application one of three roles: model, view, or controller:
+
+- *Model*: Model is your data structure. It holds the relationship within your data. Model objects encapsulate the data specific to an application and define the logic and computation that manipulate and process that data.
+- *View*: A view object is an object in an application that users can see. A view object knows how to draw itself and can respond to user actions.
+- *Controller*: A controller object acts as an intermediary between one or more of an application’s view objects and one or more of its model objects. In Android, a controller is typically a subclass of Activity, Fragment, or Service.
+
+
+
+
+
+In Android, especially for small-scale apps, it's often not easy to distinguish roles within the MVC pattern. But the benefits of MVC is obvious - it separates the front-end and back-end, and make it easier to reuse your classes.
+
+### Design principles
+
+On the [official Android website](http://developer.android.com/design/get-started/principles.html) Google lists following principles you need to follow when designing your app, but most of them boils down to common sense.
+
+- *Enchant me*: 'your app should strive to combine beauty, simplicity and purpose to create a magical experience that is effortless and powerful' (quoted directly from Google).
+- *Simplify my life*: make your app easy to navigate, easy to use, easy to understand.
+- *Make me amazing*: provide visual hints and/or default values for your app, break big tasks into smaller steps.
+
+[The Material Design](https://www.google.com/design/spec/material-design/introduction.html) (since Android 5.0 Lollipop) provides detailed guidelines for visual, motion etc. and covers almost everything one can think of in app design. Below are some common requirements that you should try to meet and pitfalls that you should try to avoid in your apps. Detailed requirements can be found in Material Design documentation.
+
+- *Motion*: Changes in acceleration or deceleration should be smooth across the duration of an animation.
+- *Style*: Use system recommended color, icons, meaningful and genuine images. Use concise and simple languages.
+- *Layout*: Design to suit different devices and screen-sizes. Try to avoid slicing up the interface into too many regions like in the following
+
+
+ 
+
+- *Components*: Requirements were laid in Material Design for different UI components such as buttons or menus. Some of these requirements are very specific, e.g. button height need to be 36dp in a dialog. Some other requirements tend to be more general, e.g the rule that states don't use flat buttons in UIs where they would be difficult to see.
+- *Patterns*: Material Design has guidelines for different scenarios which is referred to as 'patterns'. For example, launch screens can be either placeholder UI or branded launch. Of course, you can implement anything you wish, but it'll be better if you go for one of these two for your apps.
+
+The above is a really brief 'abstract' of the Material Design documentation. The important things to remember is, if in doubt, check the official documentation.
+
+### Activity lifecycle
+
+Now let's start exploring the Activity lifecycle. In Android each Activity is (normally) associated with a layout xml file. Before and after the layout becomes visible/invisible on the screen the system has to create or destroy the Activity object by calling some callback methods such as the `onCreate()`. The whole process i.e. lifecycle of an Activity involves several different stages and callback methods.
+
+Following steps below to create a new project and insert some overriding methods:
+
+1. Create a new project called 'My Activities'.
+2. Insert the following code into the class body of 'MainActivity.java'.
+
+ ```java
+ private static final String TAG_LIFECYCLE = "TagLifecycle";
+ ```
+3. Insert the following into the `onCreate` method
+
+ ```java
+ Log.d(TAG_LIFECYCLE, "In the onCreate() event");
+ ```
+4. Insert the following into the class body:
+
+ ```java
+ @Override
+ public void onStart() {
+ super.onStart();
+ Log.d(TAG_LIFECYCLE, "In the onStart() event");
+ }
+
+ @Override
+ public void onRestart() {
+ super.onRestart();
+ Log.d(TAG_LIFECYCLE, "In the onRestart() event");
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ Log.d(TAG_LIFECYCLE, "In the onResume() event");
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ Log.d(TAG_LIFECYCLE, "In the onPause() event");
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ Log.d(TAG_LIFECYCLE, "In the onStop() event");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ Log.d(TAG_LIFECYCLE, "In the onDestroy() event");
+ }
+ ```
+5. Start your AVD or connect you phone/tablet, and run the app. In logcat, use 'TagLifecycle' to filter the outputs. Now try to answer the following:
+
+ * When you first start the app, which methods were called?
+ * Press the 'home' (circle) button, which methods are called?
+ * Press the 'overview' (square) button and bring back the app, which methods are called?
+ * If you now press 'back' button, which methods are called?
+ * Now, press the app icon on your phone to start again, what happened? What does it mean?
+
+ > For button names, see [here](https://support.google.com/nexus/answer/6073614)
+
+Talking about Activity lifecycle, there're two diagrams you need know:
+
+
+
+
+`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'(a beautiful divider)
+ ` ` ` ` ` ` ` ` ` `
+
+
+
+
+The upper image depicts all callback methods an Activity has to go through from the start of its life until the end. Even though there're so many different callbacks, there're only three constant states, as shown in the lower image:
+
+- *Resumed*: The activity is in the foreground of the screen and has user focus.
+- *Paused*: Another activity is in the foreground and has focus, but this one is still visible.
+- *Stopped*: The activity is completely obscured by another activity.
+
+The other two states in the lower image above i.e. created and started are transient and the system quickly moves from them to the next state by calling the next lifecycle callback method. Read [Activity callback methods on the official guide](http://developer.android.com/guide/components/activities.html).
+
+Note here:
+
+1. The 'home' button doesn't destroy your activity. The system will remember your app's current state. So press 'home' button and then press your app icon to restart your app is **NOT** a way to show data persistence.
+2. If the system must recover memory in an emergency, `onStop()` and `onDestroy()` might not be called. Again, to save data for the sake of persistence you'll need to do it in `onPause()`.
+
+> [What is the correct order of calling superclass methods in onPause, onStop and onDestroy methods? and Why?](https://stackoverflow.com/questions/18821481/what-is-the-correct-order-of-calling-superclass-methods-in-onpause-onstop-and-o)
+
+### FrameLayout, ScrollView and TableLayouts
+
+In this section, you'll continue working on 'My Activities' project and make it a 3-activity app. The idea is that in the main activity if you click a button (i.e. 'write note') it'll take you to a second activity where you can take some notes. Once finished, if you click 'display', all the info you typed will be displayed in a new 3rd activity.
+
+Following steps below to insert two more activities and prepare the layout file for later use.
+
+1. In the Project tool window, right-click app, select New ==> Activity ==> Empty Activity, name it 'NoteEditingActivity'.
+2. Similarly, create another activity using the FullscreenActivity template and name it 'DispalyActivity'.
+3. Open activity_display.xml, you'll see the root tag is **FrameLayout**. The FrameLayout is a placeholder on the screen that you can use to display a single view. Views that you add to a FrameLayout are always anchored to the top left of the layout.
+4. Open activity_main.xml, delete TextView, and replace it with a ScrollView.
+ ```xml
+
+
+ ```
+5. On design view, drag and drop a TableLayout and a TableRow onto the ScrollView. Make some changes so the TableLayout looks like:
+
+ ```xml
+
+
+
+
+
+ ```
+
+6. Duplicate the TableRow tags seven times. In other words, it will be a 7-row table. Add some additional widgets and rearrange its attributes so it looks like the following:
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+ There're several things you need to know in this layout file:
+
+ * A **ScrollView** is a subclass of FrameLayout. It's a layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display. The ScrollView can contain only one child view or ViewGroup.
+ * A **TableLayout** is like a table in spreadsheet i.e. it has columns and rows. In the example above, the first TextView i.e. with text 'Activity No.1' starts at column 1 `android:layout_column="0"` and spans for two columns `android:layout_span="2"`.
+ * If you don't want to specify starting column number, you can put a placeholder such as an empty TextView before button 'buttonNote'.
+ * It's your first time to see the 'View' tag. This is basically to draw a divider line with height 3dp.
+
+ Your screen should now look like the following:
+
+ 
+
+7. Open activity_note_editing.xml and change the ConstraintLayout layout to have the following widgets in it:
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+
+ ```
+ This is pretty easy to understand. Note line `android:layout_height="0dp"` and `android:layout_weight="1"`. This is basically telling the EditText to occupy all available pace in its parent view. Your screen now should look like:
+
+ 
+
+8. For NoteEditingActivity, you want it to show a dialog style. In other words, it shows up as partially occupying the screen. So add the following to styles.xml
+
+ ```xml
+
+ ```
+ Open AdroidManifest.xml, change the style of the activity to the one you just created
+
+ ```xml
+
+
+ ```
+
+Now you have completed GUI design for your three activities. But you haven't looked at the DisplayActivity yet. If you open actvity_display.xml, it should look like the following
+
+
+
+Change the text displayed in the Button to 'Return' by changing the following in strings.xml `Return`.
+
+### Intents
+
+Next, let's link all buttons with appropriate methods.
+
+Open MainActivity.java, follow steps below to insert several functions:
+
+1. Open MainActivity.java, declare the following as class members:
+
+ ```java
+ public static final String KEY_MAKE = "keyMake";
+ public static final String KEY_YEAR = "keyYear";
+ public static final String KEY_COLOR = "keyColor";
+ public static final String KEY_NOTE = "keyNote";
+ private static final int REQUEST_EDIT = 1234;
+
+ private EditText editTextMake;
+ private EditText editTextYear;
+ private EditText editTextColor;
+ private EditText editTextNote;
+ ```
+
+2. In `onCreate()` method, initialize widget members by inserting the following:
+
+ ```java
+ editTextMake = (EditText) findViewById(R.id.inputMake);
+ editTextYear = (EditText) findViewById(R.id.inputYear);
+ editTextColor = (EditText) findViewById(R.id.inputColor);
+ editTextNote = (EditText) findViewById(R.id.inputNote);
+ ```
+
+3. Insert the following two methods into the class.
+
+ ```java
+ public void goEdit(View v) {
+ Intent intentEdit = new Intent(this, NoteEditingActivity.class);
+ startActivityForResult(intentEdit, REQUEST_EDIT);
+ }
+
+ public void goDisplay(View v) {
+ Intent intentDisplay = new Intent();
+ intentDisplay.setAction("com.example.jianhuayang.myactivities.ThirdActivity");
+ intentDisplay.putExtra(KEY_MAKE, editTextMake.getText().toString());
+ intentDisplay.putExtra(KEY_YEAR, Integer.parseInt(editTextYear.getText().toString()));
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_COLOR, editTextColor.getText().toString());
+ bundle.putString(KEY_NOTE, editTextNote.getText().toString());
+ intentDisplay.putExtras(bundle);
+ startActivity(intentDisplay);
+ }
+ ```
+
+ There're quite a lot going on in the code above:
+
+ * Before starting a new Activity, you must define an **Intent** object. In the example above, there are two different ways of doing it: one uses `Intent(this, NoteEditingActivity.class)` where 'this' is the current object, and '.class' is the type of the targeting object; The other is that you create an empty Intent and then set the Action, which is a String defined in **IntentFilters**. More on this later.
+ * You can pass data along with Intent objects. The way to do it is to use `putExtra()` or `putExtras()` method. These methods take key-value pairs as inputs, where the key is used to retrieve the data back.
+ * To actually move to a different Activity, you'll need either `startActivity()` or `startActivityForResult()` method. For both methods, you'll need to supply an Intent. The difference is that for the latter you need to get the results back from the other Intent.
+
+4. Insert the following method into the class. This is to retrieve data from Activities started by the `startActivityForResult()` method.
+
+ ```java
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_EDIT && resultCode == RESULT_OK) {
+ editTextNote.setText(data.getData().toString());
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ ```
+
+ The code above tests to see if the results come from the original request by comparing the request code. If it is the case and the results are ok (RESULT_OK is a constant), it will get the data passed by the intent. In this case, it used the `getData()` method which returns the URI that the intent is operating on. The URI is then turned into String and displayed in EditText.
+
+5. open NoteEditingActivity.java, and make some changes so that the class body looks like the following:
+
+ ```java
+ EditText editText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_note_editing);
+ editText = (EditText) findViewById(R.id.inputNote);
+ }
+
+ public void onDoneClick(View v) {
+ Intent intent = new Intent();
+ Uri uri = Uri.parse(editText.getText().toString());
+ intent.setData(uri);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ ```
+
+The method `onDoneClick()` works in pair with `startActivityForResult()` in a sense that it set the results i.e. Intent and close the current activity. The idea is that upon user click, whatever typed in the EditText will be passed to the calling Activity.
+
+Finally, open DisplayActivity.java. When you first look at it, the class is full of methods and comments automatically generated by the system. Don't be scared. Concentrate on the lifecycle callbacks for the moment. The idea is that in this Activity all toolbar/button etc. will be displayed for a short time, and then all these will go away apart from the TextView occupying the whole screen. (You'll learn all these later on during the module.)
+
+Do the following to make it possible to collect data passed from MainActivity.
+
+1. Insert a TextView declaration into the class `private TextView textView;`.
+2. Insert the following into the `onCreate()` method
+
+ ```java
+ textView = (TextView) findViewById(R.id.fullscreen_content);
+ StringBuilder messageFromActivity1 = new StringBuilder();
+ Intent intent = getIntent();
+ Bundle bundle = intent.getExtras();
+ messageFromActivity1.append("Make: " + intent.getStringExtra(MainActivity.KEY_MAKE) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Year: " + intent.getIntExtra(MainActivity.KEY_YEAR, 0) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Color: " + intent.getStringExtra(MainActivity.KEY_COLOR) + System.getProperty("line.separator"));
+ messageFromActivity1.append("Note: " + bundle.getString(MainActivity.KEY_NOTE) + System.getProperty("line.separator"));
+ textView.setText(messageFromActivity1);
+ ```
+
+ To get the Intent that starts the current Activity you'll need to call the `getIntent()` method. The opposite of `putExtra()` to add data into Intents is to use `getStringExtra()` or `getIntExtra()` methods to retrieve the data. To do that, you'll need to know the key for these different values as in key-values pairs mentioned previously.
+
+3. Insert the following function into the DisplayActivity.java, and associate this function with the 'dummy_button' in activity_display.xml.
+
+ ```java
+ public void onReturnClick(View v){
+ finish();
+ }
+ ```
+
+4. In order to enable intent-filters so that MainActivity can start the DispalyActivity by calling the Action name, it is necessary to define the Action in the manifest. Insert the following intent-filter into the manifest file so that the 'activity' tag for DisplayActivity becomes the following
+
+ ```xml
+
+
+
+
+
+
+
+ ```
+
+ Here Action is barely a String. You must also have a DEFAULT category. Read documents directly quoted from [Google](http://developer.android.com/guide/components/intents-filters.html): "In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare this category in your intent filter, no implicit intents will resolve to your activity."
+
+Now if you run the app, you'll see something like this:
+
+
+
+If know you click 'Write notes', it'll take you to a second Activity where all the notes you type will be automatically saved.
+
+
+
+If you hit 'Display' you'll see all the info about your car. If you touch anywhere on the screen, it'll give you the toolbar etc. for a short while.
+
+
+
+
+## Lab 2 Simple and complex view
+
+When you look at your layout files in Design view, the Palette shows everything that is available to you. You have only used a small fraction so far. In this second lab, let's explore some more.
+
+### Common controls
+
+Google has listed some commonly used widgets and refers to those collectively as [Common Controls](https://developer.android.com/guide/topics/ui/controls.html). In the following exercise, you'll see how to include these in your layouts and how to connect those with Java code. If you have finished the previous lab, duplicate the project folder and rename it MyActivities2.
+
+
+
+1. Download the ['mode edit' icon](https://material.io/icons/#ic_mode_edit) from Google, and add to the resources of your project.
+
+ 
+
+2. Download a photo of any 'vehicle' and copy it to res/drawable folder (create one if necessary) such as 'bike.jpg'.
+3. Insert the following into strings.xml file to get ready a string array
+
+ ```xml
+
+ Volvo
+ Mini
+ Volkswagen
+
+ ```
+4. Next, Open activity_main.xml. You need to put some more controls on the app screen. The ones you need are: Spinner, Switch, RadioButtons, CheckBoxes and an ImageButton. Without looking at the XML code below, try to drag/drop and rearrange so that your screen looks like this:
+
+ 
+
+ If you get stuck, compare yours with the code below, and try to understand (with the help of Google) why it is the case. Try not to just copy/paste.
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+ Spend some time with this layout file, and try to understand different attributes associated with different widgets. Here 'Make' is a drop-down menu Spinner and 'Fuel type' is a Switch. These two are new and worth spending some time on. You also have here some radio buttons and checkboxes, which are pretty straightforward. Note the 'node edit' is an ImageButton, which is also new.
+
+5. Insert/remove some variable declarations into/from the MainActivity class to accommodate layout element changes. What you want to do is to have all input fields on the graphical layout as member variables of the class. You also need a couple more virables for later use. After this step, your member variables should look like this:
+
+ ```java
+ public static final String KEY_MAKE = "keyMake";
+ public static final String KEY_Fuel = "keyFuel";
+ public static final String KEY_YEAR = "keyYear";
+ public static final String KEY_COLOR = "keyColor";
+ public static final String KEY_NEW = "keyNew";
+ public static final String KEY_RIGHT_HAND = "keyRightHand";
+ public static final String KEY_NOTE = "keyNote";
+ private static final String TAG_LIFECYCLE = "TagLifecycle";
+ private static final int REQUEST_EDIT = 1234;
+ private static final int REQUEST_DOWNLOAD = 5678;
+
+ private Spinner spinnerMaker;
+ private Switch switchFuel;
+ private EditText editTextYear;
+ private RadioGroup radioGroupColor;
+ private CheckBox checkBoxNew;
+ private CheckBox checkBoxRightHand;
+ private Button buttonImage;
+ private EditText editTextNote;
+
+ private String[] carMaker;
+ private String make;
+ ```
+6. Some of the variables in `onCreate()` will now show red color. This is because the declarations of those variables were removed. These red-colored lines can be safely removed. Instead, you need to initialize member variables declared previously. After this step, your `onCreate()` method should look like the following:
+
+ ```java
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Log.d(TAG_LIFECYCLE, "In the onCreate() event");
+
+ spinnerMaker = (Spinner) findViewById(R.id.spinnerMake);
+ switchFuel = (Switch) findViewById(R.id.switchFuel);
+ editTextYear = (EditText) findViewById(R.id.inputYear);
+ radioGroupColor = (RadioGroup) findViewById(R.id.radioColor);
+ checkBoxNew = (CheckBox) findViewById(R.id.isNew);
+ checkBoxRightHand = (CheckBox) findViewById(R.id.isRightHand);
+ buttonImage = (Button) findViewById(R.id.buttonImage);
+ editTextNote = (EditText) findViewById(R.id.inputNote);
+ carMaker = getResources().getStringArray(R.array.car_maker);
+ }
+ ```
+
+7. Update the `goDisplay()` method so it looks like the following:
+
+ ```java
+ public void goDisplay(View v) {
+ Intent intent = new Intent();
+ intent.setAction("com.example.jianhuayang.myactivities.ThirdActivity");
+ intent.putExtra(KEY_MAKE, make);
+ intent.putExtra(KEY_Fuel, switchFuel.isChecked());
+ intent.putExtra(KEY_YEAR, Integer.parseInt(editTextYear.getText().toString()));
+ Bundle bundle = new Bundle();
+ String color = ((RadioButton) findViewById(radioGroupColor.getCheckedRadioButtonId())).getText().toString();
+ bundle.putString(KEY_COLOR, color);
+ bundle.putBoolean(KEY_NEW, checkBoxNew.isChecked());
+ bundle.putBoolean(KEY_RIGHT_HAND, checkBoxRightHand.isChecked());
+ bundle.putString(KEY_NOTE, editTextNote.getText().toString());
+ intent.putExtras(bundle);
+ startActivity(intent);
+ }
+ ```
+
+ The code above parse the data collected using the app UI and pass them to the next activity. Here, all input-collecting widgets are being used. In fact, CheckBox, RadioButton, Switch, and ToggleButton are all sub-classes of CompoundButton, and share a lot of things in common e.g. methods.
+
+### Spinner and AdapterView
+
+The widgets that haven't been dealt include the Spinner. It takes a separate section for it.
+
+1. Open MainActivity.java and change MainActivity signature so the class implements `AdapterView.OnItemSelectedListener`.
+
+ ```java
+ public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{
+ ```
+
+2. Insert the following into `onCreate()` method
+
+ ```java
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
+ R.array.car_maker, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinnerMaker.setAdapter(adapter);
+ spinnerMaker.setOnItemSelectedListener(this);
+ ```
+
+3. Insert the following methods into the class.
+
+ ```java
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ make = carMaker[position];
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ make = "No maker selected";
+ }
+ ```
+
+ Spinner is a special case of AdapterView. For this type of view, you need to set data source for it, so that the 'adaptor' can combine data with a view. Here `android.R.layout.simple_spinner_item` and `android.R.layout.simple_spinner_dropdown_item` are built-in layouts provided by the system.
+
+ What you need to do to initialize the adapter is that you need to implement two concrete methods `onItemSelected()` and `onNothingSelected`. These two methods provide actions based on which item is being selected.
+
+### ProgressBar and Android threading
+
+What you also want to do for this app is that once you click the 'Download' button it will go to a separate Activity to download an image. The downloaded image can then be passed back to the main activity to be displayed.
+
+1. Create a new Empty Activity and name it DownloadActivity. Open activity_download.xml and change the default layout to vertical LinearLayout. Insert the following XML
+
+ ```xml
+
+
+
+
+
+
+
+ ```
+
+ You haven't seen ProgressBar and ImageView before. As the name suggests, basically ProgressBar show the progress of some jobs as a vertical bar or little circle, and ImageView is a view to hold images.
+
+2. Make changes to DownloadActivity so that it looks like below
+
+ ```java
+ public static final String KEY_DRAWABLE = "keyDrawable";
+
+ private ProgressBar progressBar;
+ private TextView textView;
+ private ImageView imageView;
+ private int progressStatus;
+ private static int staticStatus;
+ private Handler handler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_download);
+
+ progressBar = (ProgressBar) findViewById(R.id.progressBar);
+ textView = (TextView) findViewById(R.id.textView);
+ imageView = (ImageView) findViewById(R.id.imageView);
+ imageView.setVisibility(View.GONE);
+ staticStatus = 0;
+
+ new Thread(new Runnable() {
+ public void run() {
+ while (progressStatus < 100) {
+ progressStatus = doSomeWork();
+ handler.post(new Runnable() {
+ public void run() {
+ progressBar.setProgress(progressStatus);
+ }
+ });
+ }
+ if (progressStatus == 100) {
+ handler.post(new Runnable() {
+ public void run() {
+ progressBar.setVisibility(View.GONE);
+ textView.setVisibility(View.GONE);
+ imageView.setVisibility(View.VISIBLE);
+ imageView.setImageResource(R.drawable.bike);
+ }
+ });
+ }
+ }
+
+ private int doSomeWork() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return ++staticStatus;
+ }
+ }).start();
+ }
+
+ public void onReturnClick(View v) {
+ Intent intent = new Intent();
+ intent.putExtra(KEY_DRAWABLE, R.drawable.bike);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ ```
+
+ The code above is artificial, as you have the image resource already and there's no need to download. However, the key points here are Thread and Handler objects. In Android, your app runs in a special thread called the UI thread. Your layout and animations etc are being rendered using this thread. As you can image, if you run intensive tasks in this thread, it will slow down the display. That is not what your users want to happen. So what you do then is to run heavy tasks in a separate thread. The way to do it is to use **Thread** objects, and define tasks in `run()` method. However, what if you want to pass data back to UI thread to update display? Here comes the **Handler** object, which is a way to bridge background threads with UI element. Note here background thread can access member variables etc. The only thing they are not allowed to do is to update UI. Hence it `post()` new jobs back to UI thread, such as updating visibilities.
+
+3. Go back to MainActivity and insert the following method to respond to a button click.
+
+ ```java
+ public void goDownload(View v) {
+ Intent aIntent = new Intent(this, DownloadActivity.class);
+ startActivityForResult(aIntent, REQUEST_DOWNLOAD);
+ }
+ ```
+
+4. In MainActivity, replace `onActivityResult()` with the following. What happened here is that once you have the drawable ID, you can set the background image of the Download button.
+
+ ```java
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_EDIT && resultCode == RESULT_OK) {
+ editTextNote.setText(data.getData().toString());
+ }
+
+ if (requestCode == REQUEST_DOWNLOAD && resultCode == RESULT_OK) {
+ buttonImage.setText("");
+ buttonImage.setBackgroundResource(data.getIntExtra(DownloadActivity.KEY_DRAWABLE, R.mipmap.ic_launcher));
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ ```
+
+If everything goes well, which it should be, when you go to DownloadActivity and click Download you should see something similar to this
+
+
+
+If you wait a little while, this will turn into
+
+
+
+If you click Done, it'll take you back to the main Activity, like this
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/AdapterViewHierarchy.png b/Week_05_AdapterViews_and_Fragments/.md_images/AdapterViewHierarchy.png
new file mode 100644
index 0000000..ba18043
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/AdapterViewHierarchy.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/HeirarchyOfAdapter.png b/Week_05_AdapterViews_and_Fragments/.md_images/HeirarchyOfAdapter.png
new file mode 100644
index 0000000..fba6824
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/HeirarchyOfAdapter.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/adapters-1.png b/Week_05_AdapterViews_and_Fragments/.md_images/adapters-1.png
new file mode 100644
index 0000000..2250d87
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/adapters-1.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/blank.png b/Week_05_AdapterViews_and_Fragments/.md_images/blank.png
new file mode 100644
index 0000000..2c3449c
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/blank.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/complete_android_fragment_lifecycle.png b/Week_05_AdapterViews_and_Fragments/.md_images/complete_android_fragment_lifecycle.png
new file mode 100644
index 0000000..259990e
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/complete_android_fragment_lifecycle.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/frag_warn.png b/Week_05_AdapterViews_and_Fragments/.md_images/frag_warn.png
new file mode 100644
index 0000000..d5b2def
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/frag_warn.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/grid.png b/Week_05_AdapterViews_and_Fragments/.md_images/grid.png
new file mode 100644
index 0000000..da0b6be
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/grid.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/land.png b/Week_05_AdapterViews_and_Fragments/.md_images/land.png
new file mode 100644
index 0000000..8672bc3
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/land.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/list_res.png b/Week_05_AdapterViews_and_Fragments/.md_images/list_res.png
new file mode 100644
index 0000000..47dc89a
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/list_res.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/listitem.png b/Week_05_AdapterViews_and_Fragments/.md_images/listitem.png
new file mode 100644
index 0000000..24d1629
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/listitem.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/lists.png b/Week_05_AdapterViews_and_Fragments/.md_images/lists.png
new file mode 100644
index 0000000..53cd525
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/lists.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/package.png b/Week_05_AdapterViews_and_Fragments/.md_images/package.png
new file mode 100644
index 0000000..04883f5
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/package.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/panels.png b/Week_05_AdapterViews_and_Fragments/.md_images/panels.png
new file mode 100644
index 0000000..9752620
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/panels.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/photo.png b/Week_05_AdapterViews_and_Fragments/.md_images/photo.png
new file mode 100644
index 0000000..ddb2688
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/photo.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/port.png b/Week_05_AdapterViews_and_Fragments/.md_images/port.png
new file mode 100644
index 0000000..f8117ca
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/port.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/simple.png b/Week_05_AdapterViews_and_Fragments/.md_images/simple.png
new file mode 100644
index 0000000..6fc6667
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/simple.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/static.png b/Week_05_AdapterViews_and_Fragments/.md_images/static.png
new file mode 100644
index 0000000..5373a18
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/static.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/.md_images/todo.png b/Week_05_AdapterViews_and_Fragments/.md_images/todo.png
new file mode 100644
index 0000000..4e27a88
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/.md_images/todo.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/.gitignore b/Week_05_AdapterViews_and_Fragments/MyFragments/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/codeStyles/Project.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/gradle.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/gradle.xml
new file mode 100644
index 0000000..76a4349
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/gradle.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/misc.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/misc.xml
new file mode 100644
index 0000000..4872587
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/modules.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/modules.xml
new file mode 100644
index 0000000..e400e3f
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/runConfigurations.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/.gitignore b/Week_05_AdapterViews_and_Fragments/MyFragments/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/build.gradle b/Week_05_AdapterViews_and_Fragments/MyFragments/app/build.gradle
new file mode 100644
index 0000000..40e1c11
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.jianhuayang.myfragments"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ compile 'com.android.support:support-v4:26.+'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/proguard-rules.pro b/Week_05_AdapterViews_and_Fragments/MyFragments/app/proguard-rules.pro
new file mode 100644
index 0000000..6d3585e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/jianhuayang/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/androidTest/java/com/example/jianhuayang/myfragments/ExampleInstrumentedTest.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/androidTest/java/com/example/jianhuayang/myfragments/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..87dc317
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/androidTest/java/com/example/jianhuayang/myfragments/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.jianhuayang.myfragments;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.jianhuayang.myfragments", appContext.getPackageName());
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/AndroidManifest.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f3263c6
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/DetailsFragment.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/DetailsFragment.java
new file mode 100644
index 0000000..9f4d90e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/DetailsFragment.java
@@ -0,0 +1,50 @@
+package com.example.jianhuayang.myfragments;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.example.jianhuayang.myfragments.data.Candidates;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class DetailsFragment extends Fragment {
+
+
+ public static final String POSITION = "position";
+
+ public DetailsFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ Bundle args = getArguments();
+ if (args != null) {
+ int position = args.getInt(POSITION);
+ TextView description = (TextView) getActivity().findViewById(R.id.description);
+ description.setText(Candidates.candidateDetails[position]);
+ ImageView imageView = (ImageView) getActivity().findViewById(R.id.imageView);
+ imageView.setImageResource(Candidates.candidatePhotos[position]);
+ } else {
+ TextView description = (TextView) getActivity().findViewById(R.id.description);
+ description.setText("Click on the names on the left to see details");
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_details, container, false);
+ }
+
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/DynamicActivity.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/DynamicActivity.java
new file mode 100644
index 0000000..042b7da
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/DynamicActivity.java
@@ -0,0 +1,30 @@
+package com.example.jianhuayang.myfragments;
+
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.AppCompatActivity;
+
+import layout.BlankFragment;
+import layout.BlankFragment2;
+
+public class DynamicActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ BlankFragment frag1 = new BlankFragment();
+ fragmentTransaction.replace(R.id.activity_dynamic, frag1);
+ } else {
+ BlankFragment2 frag2 = new BlankFragment2();
+ fragmentTransaction.replace(R.id.activity_dynamic, frag2);
+ }
+ fragmentTransaction.commit();
+ setContentView(R.layout.activity_dynamic);
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/ItemFragment.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/ItemFragment.java
new file mode 100644
index 0000000..c921816
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/ItemFragment.java
@@ -0,0 +1,61 @@
+package com.example.jianhuayang.myfragments;
+
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.ListFragment;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.example.jianhuayang.myfragments.data.Candidates;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class ItemFragment extends ListFragment implements AdapterView.OnItemClickListener {
+
+
+ public ItemFragment() {
+ // Required empty public constructor
+ }
+
+
+// @Override
+// public View onCreateView(LayoutInflater inflater, ViewGroup container,
+// Bundle savedInstanceState) {
+// TextView textView = new TextView(getActivity());
+// textView.setText(R.string.hello_blank_fragment);
+// return textView;
+// }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ setListAdapter(new ArrayAdapter(getActivity(),
+ android.R.layout.simple_list_item_1, android.R.id.text1, Candidates.candidateNames));
+// getListView().setOnItemClickListener(this);
+ if (getActivity() instanceof ListFragmentActivity) {
+ getListView().setOnItemClickListener(this);
+ }
+
+ if (getActivity() instanceof MultiPanelActivity) {
+ getListView().setOnItemClickListener((MultiPanelActivity) getActivity());
+ }
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Toast.makeText(getActivity(), Candidates.candidateNames[position], Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ getListView().setSelector(android.R.color.darker_gray);
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/ListFragmentActivity.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/ListFragmentActivity.java
new file mode 100644
index 0000000..1af84c6
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/ListFragmentActivity.java
@@ -0,0 +1,15 @@
+package com.example.jianhuayang.myfragments;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+public class ListFragmentActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_list_fragment);
+ getSupportFragmentManager().beginTransaction().add(R.id.activity_list_fragment, new ItemFragment()).commit();
+
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/MainActivity.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/MainActivity.java
new file mode 100644
index 0000000..ef71c58
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/MainActivity.java
@@ -0,0 +1,31 @@
+package com.example.jianhuayang.myfragments;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+
+ public void onButtonClick(View v){
+
+ switch (v.getId()){
+ case R.id.dynamicFragments:
+ startActivity(new Intent(this, DynamicActivity.class));
+ break;
+ case R.id.listFragment:
+ startActivity(new Intent(this, ListFragmentActivity.class));
+ break;
+ case R.id.multipanel:
+ startActivity(new Intent(this, MultiPanelActivity.class));
+ break;
+ }
+
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/MultiPanelActivity.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/MultiPanelActivity.java
new file mode 100644
index 0000000..dc0d26c
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/MultiPanelActivity.java
@@ -0,0 +1,39 @@
+package com.example.jianhuayang.myfragments;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.AdapterView;
+
+public class MultiPanelActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_multi_panel);
+ if (savedInstanceState == null){
+ getSupportFragmentManager().beginTransaction().add(R.id.fragmentLeft, new
+ ItemFragment()).commit();
+ getSupportFragmentManager().beginTransaction().add(R.id.fragmentRight, new
+ DetailsFragment()).commit();
+ }
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ DetailsFragment detailsFragmentNew = new DetailsFragment();
+ Bundle bundle = new Bundle();
+ bundle.putInt(DetailsFragment.POSITION, position);
+ detailsFragmentNew.setArguments(bundle);
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ fragmentTransaction.replace(R.id.fragmentRight, detailsFragmentNew);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ // If article frag is available, we're in two-pane layout...
+ // Call a method in the ArticleFragment to update its content
+ // ((TextView) findViewById(R.id.description)).setText(Candidates.candidateDetails[position]);
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/data/Candidates.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/data/Candidates.java
new file mode 100644
index 0000000..506e211
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/com/example/jianhuayang/myfragments/data/Candidates.java
@@ -0,0 +1,40 @@
+package com.example.jianhuayang.myfragments.data;
+
+import com.example.jianhuayang.myfragments.R;
+
+/**
+ * Created by jianhuayang on 31/10/2017.
+ */
+
+public class Candidates {
+ public static final String[] candidateNames = {
+ "Hillary Clinton",
+ "Bernie Sanders",
+ "Martin O'Malley",
+ "Lincoln Chafee",
+ "Donald Trump",
+ "Ben Carson",
+ "Marco Rubio",
+ "Jeb Bush"
+ };
+ public static final String[] candidateDetails = {
+ "Former US Secretary of State Hillary Clinton (New York)",
+ "US Senator Bernie Sanders (Vermont)",
+ "Former Governor Martin O\'Malley (Maryland)",
+ "Former Governor Lincoln Chafee (Rhode Island)",
+ "Businessman Donald Trump (New York)",
+ "Dr. Ben Carson (Florida)",
+ "US Senator Marco Rubio (Florida)",
+ "Former Governor Jeb Bush (Florida)",
+ };
+ public static final int[] candidatePhotos = {
+ R.drawable.clinton,
+ R.drawable.sanders,
+ R.drawable.omalley,
+ R.drawable.chafee,
+ R.drawable.trump,
+ R.drawable.carson,
+ R.drawable.rubio,
+ R.drawable.bush
+ };
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/layout/BlankFragment.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/layout/BlankFragment.java
new file mode 100644
index 0000000..4595ee7
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/layout/BlankFragment.java
@@ -0,0 +1,30 @@
+package layout;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.example.jianhuayang.myfragments.R;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class BlankFragment extends Fragment {
+
+
+ public BlankFragment() {
+ // Required empty public constructor
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_blank, container, false);
+ }
+
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/layout/BlankFragment2.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/layout/BlankFragment2.java
new file mode 100644
index 0000000..c301afa
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/java/layout/BlankFragment2.java
@@ -0,0 +1,30 @@
+package layout;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.example.jianhuayang.myfragments.R;
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class BlankFragment2 extends Fragment {
+
+
+ public BlankFragment2() {
+ // Required empty public constructor
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_blank2, container, false);
+ }
+
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/bush.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/bush.jpg
new file mode 100644
index 0000000..76a5c24
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/bush.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/carson.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/carson.jpg
new file mode 100644
index 0000000..535a2ea
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/carson.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/chafee.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/chafee.jpg
new file mode 100644
index 0000000..a2f04c1
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/chafee.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/clinton.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/clinton.jpg
new file mode 100644
index 0000000..ab248f3
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/clinton.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/omalley.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/omalley.jpg
new file mode 100644
index 0000000..074db96
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/omalley.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/rubio.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/rubio.jpg
new file mode 100644
index 0000000..5574335
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/rubio.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/sanders.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/sanders.jpg
new file mode 100644
index 0000000..772b27f
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/sanders.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/trump.jpg b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/trump.jpg
new file mode 100644
index 0000000..764d0bf
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/drawable/trump.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_dynamic.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_dynamic.xml
new file mode 100644
index 0000000..4e7e9f6
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_dynamic.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_list_fragment.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_list_fragment.xml
new file mode 100644
index 0000000..7972b2b
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_list_fragment.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_main.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..4c840f8
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_multi_panel.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_multi_panel.xml
new file mode 100644
index 0000000..0d2d541
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/activity_multi_panel.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_blank.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_blank.xml
new file mode 100644
index 0000000..161ce87
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_blank.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_blank2.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_blank2.xml
new file mode 100644
index 0000000..e170380
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_blank2.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_details.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_details.xml
new file mode 100644
index 0000000..83b1b6f
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/layout/fragment_details.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/colors.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/strings.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f3487ac
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ My Fragments
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/styles.xml b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/test/java/com/example/jianhuayang/myfragments/ExampleUnitTest.java b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/test/java/com/example/jianhuayang/myfragments/ExampleUnitTest.java
new file mode 100644
index 0000000..9683175
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/app/src/test/java/com/example/jianhuayang/myfragments/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jianhuayang.myfragments;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/build.gradle b/Week_05_AdapterViews_and_Fragments/MyFragments/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/gradle.properties b/Week_05_AdapterViews_and_Fragments/MyFragments/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/gradle/wrapper/gradle-wrapper.jar b/Week_05_AdapterViews_and_Fragments/MyFragments/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/gradle/wrapper/gradle-wrapper.properties b/Week_05_AdapterViews_and_Fragments/MyFragments/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f658c82
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Oct 31 09:58:19 GMT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/gradlew b/Week_05_AdapterViews_and_Fragments/MyFragments/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/gradlew.bat b/Week_05_AdapterViews_and_Fragments/MyFragments/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments/settings.gradle b/Week_05_AdapterViews_and_Fragments/MyFragments/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/.gitignore b/Week_05_AdapterViews_and_Fragments/MyFragments2/.gitignore
new file mode 100644
index 0000000..fd45b12
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches/build_file_checksums.ser
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/codeStyles/Project.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/gradle.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/misc.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/misc.xml
new file mode 100644
index 0000000..7bfef59
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/runConfigurations.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/.gitignore b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/build.gradle b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/build.gradle
new file mode 100644
index 0000000..0fe212b
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/build.gradle
@@ -0,0 +1,29 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.example.ab5603.myfragments"
+ minSdkVersion 15
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.android.support:design:28.0.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/proguard-rules.pro b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/androidTest/java/com/example/ab5603/myfragments/ExampleInstrumentedTest.java b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/androidTest/java/com/example/ab5603/myfragments/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..8c6231b
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/androidTest/java/com/example/ab5603/myfragments/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.ab5603.myfragments;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.ab5603.myfragments", appContext.getPackageName());
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/AndroidManifest.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..391f5d9
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/java/com/example/ab5603/myfragments/MainActivity.java b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/java/com/example/ab5603/myfragments/MainActivity.java
new file mode 100644
index 0000000..9a5e18f
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/java/com/example/ab5603/myfragments/MainActivity.java
@@ -0,0 +1,52 @@
+package com.example.ab5603.myfragments;
+
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_settings) {
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..1f6bb29
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/drawable/ic_launcher_background.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/layout/activity_main.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..eed4d89
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/layout/content_main.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/layout/content_main.xml
new file mode 100644
index 0000000..3fc2170
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/layout/content_main.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/menu/menu_main.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..7a85a93
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,10 @@
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/colors.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..69b2233
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #008577
+ #00574B
+ #D81B60
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/dimens.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..59a0b0c
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/dimens.xml
@@ -0,0 +1,3 @@
+
+ 16dp
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/strings.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..cb1e4a3
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ My Fragments
+ Settings
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/styles.xml b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..545b9c6
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/test/java/com/example/ab5603/myfragments/ExampleUnitTest.java b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/test/java/com/example/ab5603/myfragments/ExampleUnitTest.java
new file mode 100644
index 0000000..9232604
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/app/src/test/java/com/example/ab5603/myfragments/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.ab5603.myfragments;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/build.gradle b/Week_05_AdapterViews_and_Fragments/MyFragments2/build.gradle
new file mode 100644
index 0000000..8d3ef8e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/build.gradle
@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.2.1'
+
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle.properties b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle.properties
new file mode 100644
index 0000000..82618ce
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle.properties
@@ -0,0 +1,15 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle/wrapper/gradle-wrapper.jar b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle/wrapper/gradle-wrapper.properties b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9a4163a
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/gradlew b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/gradlew.bat b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_05_AdapterViews_and_Fragments/MyFragments2/settings.gradle b/Week_05_AdapterViews_and_Fragments/MyFragments2/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyFragments2/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.gitignore b/Week_05_AdapterViews_and_Fragments/MyLists/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.idea/compiler.xml b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.idea/copyright/profiles_settings.xml b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.idea/gradle.xml b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.idea/misc.xml b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/misc.xml
new file mode 100644
index 0000000..5d19981
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.idea/modules.xml b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/modules.xml
new file mode 100644
index 0000000..a1edcd6
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/.idea/runConfigurations.xml b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/.gitignore b/Week_05_AdapterViews_and_Fragments/MyLists/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/build.gradle b/Week_05_AdapterViews_and_Fragments/MyLists/app/build.gradle
new file mode 100644
index 0000000..e0475db
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.yang.mylists"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/proguard-rules.pro b/Week_05_AdapterViews_and_Fragments/MyLists/app/proguard-rules.pro
new file mode 100644
index 0000000..3048997
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/yang/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/androidTest/java/com/example/yang/mylists/ExampleInstrumentedTest.java b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/androidTest/java/com/example/yang/mylists/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..27ba9f8
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/androidTest/java/com/example/yang/mylists/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.yang.mylists;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.yang.mylists", appContext.getPackageName());
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/AndroidManifest.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..0a79aa2
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/Candidate.java b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/Candidate.java
new file mode 100644
index 0000000..1e20727
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/Candidate.java
@@ -0,0 +1,34 @@
+package com.example.yang.mylists;
+
+/**
+ * Created by jianhuayang on 30/10/2017.
+ */
+
+public class Candidate {
+ private String name;
+ private String detail;
+ private int photo;
+
+ public Candidate(String name, String detail, int photo) {
+ this.name = name;
+ this.detail = detail;
+ this.photo = photo;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDetail() {
+ return detail;
+ }
+
+ public int getPhoto() {
+ return photo;
+ }
+
+ @Override
+ public String toString() {
+ return detail;
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/CandidateAdapter.java b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/CandidateAdapter.java
new file mode 100644
index 0000000..10b686a
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/CandidateAdapter.java
@@ -0,0 +1,56 @@
+package com.example.yang.mylists;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Created by jianhuayang on 30/10/2017.
+ */
+
+public class CandidateAdapter extends ArrayAdapter {
+
+ private int resource;
+ private ArrayList candidates;
+ private Context context;
+
+ public CandidateAdapter(Context context, int resource, ArrayList candidates) {
+ super(context, resource, candidates);
+ this.resource = resource;
+ this.candidates = candidates;
+ this.context = context;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ try {
+ if (v == null) {
+ LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = layoutInflater.inflate(resource, parent, false);
+ }
+
+ ImageView imageView = (ImageView) v.findViewById(R.id.imageView);
+ TextView textViewName = (TextView) v.findViewById(R.id.textViewName);
+ TextView textViewDetail = (TextView) v.findViewById(R.id.textViewDetail);
+
+ imageView.setImageResource(candidates.get(position).getPhoto());
+ textViewName.setText(candidates.get(position).getName());
+ textViewDetail.setText(candidates.get(position).getDetail());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ e.getCause();
+ }
+ return v;
+ }
+
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/MainActivity.java b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/MainActivity.java
new file mode 100644
index 0000000..2bc4b9e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/MainActivity.java
@@ -0,0 +1,50 @@
+package com.example.yang.mylists;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class MainActivity extends AppCompatActivity {
+ private ListView listView;
+ private String[] candidateNames;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ candidateNames = getResources().getStringArray(R.array.candidateNames);
+
+ listView = (ListView) findViewById(R.id.listViewSimple);
+ ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, candidateNames);
+ listView.setAdapter(arrayAdapter);
+ listView.setOnItemClickListener(
+
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Toast.makeText(getBaseContext(), candidateNames[position] + ", seriously?", Toast.LENGTH_SHORT).show();
+ }
+ }
+ );
+
+ List candidateNamesNew = new ArrayList(Arrays.asList(candidateNames));
+ ArrayAdapter arrayAdapterNew = new ArrayAdapter(this, android.R.layout
+ .simple_list_item_1, candidateNamesNew);
+ listView.setAdapter(arrayAdapterNew);
+ arrayAdapterNew.add("New Someone");
+ arrayAdapter.notifyDataSetInvalidated();
+ }
+ public void onButtonClick(View v){
+ startActivity(new Intent(this, PhotoListActivity.class));
+ }
+
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/PhotoListActivity.java b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/PhotoListActivity.java
new file mode 100644
index 0000000..d67fc31
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/java/com/example/yang/mylists/PhotoListActivity.java
@@ -0,0 +1,59 @@
+package com.example.yang.mylists;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+public class PhotoListActivity extends AppCompatActivity {
+
+ private ListView listView;
+ private String[] candidateNames;
+ private String[] candidateDetails;
+ public static int[] candidatePhotos = {
+ R.drawable.clinton,
+ R.drawable.sanders,
+ R.drawable.omalley,
+ R.drawable.chafee,
+ R.drawable.trump,
+ R.drawable.carson,
+ R.drawable.rubio,
+ R.drawable.bush
+ };
+ private ArrayList candidates = new ArrayList<>();
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_photo_list);
+
+ candidateNames = getResources().getStringArray(R.array.candidateNames);
+ candidateDetails = getResources().getStringArray(R.array.candidateDetails);
+ generateCandidates();
+
+ listView = (ListView) findViewById(R.id.listViewComplex);
+ listView.setAdapter(new CandidateAdapter(this, R.layout.list_item, candidates));
+ listView.setOnItemClickListener(
+
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+
+ Toast.makeText(getBaseContext(), "You clicked " + candidates.get(position), Toast.LENGTH_SHORT).show();
+ }
+ }
+ );
+ }
+
+ private void generateCandidates() {
+
+ for (int i = 0; i < candidatePhotos.length; i++) {
+ candidates.add(new Candidate(candidateNames[i], candidateDetails[i], candidatePhotos[i]));
+ }
+ }
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/bush.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/bush.jpg
new file mode 100644
index 0000000..76a5c24
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/bush.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/carson.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/carson.jpg
new file mode 100644
index 0000000..535a2ea
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/carson.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/chafee.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/chafee.jpg
new file mode 100644
index 0000000..a2f04c1
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/chafee.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/clinton.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/clinton.jpg
new file mode 100644
index 0000000..ab248f3
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/clinton.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/omalley.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/omalley.jpg
new file mode 100644
index 0000000..074db96
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/omalley.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/rubio.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/rubio.jpg
new file mode 100644
index 0000000..5574335
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/rubio.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/sanders.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/sanders.jpg
new file mode 100644
index 0000000..772b27f
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/sanders.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/trump.jpg b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/trump.jpg
new file mode 100644
index 0000000..764d0bf
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/drawable/trump.jpg differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/activity_main.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..ca93007
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/activity_photo_list.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/activity_photo_list.xml
new file mode 100644
index 0000000..2bc0983
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/activity_photo_list.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/list_item.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/list_item.xml
new file mode 100644
index 0000000..c6df075
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/layout/list_item.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/colors.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/strings.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..55e0118
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/strings.xml
@@ -0,0 +1,24 @@
+
+ My Lists
+
+ Hillary Clinton
+ Bernie Sanders
+ Martin O\'Malley
+ Lincoln Chafee
+ Donald Trump
+ Ben Carson
+ Marco Rubio
+ Jeb Bush
+
+
+
+ Former US Secretary of State Hillary Clinton (New York)
+ US Senator Bernie Sanders (Vermont)
+ Former Governor Martin O\'Malley (Maryland)
+ Former Governor Lincoln Chafee (Rhode Island)
+ Businessman Donald Trump (New York)
+ Dr. Ben Carson (Florida)
+ US Senator Marco Rubio (Florida)
+ Former Governor Jeb Bush (Florida)
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/styles.xml b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/app/src/test/java/com/example/yang/mylists/ExampleUnitTest.java b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/test/java/com/example/yang/mylists/ExampleUnitTest.java
new file mode 100644
index 0000000..e525ae8
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/app/src/test/java/com/example/yang/mylists/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.yang.mylists;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/build.gradle b/Week_05_AdapterViews_and_Fragments/MyLists/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/gradle.properties b/Week_05_AdapterViews_and_Fragments/MyLists/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/gradle/wrapper/gradle-wrapper.jar b/Week_05_AdapterViews_and_Fragments/MyLists/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_05_AdapterViews_and_Fragments/MyLists/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/gradle/wrapper/gradle-wrapper.properties b/Week_05_AdapterViews_and_Fragments/MyLists/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..a52d5fe
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Oct 30 14:08:49 GMT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/gradlew b/Week_05_AdapterViews_and_Fragments/MyLists/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/gradlew.bat b/Week_05_AdapterViews_and_Fragments/MyLists/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_05_AdapterViews_and_Fragments/MyLists/settings.gradle b/Week_05_AdapterViews_and_Fragments/MyLists/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/MyLists/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_05_AdapterViews_and_Fragments/README.md b/Week_05_AdapterViews_and_Fragments/README.md
new file mode 100644
index 0000000..9265746
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/README.md
@@ -0,0 +1,795 @@
+# AdapterViews and Fragments
+
+What do you do if the app needs to handle data of a large quantity or dynamically generated? Do you put say 200 student records in TextViews one after another? Obviously, the answer is no here. Let's find out how to do it properly.
+
+## Lab 1 AdapterViews
+
+Spinners you looked at previously is a special case i.e. subclass of AdapterView. In order to get it work, yous had to combine three elements: the View itself (Spinner), the data resource which is typically a Collection (interface), an Adaptor that binds every *single entry* in the Collection with its layout.
+
+
+
+
+Now let's look at some more subclasses of AdapterView.
+
+### Simple ListView
+
+Using default options, create a new project and name it 'My Lists'. Then, follow steps below to create a simple list:
+
+1. First of all, define some data to play with. Insert the following into string.xml.
+
+ ```xml
+
+ Hillary Clinton
+ Bernie Sanders
+ Martin O\'Malley
+ Lincoln Chafee
+ Donald Trump
+ Ben Carson
+ Marco Rubio
+ Jeb Bush
+
+
+
+ Former US Secretary of State Hillary Clinton (New York)
+ US Senator Bernie Sanders (Vermont)
+ Former Governor Martin O\'Malley (Maryland)
+ Former Governor Lincoln Chafee (Rhode Island)
+ Businessman Donald Trump (New York)
+ Dr. Ben Carson (Florida)
+ US Senator Marco Rubio (Florida)
+ Former Governor Jeb Bush (Florida)
+
+ ```
+2. Open activity_main.xml, delete the default TextView and drag/drop a ListView from Containers sub-group in Palette. In text mode, rearrange XML so it looks like this
+
+ ```xml
+
+ ```
+
+3. Open MainActivity.java, insert the following declarations:
+
+ ```java
+ private ListView listView;
+ private String[] candidateNames;
+ ```
+
+4. In MainActivity.java, insert the following into the `onCreate()` method
+
+ ```java
+ candidateNames = getResources().getStringArray(R.array.candidateNames);
+
+ listView = (ListView) findViewById(R.id.listViewSimple);
+ ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, candidateNames);
+ listView.setAdapter(arrayAdapter);
+ listView.setOnItemClickListener(
+
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Toast.makeText(getBaseContext(), candidateNames[position] + ", seriously?", Toast.LENGTH_SHORT).show();
+ }
+ }
+ );
+ ```
+
+ What the code above does is to associate the ListView declared in the layout file with the data (string array) declared in string resource. ArrayAdapter takes three parameters: context, a layout resource for a single element of data, and the data. Here `android.R.layout.simple_list_item_1` is a system-defined resource layout file that contains only one TextView. You can define you own resource files as you see later on.
+
+ > [simple_list_item_1](https://github.com/android/platform_frameworks_base/blob/master/core/res/res/layout/simple_list_item_1.xml) on Github.
+
+ Inside `setOnItemClickListener()` block is an anonymous inner class. There're two ways of defining an onClickListener, one is to do `public void doSomething(View v)` and then associate with View's `onClick` attribute in XML, the other is what you see here. Note here instead of declaring `View.onClick()` for Buttons, it declared `AdapterView.OnItemClickListener()` wich is specific for AdapterViews. Here 'parent' is the parent view of single data entry, in our case is the ListView, view is the View being clicked, position is the 'index' of current view within the adapter, id is the row id the data entry.
+
+ The question mark inside angle brackets is Java generic wildcard, which basically means the type of parent passed into the method is an AdapterView of any type.
+
+If you run the app, what you'll see is something like this:
+
+
+
+The following code can be added after the `setOnItemClickListener()` block, but still within `onCreate()`method:
+
+```java
+List candidateNamesNew = new ArrayList(Arrays.asList(candidateNames));
+ArrayAdapter arrayAdapterNew = new ArrayAdapter(this, android.R.layout
+ .simple_list_item_1, candidateNamesNew);
+listView.setAdapter(arrayAdapterNew);
+arrayAdapterNew.add("New Someone");
+arrayAdapter.notifyDataSetInvalidated();
+```
+
+Have a look at the code above, and try to answer the following questions:
+
+* Why is it necessary to convert string array to array list?
+* How does array adapter update the actual dataset i.e. candidate data?
+* What is the purpose of `notifyDataSetInvalidated()`?
+
+### Complex ListView
+
+Simple ListView is useful for displaying data that can be converted to strings in easy steps. But if you want to have fine control of the presentation of single entries in your ListView, you need to provide customized layout files for your adapter. In this way, you'll make it a 'complex ListView'.
+
+1. First of all, download some images to use later on. Click on [this link](https://github.coventry.ac.uk/300CEM-1718SEPJAN/TEACHING-MATERIALS/blob/master/Additional_resources/candidates_photos.zip) to go to GitHub page and then click 'View Raw' to download some images of US presidential election candidates. Add those to your res/drawable resources folder.
+
+2. Create a new Java class called Candidate and insert the following
+
+ ```java
+ private String name;
+ private String detail;
+ private int photo;
+
+ public Candidate(String name, String detail, int photo) {
+ this.name = name;
+ this.detail = detail;
+ this.photo = photo;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDetail() {
+ return detail;
+ }
+
+ public int getPhoto() {
+ return photo;
+ }
+
+ @Override
+ public String toString() {
+ return detail;
+ }
+ ```
+
+3. Create a new layout resource file by right-clicking on the layout folder and select New ==> Layout resource file. Name it list_item.xml.
+
+ 
+
+ Change the default orientation of the container LinearLayout from `vertical` to `horizontal`, and insert the following within the LinearLayout
+
+ ```xml
+
+
+
+
+
+
+
+
+
+ ```
+
+ At the moment, your preview window should look like below. This is the layout for a single item in your list.
+
+ 
+
+4. Create a new activity using the 'Empty Activity' template and name it PhotoListActivity. Open activity_photo_list.xml, insert the following into the container RelativeLayout:
+
+ ```xml
+
+
+
+ ```
+
+ This layout is very similar to the simple list example. The only difference is that it has an additional TextView above ListView.
+
+5. In PhotoListActivity.java, add the following class member variable declaration/initialization.
+
+ ```java
+ private ListView listView;
+ private String[] candidateNames;
+ private String[] candidateDetails;
+ public static int[] candidatePhotos = {
+ R.drawable.clinton,
+ R.drawable.sanders,
+ R.drawable.omalley,
+ R.drawable.chafee,
+ R.drawable.trump,
+ R.drawable.carson,
+ R.drawable.rubio,
+ R.drawable.bush
+ };
+ private ArrayList candidates = new ArrayList<>();
+ ```
+
+ Note in the code above an array of integers is declared for drawable resources. (Why is the type int?)
+
+6. Insert String array initialization into the `onCreate()` method, just below `setContentView()`, so your `onCreate()` becomes
+
+ ```java
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_photo_list);
+
+ candidateNames = getResources().getStringArray(R.array.candidateNames);
+ candidateDetails = getResources().getStringArray(R.array.candidateDetails);
+ generateCandidates();
+ ```
+
+ Insert the following as a class method. This is to create a function that initializes the ArrayList for Candidate class.
+
+ ```java
+ private void generateCandidates() {
+
+ for (int i = 0; i < candidatePhotos.length; i++) {
+ candidates.add(new Candidate(candidateNames[i], candidateDetails[i], candidatePhotos[i]));
+ }
+ }
+ ```
+
+7. Insert the following code into `onCreate()` method
+
+ ```java
+ listView = (ListView) findViewById(R.id.listViewComplex);
+ listView.setAdapter(new CandidateAdapter(this, R.layout.list_item, candidates));
+ listView.setOnItemClickListener(
+
+ new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+
+ Toast.makeText(getBaseContext(), "You clicked " + candidates.get(position), Toast.LENGTH_SHORT).show();
+ }
+ }
+ );
+ ```
+
+ The code above initialize a ListView and associates it with a customized Adapter. The onClickListner is the same as in the simple list example. The only thing that is new here is the association of data and ListView through a customized Adapter.
+
+ > CandidateAdapter can be used to add more data to the arraylist e.g. `candidateAdapter.add(candidates.get(0)); candidateAdapter.notifyDataSetInvalidated();` But this requires a 'candidateAdapter' object to be created beforehand.
+
+8. Create a new class called CandidateAdapter. Open the Java file and replace auto-generated class with the following (don't touch the package declaration!)
+
+ ```java
+ public class CandidateAdapter extends ArrayAdapter {
+
+ private int resource;
+ private ArrayList candidates;
+ private Context context;
+
+ public CandidateAdapter(Context context, int resource, ArrayList candidates) {
+ super(context, resource, candidates);
+ this.resource = resource;
+ this.candidates = candidates;
+ this.context = context;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ try {
+ if (v == null) {
+ LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = layoutInflater.inflate(resource, parent, false);
+ }
+
+ ImageView imageView = (ImageView) v.findViewById(R.id.imageView);
+ TextView textViewName = (TextView) v.findViewById(R.id.textViewName);
+ TextView textViewDetail = (TextView) v.findViewById(R.id.textViewDetail);
+
+ imageView.setImageResource(candidates.get(position).getPhoto());
+ textViewName.setText(candidates.get(position).getName());
+ textViewDetail.setText(candidates.get(position).getDetail());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ e.getCause();
+ }
+ return v;
+ }
+
+ }
+ ```
+
+ It's important to understand the code above: the CandidatesAdapter class extends ArrayAdapter of type Candidates. In the constructor, it needs the layout resource name i.e. the file that contains the customized layout XML created earlier. The most important method is `getView()`, where it checks if a convertView (i.e. old view) exists or not. If it doesn’t, it’ll need to inflate it. The reason for doing this is because ListView recycles its rows when they move out of the screen, instead of creating new ones, to save system resources.
+
+ > [How ListView's recycling mechanism works](http://stackoverflow.com/questions/11945563/how-listviews-recycling-mechanism-works)
+
+ There're several different ways of getting an LayoutInflater object:
+
+ * The code above, `LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)`, is from official [documentation](http://developer.android.com/reference/android/view/LayoutInflater.html).
+ * You can use `LayoutInflater inflater = ((Activity)context).getLayoutInflater()`, see an example from [here](http://www.ezzylearning.com/tutorial/customizing-android-listview-items-with-custom-arrayadapter).
+ * You can also use `LayoutInflater inflater = (LayoutInflater) CandidatesAdapter.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)`, see an example from [here](https://github.com/pranayairan/Code-Learn-Android-Example/blob/master/CodeLearnListExample/src/org/codelearn/codelearnlistexample/ListViewWithBaseAdapter.java).
+
+ Note here `v.findViewById()` is different from `findViewById()`. `v.findViewById()` will only find sub views i.e. views being contained by 'v'; whereas `findViewById()` will find anything contained in the Activity.
+
+
+9. Insert the following into activity_main.xml before the ListView
+
+ ```xml
+
+ ```
+
+ You'll see that ListView and Button overlap at the top-left corner of the screen. Change the following attribute of `ListView` to have more space at the top `app:layout_constraintTop_toBottomOf="@+id/complexList"`
+
+10. Open MainActivity.java, insert the following into the class
+
+ ```java
+ public void onButtonClick(View v){
+ startActivity(new Intent(this, PhotoListActivity.class));
+ }
+ ```
+
+If you run the app, click on 'Complex List' button, you'll see the following:
+
+
+
+
+
+### AdapterView hierarchy
+
+You saw ArrayAdapter already. If you Google online examples you'll see more Adapters such as BaseAdapter, ListAdapter, and SimpleAdapter etc. What are the relationships among these?
+
+Basically, ArrayAdapter is the first concrete Adapter in the tree, above it are interfaces and an abstract class. But sometimes people do declare something like `ListAdapter listAdapter = new ArrayAdapter()`, don't be confused.
+
+
+
+
+A similar hierarchy can be drawn for AdapterView and subclasses. Even though those 'collection' Views are named differently, they are in fact closely related to each other.
+
+
+
+
+> Above images are from a [blog](http://www.intertech.com/Blog/android-adapters-adapterviews/) written by Jim White.
+
+## Lab 2 Fragments
+
+Fragment in Android is basically a fraction of your layout. The idea is that Fragments can be reused to suit different screen sizes/orientations.
+
+### Static Fragments
+
+Follow steps below to add static Fragments:
+
+1. Start a new Android Studio project called 'My Fragments' using all default options. Open activity_main.xml, change the default layout to LinearLayout, add `android:orientation` attribute as vertical.
+2. Delete the TextView.
+3. Right-click on the blank area of the Project tool window, select New ==> Fragment ==> Fragment (blank). If the system doesn’t give you the option to create new Fragment, check that if you are under the Android view. In the window that pops up, **uncheck both** 'include fragment factory methods' and 'include interface callbacks'. Use the default name 'BlankFragment' and click Finish.
+4. Repeat the above process for a second time to produce another fragment. In the Configure Component window, name the new fragment 'BlankFragment2', and set the Fragment Layout Name to be 'fragment_blank2'. After this step, your project should contain three java classes and three layout files. The project view of Android Studio should look like this
+
+ 
+
+5. Double click to open fragment_blank.xml. Note the TODO sentence online No.7. This is a nice feature of Android Studio. If you click on the TODO tab at the bottom of the workbench you’ll see that all TODOs are being summarized there.
+
+ 
+
+6. In fragment_blank.xml, change the layout from FrameLayout to LinearLayout, add vertical as orientation. Change the TextView text to 'This is fragment No.1'.
+7. In the LinearLayout opening tag, add `android:background="#00FF00"`.
+
+ > If you are using a Mac, you need to type in key combinations 'alt' + '3' to insert the # sign.
+
+8. Repeat the steps 6 & 7 above for fragment_blank2.xml, i.e. change layout, add orientation, change TextView text to 'This is fragment No.2', and change the background color to be "#ff191e".
+
+9. Open your activity_main.xml, in Design view, scroll down Palette until you see fragment under Layouts sub-group. Drag/drop fragment from Palette onto graphical layout and the system will give you a list of Fragments to choose from. Select BlankFragment and click OK. What you'll see next is that your fragment appears like a narrow line, and the system gives you some warning messages. Click on 'Use @layout/fragment_blank' to continue.
+
+ 
+
+10. In the same way, add BlandFrangment2 onto your layout. In text mode, for each fragment, change layout_height to "0dp" and add the following attribute `android:layout_weight="1"`. Now each fragment will take up approximately half of the screen. (Not exactly because of the padding spaces). Your XML should now look like the following:
+
+ ```xml
+
+
+
+ ```
+
+If you run your app you should have something similar to the one below.
+
+
+
+### Programmatically add the fragment
+
+In the previous example, you added static Fragments into your layout resource file. This is possible, but a more handy way to do it is to add Fragments programmatically.
+
+1. Create an Empty Activity called DynamicActivity.
+2. Open DynamicActivity.java, insert the following into the ConstraintLayout of activity_dynamic.xml:
+
+ ```xml
+ android:id="@+id/activity_dynamic"
+ ```
+
+ Insert the following code into `onCreate()`, just below the `setContentView()` method:
+
+ ```java
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ BlankFragment frag1 = new BlankFragment();
+ fragmentTransaction.replace(R.id.activity_dynamic, frag1);
+ } else {
+ BlankFragment2 frag2 = new BlankFragment2();
+ fragmentTransaction.replace(R.id.activity_dynamic, frag2);
+ }
+ fragmentTransaction.commit();
+ ```
+
+ In order to have Fragments loaded in your Java code, it first created a FragmentManager, which is followed by FragmentTransaction. FragmentManager, as the name suggests, can be used to track Fragments i.e. `findFragmentById()` or `findFragmentByTag()`. It can also be used to pop fragments off the back stack, or register a listener for changes to the back stack. FragmentTransaction is used to manipulate Fragments. It has methods such as `add()`, `remove()`, and `replace()`. To apply the transaction to the activity, you must call `commit()`.
+
+ `getResources().getConfiguration().orientation` is a way to determine screen orientation. Click [here](http://developer.android.com/reference/android/content/res/Configuration.html#orientation) to read the manual on Configuration class. There're other ways to determine screen orientation, e.g. `getWindowManager().getDefaultDisplay().getRotation()`, check it out on [StackOverflow](http://stackoverflow.com/questions/2795833/check-orientation-on-android-phone).
+
+3. Add the following into activity_main.xml, before the first fragment
+
+ ```xml
+
+ ```
+
+4. Insert the following method into MainActivity.java
+
+ ```java
+ public void onButtonClick(View v){
+ startActivity(new Intent(this, DynamicActivity.class));
+ }
+ ```
+
+If you run the app and click the 'Dynamic fragments', you'll have two different Fragments for different orientations.
+
+
+
+
+
+### ListFragment
+
+So far you have only dealt with Fragments that contain static data, you haven't used any of the AdapterViews you learned previously. Let's now move to an example where you combine Fragments with ListView i.e. ListFragments. ListFragment displays a list of items that are managed by an adapter.
+
+1. First of all, you need to have some data to play with. Copy the 8 photos you downloaded for project 'My Lists' into the drawable folder of the current project. The URL is [here](https://github.coventry.ac.uk/300CEM-1718SEPJAN/TEACHING-MATERIALS/blob/master/Additional_resources/candidates_photos.zip).
+2. Right-click on the package name of your project, select New ==> Package. Give it a name of 'data'.
+
+ 
+
+3. Within the 'data' package, create a new class and name it Candidates. Insert the following code into the class
+
+ ```java
+ public static final String[] candidateNames = {
+ "Hillary Clinton",
+ "Bernie Sanders",
+ "Martin O'Malley",
+ "Lincoln Chafee",
+ "Donald Trump",
+ "Ben Carson",
+ "Marco Rubio",
+ "Jeb Bush"
+ };
+ public static final String[] candidateDetails = {
+ "Former US Secretary of State Hillary Clinton (New York)",
+ "US Senator Bernie Sanders (Vermont)",
+ "Former Governor Martin O\'Malley (Maryland)",
+ "Former Governor Lincoln Chafee (Rhode Island)",
+ "Businessman Donald Trump (New York)",
+ "Dr. Ben Carson (Florida)",
+ "US Senator Marco Rubio (Florida)",
+ "Former Governor Jeb Bush (Florida)",
+ };
+ public static final int[] candidatePhotos = {
+ R.drawable.clinton,
+ R.drawable.sanders,
+ R.drawable.omalley,
+ R.drawable.chafee,
+ R.drawable.trump,
+ R.drawable.carson,
+ R.drawable.rubio,
+ R.drawable.bush
+ };
+ ```
+
+ If you see 'R' is highlighted using red underline, you'll need to import the 'R' class. Now it's ready to create a new Fragment.
+
+4. Create a new Fragment using the Blank Fragment template, uncheck the 'Create layout XML' box, also uncheck the two 'include...' checkboxes. Name this fragment ItemFragment. Open ItemFragment.java, replace superclass Fragment with ListFragment, and implement AdapterView.OnItemClickListener. Now your class declaration should look like this
+
+ ```java
+ public class ItemFragment extends ListFragment implements AdapterView.OnItemClickListener
+ ```
+
+ The reason to unchecked 'Create layout XML' box is that ListFragment has a default layout that consists of a single list view. You can manipulate this ListView in Java code.
+
+5. Remove the auto-generated `onCreateView()` method. Insert the following code into the ItemFragment class.
+ ```java
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ setListAdapter(new ArrayAdapter(getActivity(),
+ android.R.layout.simple_list_item_1, android.R.id.text1, Candidates.candidateNames));
+ getListView().setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Toast.makeText(getActivity(), Candidates.candidateNames[position], Toast.LENGTH_SHORT).show();
+ }
+ ```
+
+ Note the `onActivityCreated()` callback method in code above. As you'll see later, there're a few lifecycle callback methods that are specific to fragments. This is one of those. It'll be called when the activity associated with the fragment is created.
+
+6. Create an Empty Activity and name it ListFragmentActivity. In activity_list_fragment.xml, replace the default ConstraintLayout with a vertial LinearLayout. And insert the following:
+
+ ```xml
+ android:id="@+id/activity_list_fragment"
+ ```
+
+7. Open ListFragmentActivity.java, insert the following line of code into `onCreate()`, just below `setContentView()`
+
+ ```java
+ getSupportFragmentManager().beginTransaction().add(R.id.activity_list_fragment, new ItemFragment()).commit();
+ ```
+
+8. Add the following into activity_main.xml, before the first fragment
+
+ ```xml
+
+ ```
+
+9. In MainActivity.java, replace the `onButtonClick()` with the following
+
+ ```java
+ public void onButtonClick(View v){
+
+ switch (v.getId()){
+ case R.id.dynamicFragments:
+ startActivity(new Intent(this, DynamicActivity.class));
+ break;
+ case R.id.listFragment:
+ startActivity(new Intent(this, ListFragmentActivity.class));
+ break;
+ }
+ }
+ ```
+
+
+Now if you run the app and click 'List Fragment' you'll see the following
+
+
+
+### Two-panel layouts
+
+You often see multi-panel layouts in apps such as Gmail. In some of these apps, there's a list panel where you can click and select, and then in the detail panel contents will get updated accordingly. The following exercise teaches you how to do something alike
+
+1. Create a new blank Fragment, uncheck the two 'include...' checkboxes. Name it DetailsFragment. This fragment is going to be used to display candidates details. Open fragment_details.xml, delete the auto-generated TextView and insert the following attribute into FragmentLayout.
+ ```xml
+ android:id="@+id/detailsFrameLayout"
+ ```
+
+ Insert the following widgets into the FragmentLayout
+ ```xml
+
+
+
+
+
+
+ ```
+
+2. Insert the following into DetailsFragment class. What it does here is that it gets any data that passed into the fragment first of all. In a way similar to `getIntent()` for activities, Fragments use `getArguments()`. The argument is typically a Bundle. Depending on if the Bundle is empty, it initializes the views accordingly.
+
+ ```java
+ public static final String POSITION = "position";
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ Bundle args = getArguments();
+ if (args != null) {
+ int position = args.getInt(POSITION);
+ TextView description = (TextView) getActivity().findViewById(R.id.description);
+ description.setText(Candidates.candidateDetails[position]);
+ ImageView imageView = (ImageView) getActivity().findViewById(R.id.imageView);
+ imageView.setImageResource(Candidates.candidatePhotos[position]);
+ } else {
+ TextView description = (TextView) getActivity().findViewById(R.id.description);
+ description.setText("Click on the names on the left to see details");
+ }
+ }
+ ```
+
+3. Create an empty activity called MultiPanelActivity. Open activity_multi_panel.xml, change the container layout to horizontal LinearLayout and insert the following FrameLayouts. FrameLayouts here are used as placeholders for our fragments.
+
+ ```xml
+
+
+
+ ```
+
+4. Open MultiPanelActivity.java and make the class implement `AdapterView.OnItemClickListener` interface. So your class declaration should look like this
+
+ ```java
+ public class MultiPanelActivity extends AppCompatActivity implements AdapterView.OnItemClickListener
+ ```
+
+ Insert the following overriding `onItemClick()` method into the class. By doing this, this MultiPanelActivity is capable of handling clicks that take place within an AdapterView.
+
+ ```java
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ DetailsFragment detailsFragmentNew = new DetailsFragment();
+ Bundle bundle = new Bundle();
+ bundle.putInt(DetailsFragment.POSITION, position);
+ detailsFragmentNew.setArguments(bundle);
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ fragmentTransaction.replace(R.id.fragmentRight, detailsFragmentNew);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ }
+ ```
+
+ >Instead of creating a new fragment and passing data to it, you can use just one line of code to update, what will that be? Navigate to MyFragment sample project MultiPanelActivity.java source code to find out.
+
+5. In MultiPanelActivity class, insert the following code into `onCreate()` method, below `setContentView()`. This will initialize the activity with the two fragments.
+
+ ```java
+ if (savedInstanceState == null){
+ getSupportFragmentManager().beginTransaction().add(R.id.fragmentLeft, new
+ ItemFragment()).commit();
+ getSupportFragmentManager().beginTransaction().add(R.id.fragmentRight, new
+ DetailsFragment()).commit();
+ }
+ ```
+
+ The code above initializes the activity layout in `onCreate()` using the two fragments. 'savedInstanceState' is used to check if it's restoring from configuration change e.g. screen rotation.
+
+6. Open ItemFragment.java, replace `getListView().setOnItemClickListener(this);` with the following. This code checks the container activity and set OnItemClickListener accordingly.
+
+ ```java
+ if (getActivity() instanceof ListFragmentActivity) {
+ getListView().setOnItemClickListener(this);
+ }
+
+ if (getActivity() instanceof MultiPanelActivity) {
+ getListView().setOnItemClickListener((MultiPanelActivity) getActivity());
+ }
+ ```
+
+ Insert the following method into the ItemFragment class
+
+ ```java
+ @Override
+ public void onStart() {
+ super.onStart();
+ getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ getListView().setSelector(android.R.color.darker_gray);
+ }
+ ```
+
+
+ The default behavior of ListView is that you click the ListView item but the item you clicked doesn't stay highlighted. The code above makes the item you clicked stays highlighted.
+
+7. Follow previous instructions (points No.3 & 4 in 'Programmatically add the fragment') to add a button called 'Multipanel' in activity_main.xml, associate this button with an intent that goes to MultiPanelActivity.
+
+If you run the app, you'll see something similar to below
+
+
+
+> The exercise here is a simplified version of a sample from the official API guide. For the original full version, see [Android references on Fragment](https://developer.android.com/reference/android/app/Fragment.html) and [Android API guide on Fragments](https://developer.android.com/guide/components/fragments.html).
+
+### Fragment lifecycle
+
+You have seen methods such as `onCreate()`, `onCreateView()`, and `onStart()`. All these are Fragment lifecycle callbacks, similar to Activity callbacks. The most important things to remember:
+
+* Fragments need to have empty constructors (and don't ask me why). Data passed into it need to use `setArguments()`.
+* `onAttach()` is specific to fragments. There're several other fragment-specific call-back functions. Read the [official guide](https://developer.android.com/guide/components/fragments.html) for details on this.
+* Activity coordinates Fragments lifecycle. For example, when the activity receives `onPause()`, each fragment in the activity receives `onPause()`.
+
+> A detailed image illustration of [fragment_lifecycle](https://raw.githubusercontent.com/xxv/android-lifecycle/master/complete_android_fragment_lifecycle.png) created by [Steve Pomeroy](https://github.com/xxv/android-lifecycle).
+
+
diff --git a/Week_05_AdapterViews_and_Fragments/README_gridview.md b/Week_05_AdapterViews_and_Fragments/README_gridview.md
new file mode 100644
index 0000000..0ecd8d9
--- /dev/null
+++ b/Week_05_AdapterViews_and_Fragments/README_gridview.md
@@ -0,0 +1,116 @@
+### Grid View
+
+
+Previous two examples used default ArrayAdapter and customized (extended) ArrayAdapter. In fact, ArrayAdapter is a subclass of BaseAdapter. Let's now go one step further and see how to customize (extend) BaseAdapter. In the following example, you'll learn how to create a GridView and provide a customized BaseAdaptor for it.
+
+1. Create a new Activity using the 'Empty Activity' template and name it GridAcitivty. Open activity_grid.xml and change the container layout from RelativeLayout to GridView. Insert the following attributes into the opening tag of GridView:
+
+ ```xml
+ android:columnWidth="90dp"
+ android:gravity="center"
+ android:horizontalSpacing="10dp"
+ android:numColumns="auto_fit"
+ android:stretchMode="columnWidth"
+ android:verticalSpacing="10dp"
+ ```
+
+ There are new attributes, but they are quite self-explanatory.
+
+2. Open GridActivity.java, insert the following code into `onCreate()` just before the ending curly brackets '}'.
+
+ ```java
+ GridView gridview = (GridView) findViewById(R.id.activity_grid);
+ gridview.setAdapter(new ImageAdapter(this));
+
+ gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView> parent, View v, int position, long id) {
+ Toast.makeText(getBaseContext(), "At position " + position + " is " + getResources().getStringArray(R.array.candidateNames)[position], Toast.LENGTH_SHORT).show();
+ }
+ });
+ ```
+ The only thing new here is the ImageAdapter, which we'll look at next.
+
+3. Create a new class called ImageAdapter. Replace the auto-generated class with the following
+
+ ```java
+ public class ImageAdapter extends BaseAdapter {
+
+ private int[] candidatePhotos = PhotoListActivity.candidatePhotos;
+ private Context context;
+
+ public ImageAdapter(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public int getCount() {
+ return candidatePhotos.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ImageView imageView;
+ if (convertView == null) {
+ imageView = new ImageView(context);
+ imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
+ imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+ imageView.setPadding(8, 8, 8, 8);
+ } else {
+ imageView = (ImageView) convertView;
+ }
+
+ imageView.setImageResource(candidatePhotos[position]);
+ return imageView;
+ }
+
+ }
+ ```
+
+ BaseAdapter is the superclass of different Adapters, but it's an abstract class. That means you have to provide concrete implementations for all abstract methods. That's why you see `getItem()` and `getItemId()` above. Although we don't use those two methods in our example we have to implement them. `getCount()` return the size of the data. The most important one is still `getView()`. Here instead of using layout resource file, we programmatically add layout widgets into the parent and set it's properties. `GridView.LayoutParams()` creates an GridView.LayoutParams object that resides inside the parent view, which is a GridView in our case.
+
+5. Insert the following into activity_main.xml, just before the ListView
+
+ ```xml
+
+ ```
+
+ Change the ListView attribute `android:layout_below` value from `"@id/complexList"` to `"@id/gridView"`.
+
+10. Open MainActivity.java, insert the following into the class
+
+ ```java
+ public void onButtonClick(View v){
+ startActivity(new Intent(this, PhotoListActivity.class));
+ }
+ ```
+6. Open MainActivity.java, replace contents of `onButtonClick()` with the following
+
+ ```java
+ switch (v.getId()) {
+ case R.id.complexList:
+ startActivity(new Intent(this, PhotoListActivity.class));
+ break;
+ case R.id.gridView:
+ startActivity(new Intent(this, GridActivity.class));
+ break;
+ }
+ ```
+
+If you run the app and click on 'GridView', you'll see something similar to below
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/.md_images/db_file.png b/Week_06_Data_persistence/.md_images/db_file.png
new file mode 100644
index 0000000..812a583
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/db_file.png differ
diff --git a/Week_06_Data_persistence/.md_images/db_insert.png b/Week_06_Data_persistence/.md_images/db_insert.png
new file mode 100644
index 0000000..7243cd5
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/db_insert.png differ
diff --git a/Week_06_Data_persistence/.md_images/export.png b/Week_06_Data_persistence/.md_images/export.png
new file mode 100644
index 0000000..d88b3a0
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/export.png differ
diff --git a/Week_06_Data_persistence/.md_images/fiddle.png b/Week_06_Data_persistence/.md_images/fiddle.png
new file mode 100644
index 0000000..1836f39
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/fiddle.png differ
diff --git a/Week_06_Data_persistence/.md_images/fiddle_o.png b/Week_06_Data_persistence/.md_images/fiddle_o.png
new file mode 100644
index 0000000..6a66c05
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/fiddle_o.png differ
diff --git a/Week_06_Data_persistence/.md_images/file_layout.png b/Week_06_Data_persistence/.md_images/file_layout.png
new file mode 100644
index 0000000..a3e5b91
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/file_layout.png differ
diff --git a/Week_06_Data_persistence/.md_images/files.png b/Week_06_Data_persistence/.md_images/files.png
new file mode 100644
index 0000000..e7c055d
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/files.png differ
diff --git a/Week_06_Data_persistence/.md_images/init.png b/Week_06_Data_persistence/.md_images/init.png
new file mode 100644
index 0000000..e74c4d5
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/init.png differ
diff --git a/Week_06_Data_persistence/.md_images/layout.png b/Week_06_Data_persistence/.md_images/layout.png
new file mode 100644
index 0000000..0d16329
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/layout.png differ
diff --git a/Week_06_Data_persistence/.md_images/sp.png b/Week_06_Data_persistence/.md_images/sp.png
new file mode 100644
index 0000000..ecbaaa4
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/sp.png differ
diff --git a/Week_06_Data_persistence/.md_images/sql.png b/Week_06_Data_persistence/.md_images/sql.png
new file mode 100644
index 0000000..ccedff9
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/sql.png differ
diff --git a/Week_06_Data_persistence/.md_images/sqlite_screen.png b/Week_06_Data_persistence/.md_images/sqlite_screen.png
new file mode 100644
index 0000000..2e79777
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/sqlite_screen.png differ
diff --git a/Week_06_Data_persistence/.md_images/sqliteh.png b/Week_06_Data_persistence/.md_images/sqliteh.png
new file mode 100644
index 0000000..e17d539
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/sqliteh.png differ
diff --git a/Week_06_Data_persistence/.md_images/switcher.png b/Week_06_Data_persistence/.md_images/switcher.png
new file mode 100644
index 0000000..6ac8a5e
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/switcher.png differ
diff --git a/Week_06_Data_persistence/.md_images/xml.png b/Week_06_Data_persistence/.md_images/xml.png
new file mode 100644
index 0000000..b115087
Binary files /dev/null and b/Week_06_Data_persistence/.md_images/xml.png differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/.gitignore b/Week_06_Data_persistence/ExistingSQLite/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_06_Data_persistence/ExistingSQLite/.idea/compiler.xml b/Week_06_Data_persistence/ExistingSQLite/.idea/compiler.xml
new file mode 100644
index 0000000..32b8ce7
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/.idea/copyright/profiles_settings.xml b/Week_06_Data_persistence/ExistingSQLite/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..7d61b5c
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/.idea/gradle.xml b/Week_06_Data_persistence/ExistingSQLite/.idea/gradle.xml
new file mode 100644
index 0000000..c3b1da4
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/.gitignore b/Week_06_Data_persistence/ExistingSQLite/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/build.gradle b/Week_06_Data_persistence/ExistingSQLite/app/build.gradle
new file mode 100644
index 0000000..dfb6257
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/build.gradle
@@ -0,0 +1,29 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "24.0.3"
+ defaultConfig {
+ applicationId "com.example.jianhuayang.existingsqlite"
+ minSdkVersion 15
+ targetSdkVersion 25
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:25.+'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/proguard-rules.pro b/Week_06_Data_persistence/ExistingSQLite/app/proguard-rules.pro
new file mode 100644
index 0000000..cce7213
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/jianhuayang/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/androidTest/java/com/example/jianhuayang/existingsqlite/ExampleInstrumentedTest.java b/Week_06_Data_persistence/ExistingSQLite/app/src/androidTest/java/com/example/jianhuayang/existingsqlite/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..f212a5c
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/androidTest/java/com/example/jianhuayang/existingsqlite/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.jianhuayang.existingsqlite;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.jianhuayang.existingsqlite", appContext.getPackageName());
+ }
+}
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/AndroidManifest.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ba822c6
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/assets/students.sql b/Week_06_Data_persistence/ExistingSQLite/app/src/main/assets/students.sql
new file mode 100644
index 0000000..66c9123
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/assets/students.sql
@@ -0,0 +1,10 @@
+DROP TABLE IF EXISTS contacts;
+CREATE TABLE contacts (
+ id INT PRIMARY KEY NOT NULL,
+ name TEXT NOT NULL,
+ age INT,
+ address CHAR(50)
+);
+INSERT INTO contacts (id, name, age, address) VALUES (1, 'Paul', 22, 'Singer Hall');
+INSERT INTO contacts (id, name, age, address) VALUES (2, 'John', 23, 'Singer Hall');
+INSERT INTO contacts (id, name, age, address) VALUES (3, 'Ben', 23, 'Callice Court');
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/assets/students.sqlite3 b/Week_06_Data_persistence/ExistingSQLite/app/src/main/assets/students.sqlite3
new file mode 100644
index 0000000..8c45cc4
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/app/src/main/assets/students.sqlite3 differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/java/com/example/jianhuayang/existingsqlite/DatabaseHandler.java b/Week_06_Data_persistence/ExistingSQLite/app/src/main/java/com/example/jianhuayang/existingsqlite/DatabaseHandler.java
new file mode 100644
index 0000000..c65e684
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/java/com/example/jianhuayang/existingsqlite/DatabaseHandler.java
@@ -0,0 +1,55 @@
+package com.example.jianhuayang.existingsqlite;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * Created by jianhuayang on 10/12/2016.
+ */
+
+public class DatabaseHandler extends SQLiteOpenHelper {
+
+
+ private Context context;
+
+ public DatabaseHandler(Context context) {
+ super(context, MainActivity.DB_NAME, null, 1);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase) {
+
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
+
+ }
+
+ public String getAll() {
+
+ SQLiteDatabase sqLiteDatabase = getReadableDatabase();
+ Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM contacts", null);
+ StringBuilder out = new StringBuilder();
+
+ // http://stackoverflow.com/questions/10723770/whats-the-best-way-to-iterate-an-android
+ // -cursor
+ try {
+ while (cursor.moveToNext()) {
+ out.append(cursor.getString(0));
+ out.append(cursor.getString(1));
+ out.append(cursor.getString(2));
+ out.append(cursor.getString(3));
+ out.append("\n");
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return out.toString();
+ }
+
+
+}
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/java/com/example/jianhuayang/existingsqlite/MainActivity.java b/Week_06_Data_persistence/ExistingSQLite/app/src/main/java/com/example/jianhuayang/existingsqlite/MainActivity.java
new file mode 100644
index 0000000..69aaef5
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/java/com/example/jianhuayang/existingsqlite/MainActivity.java
@@ -0,0 +1,106 @@
+package com.example.jianhuayang.existingsqlite;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+//some code from http://icetea09.com/blog/2014/01/22/android-use-existing-sqlite-database-in-android-app/
+public class MainActivity extends AppCompatActivity {
+ public static String DB_NAME = "students.sqlite3";
+ private String dbPath;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ dbPath = this.getDatabasePath(DB_NAME).getPath();
+ try {
+ createDataBase();
+ } catch (Exception e) {
+
+ }
+
+ }
+
+
+ /***
+ * Copy database from source code assets to device
+ *
+ * @throws IOException
+ */
+ public void copyDataBase() throws IOException {
+ try {
+ InputStream myInput = this.getAssets().open(DB_NAME);
+ OutputStream myOutput = new FileOutputStream(dbPath);
+
+ byte[] buffer = new byte[1024];
+ int length;
+
+ while ((length = myInput.read(buffer)) > 0) {
+ myOutput.write(buffer, 0, length);
+ }
+
+ myOutput.flush();
+ myOutput.close();
+ myInput.close();
+ } catch (Exception e) {
+ Log.e("tle99 - copyDatabase", e.getMessage());
+ }
+
+ }
+
+ /***
+ * Check if the database doesn't exist on device, create new one
+ *
+ * @throws IOException
+ */
+ public void createDataBase() throws IOException {
+ boolean dbExist = checkDataBase();
+
+ if (dbExist) {
+
+ } else {
+ try {
+ copyDataBase();
+ } catch (IOException e) {
+ Log.e("tle99 - create", e.getMessage());
+ }
+ }
+ }
+
+ // ---------------------------------------------
+ // PRIVATE METHODS
+ // ---------------------------------------------
+
+ /***
+ * Check if the database is exist on device or not
+ *
+ * @return
+ */
+ private boolean checkDataBase() {
+ SQLiteDatabase tempDB = null;
+ try {
+ tempDB = SQLiteDatabase.openDatabase(dbPath, null,
+ SQLiteDatabase.OPEN_READWRITE);
+ } catch (SQLiteException e) {
+ Log.e("tle99 - check", e.getMessage());
+ }
+ if (tempDB != null)
+ tempDB.close();
+ return tempDB != null ? true : false;
+ }
+
+ public void onClick(View v) {
+ DatabaseHandler databaseHandler = new DatabaseHandler(this);
+ Log.d("xxx", databaseHandler.getAll());
+ }
+}
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/layout/activity_main.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..9c87859
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values-w820dp/dimens.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/colors.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/dimens.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/strings.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e833cc9
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Existing SQLite
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/styles.xml b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/ExistingSQLite/app/src/test/java/com/example/jianhuayang/existingsqlite/ExampleUnitTest.java b/Week_06_Data_persistence/ExistingSQLite/app/src/test/java/com/example/jianhuayang/existingsqlite/ExampleUnitTest.java
new file mode 100644
index 0000000..5a056f6
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/app/src/test/java/com/example/jianhuayang/existingsqlite/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jianhuayang.existingsqlite;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
diff --git a/Week_06_Data_persistence/ExistingSQLite/build.gradle b/Week_06_Data_persistence/ExistingSQLite/build.gradle
new file mode 100644
index 0000000..c20bca1
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.2.2'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_06_Data_persistence/ExistingSQLite/gradle.properties b/Week_06_Data_persistence/ExistingSQLite/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_06_Data_persistence/ExistingSQLite/gradle/wrapper/gradle-wrapper.jar b/Week_06_Data_persistence/ExistingSQLite/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_06_Data_persistence/ExistingSQLite/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_06_Data_persistence/ExistingSQLite/gradle/wrapper/gradle-wrapper.properties b/Week_06_Data_persistence/ExistingSQLite/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..04e285f
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Dec 28 10:00:20 PST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
diff --git a/Week_06_Data_persistence/ExistingSQLite/gradlew b/Week_06_Data_persistence/ExistingSQLite/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_06_Data_persistence/ExistingSQLite/gradlew.bat b/Week_06_Data_persistence/ExistingSQLite/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_06_Data_persistence/ExistingSQLite/settings.gradle b/Week_06_Data_persistence/ExistingSQLite/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_06_Data_persistence/ExistingSQLite/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_06_Data_persistence/MyFiles/.gitignore b/Week_06_Data_persistence/MyFiles/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_06_Data_persistence/MyFiles/.idea/compiler.xml b/Week_06_Data_persistence/MyFiles/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/.idea/copyright/profiles_settings.xml b/Week_06_Data_persistence/MyFiles/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/.idea/gradle.xml b/Week_06_Data_persistence/MyFiles/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/.idea/misc.xml b/Week_06_Data_persistence/MyFiles/.idea/misc.xml
new file mode 100644
index 0000000..5d19981
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/.idea/modules.xml b/Week_06_Data_persistence/MyFiles/.idea/modules.xml
new file mode 100644
index 0000000..28ab683
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/.idea/runConfigurations.xml b/Week_06_Data_persistence/MyFiles/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/app/.gitignore b/Week_06_Data_persistence/MyFiles/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_06_Data_persistence/MyFiles/app/build.gradle b/Week_06_Data_persistence/MyFiles/app/build.gradle
new file mode 100644
index 0000000..a5c4d8d
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.jianhuayang.mysharedpreferences"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_06_Data_persistence/MyFiles/app/proguard-rules.pro b/Week_06_Data_persistence/MyFiles/app/proguard-rules.pro
new file mode 100644
index 0000000..6d3585e
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/jianhuayang/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_06_Data_persistence/MyFiles/app/src/androidTest/java/com/example/jianhuayang/mysharedpreferences/ExampleInstrumentedTest.java b/Week_06_Data_persistence/MyFiles/app/src/androidTest/java/com/example/jianhuayang/mysharedpreferences/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..21c4bd3
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/androidTest/java/com/example/jianhuayang/mysharedpreferences/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.jianhuayang.mysharedpreferences;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.jianhuayang.mysharedpreferences", appContext.getPackageName());
+ }
+}
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/AndroidManifest.xml b/Week_06_Data_persistence/MyFiles/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..622ec85
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/java/com/example/jianhuayang/mysharedpreferences/MainActivity.java b/Week_06_Data_persistence/MyFiles/app/src/main/java/com/example/jianhuayang/mysharedpreferences/MainActivity.java
new file mode 100644
index 0000000..ffab463
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/main/java/com/example/jianhuayang/mysharedpreferences/MainActivity.java
@@ -0,0 +1,58 @@
+package com.example.jianhuayang.mysharedpreferences;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class MainActivity extends AppCompatActivity {
+
+ public static final String FILE_NAME = "contacts.txt";
+ private EditText editTextName;
+ private EditText editTextPhone;
+ private File file;
+ private FileOutputStream outputStream;
+ private FileInputStream inputStream;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ editTextName = (EditText) findViewById(R.id.nameText);
+ editTextPhone = (EditText) findViewById(R.id.phoneText);
+ file = new File(this.getFilesDir(), FILE_NAME);
+ }
+
+ public void save(View v) {
+ String data = editTextName.getText().toString() + "|" + editTextPhone.getText().toString();
+ try {
+ outputStream = new FileOutputStream(file);
+ outputStream.write(data.getBytes());
+ outputStream.close();
+ Toast.makeText(this, "data saved", Toast.LENGTH_SHORT).show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void load(View v) {
+ int length = (int) file.length();
+ byte[] bytes = new byte[length];
+ try {
+ inputStream = new FileInputStream(file);
+ inputStream.read(bytes);
+ inputStream.close();
+ String data = new String(bytes);
+ editTextName.setText(data.split("\\|")[0]);
+ editTextPhone.setText(data.split("\\|")[1]);
+ Toast.makeText(getBaseContext(), "data loaded", Toast.LENGTH_SHORT).show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/layout/activity_main.xml b/Week_06_Data_persistence/MyFiles/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..bd6f70b
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/values/colors.xml b/Week_06_Data_persistence/MyFiles/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/values/strings.xml b/Week_06_Data_persistence/MyFiles/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f8d13eb
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ My SharedPreferences
+
diff --git a/Week_06_Data_persistence/MyFiles/app/src/main/res/values/styles.xml b/Week_06_Data_persistence/MyFiles/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/MyFiles/app/src/test/java/com/example/jianhuayang/mysharedpreferences/ExampleUnitTest.java b/Week_06_Data_persistence/MyFiles/app/src/test/java/com/example/jianhuayang/mysharedpreferences/ExampleUnitTest.java
new file mode 100644
index 0000000..ad48032
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/app/src/test/java/com/example/jianhuayang/mysharedpreferences/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jianhuayang.mysharedpreferences;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MyFiles/build.gradle b/Week_06_Data_persistence/MyFiles/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_06_Data_persistence/MyFiles/gradle.properties b/Week_06_Data_persistence/MyFiles/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_06_Data_persistence/MyFiles/gradle/wrapper/gradle-wrapper.jar b/Week_06_Data_persistence/MyFiles/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_06_Data_persistence/MyFiles/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_06_Data_persistence/MyFiles/gradle/wrapper/gradle-wrapper.properties b/Week_06_Data_persistence/MyFiles/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..96ab613
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Nov 07 07:04:21 GMT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_06_Data_persistence/MyFiles/gradlew b/Week_06_Data_persistence/MyFiles/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_06_Data_persistence/MyFiles/gradlew.bat b/Week_06_Data_persistence/MyFiles/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_06_Data_persistence/MyFiles/settings.gradle b/Week_06_Data_persistence/MyFiles/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_06_Data_persistence/MyFiles/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_06_Data_persistence/MySQLite/.gitignore b/Week_06_Data_persistence/MySQLite/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_06_Data_persistence/MySQLite/.idea/compiler.xml b/Week_06_Data_persistence/MySQLite/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/.idea/copyright/profiles_settings.xml b/Week_06_Data_persistence/MySQLite/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/.idea/gradle.xml b/Week_06_Data_persistence/MySQLite/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/.idea/misc.xml b/Week_06_Data_persistence/MySQLite/.idea/misc.xml
new file mode 100644
index 0000000..5d19981
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/.idea/modules.xml b/Week_06_Data_persistence/MySQLite/.idea/modules.xml
new file mode 100644
index 0000000..68c2a0b
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/.idea/runConfigurations.xml b/Week_06_Data_persistence/MySQLite/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/app/.gitignore b/Week_06_Data_persistence/MySQLite/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_06_Data_persistence/MySQLite/app/build.gradle b/Week_06_Data_persistence/MySQLite/app/build.gradle
new file mode 100644
index 0000000..68f955e
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.jianhuayang.mysqlite"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_06_Data_persistence/MySQLite/app/proguard-rules.pro b/Week_06_Data_persistence/MySQLite/app/proguard-rules.pro
new file mode 100644
index 0000000..6d3585e
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/jianhuayang/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_06_Data_persistence/MySQLite/app/src/androidTest/java/com/example/jianhuayang/mysqlite/ExampleInstrumentedTest.java b/Week_06_Data_persistence/MySQLite/app/src/androidTest/java/com/example/jianhuayang/mysqlite/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..e54202e
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/androidTest/java/com/example/jianhuayang/mysqlite/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.jianhuayang.mysqlite;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.jianhuayang.mysqlite", appContext.getPackageName());
+ }
+}
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/AndroidManifest.xml b/Week_06_Data_persistence/MySQLite/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6c26dcf
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/Contact.java b/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/Contact.java
new file mode 100644
index 0000000..99093f4
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/Contact.java
@@ -0,0 +1,41 @@
+package com.example.jianhuayang.mysqlite;
+
+/**
+ * Created by jianhuayang on 07/11/2017.
+ */
+
+public class Contact {
+ private int id;
+ private String name;
+ private String phone;
+
+ public Contact(int id, String name, String phone) {
+ this.id = id;
+ this.name = name;
+ this.phone = phone;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+}
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/DatabaseHandler.java b/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/DatabaseHandler.java
new file mode 100644
index 0000000..8dd09bf
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/DatabaseHandler.java
@@ -0,0 +1,49 @@
+package com.example.jianhuayang.mysqlite;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+/**
+ * Created by jianhuayang on 08/11/2017.
+ */
+
+public class DatabaseHandler extends SQLiteOpenHelper {
+
+ public DatabaseHandler(Context context) {
+ super(context, "testDB", null, 1);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE contactTable (colID, colName, colPhone)");
+ }
+
+// public DatabaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
+// super(context, name, factory, version);
+// }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ }
+
+ public void addContact(Contact contact) {
+ SQLiteDatabase sqLiteDatabase = getReadableDatabase();
+
+ ContentValues contentValues = new ContentValues();
+ contentValues.put("colID", contact.getId());
+ contentValues.put("colName", contact.getName());
+ contentValues.put("colPhone", contact.getPhone());
+
+ long result = sqLiteDatabase.insert("contactTable", null, contentValues);
+
+ if (result > 0) {
+ Log.d("dbhelper", "inserted successfully");
+ } else {
+ Log.d("dbhelper", "failed to insert");
+ }
+ sqLiteDatabase.close();
+ }
+}
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/MainActivity.java b/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/MainActivity.java
new file mode 100644
index 0000000..0a1193c
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/java/com/example/jianhuayang/mysqlite/MainActivity.java
@@ -0,0 +1,30 @@
+package com.example.jianhuayang.mysqlite;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.EditText;
+
+public class MainActivity extends AppCompatActivity {
+
+ private EditText idText;
+ private EditText nameText;
+ private EditText phoneText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ idText = (EditText) findViewById(R.id.IDText);
+ nameText = (EditText) findViewById(R.id.nameText);
+ phoneText = (EditText) findViewById(R.id.phoneText);
+ }
+
+ public void save(View v){
+ int anID = Integer.parseInt(idText.getText().toString());
+ String aName = nameText.getText().toString();
+ String aPhone = phoneText.getText().toString();
+ DatabaseHandler db = new DatabaseHandler(this);
+ db.addContact(new Contact(anID, aName, aPhone));
+ }
+}
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/layout/activity_main.xml b/Week_06_Data_persistence/MySQLite/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..63c6f33
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/values/colors.xml b/Week_06_Data_persistence/MySQLite/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/values/strings.xml b/Week_06_Data_persistence/MySQLite/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..ca40592
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ My SQLite
+
diff --git a/Week_06_Data_persistence/MySQLite/app/src/main/res/values/styles.xml b/Week_06_Data_persistence/MySQLite/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/MySQLite/app/src/test/java/com/example/jianhuayang/mysqlite/ExampleUnitTest.java b/Week_06_Data_persistence/MySQLite/app/src/test/java/com/example/jianhuayang/mysqlite/ExampleUnitTest.java
new file mode 100644
index 0000000..3d65c83
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/app/src/test/java/com/example/jianhuayang/mysqlite/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jianhuayang.mysqlite;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySQLite/build.gradle b/Week_06_Data_persistence/MySQLite/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_06_Data_persistence/MySQLite/gradle.properties b/Week_06_Data_persistence/MySQLite/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_06_Data_persistence/MySQLite/gradle/wrapper/gradle-wrapper.jar b/Week_06_Data_persistence/MySQLite/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_06_Data_persistence/MySQLite/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_06_Data_persistence/MySQLite/gradle/wrapper/gradle-wrapper.properties b/Week_06_Data_persistence/MySQLite/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..230d76f
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Nov 07 23:05:36 GMT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_06_Data_persistence/MySQLite/gradlew b/Week_06_Data_persistence/MySQLite/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_06_Data_persistence/MySQLite/gradlew.bat b/Week_06_Data_persistence/MySQLite/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_06_Data_persistence/MySQLite/settings.gradle b/Week_06_Data_persistence/MySQLite/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_06_Data_persistence/MySQLite/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_06_Data_persistence/MySharedPreferences/.gitignore b/Week_06_Data_persistence/MySharedPreferences/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_06_Data_persistence/MySharedPreferences/.idea/compiler.xml b/Week_06_Data_persistence/MySharedPreferences/.idea/compiler.xml
new file mode 100644
index 0000000..96cc43e
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/.idea/copyright/profiles_settings.xml b/Week_06_Data_persistence/MySharedPreferences/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/.idea/gradle.xml b/Week_06_Data_persistence/MySharedPreferences/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/.idea/misc.xml b/Week_06_Data_persistence/MySharedPreferences/.idea/misc.xml
new file mode 100644
index 0000000..5d19981
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.idea/misc.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/.idea/modules.xml b/Week_06_Data_persistence/MySharedPreferences/.idea/modules.xml
new file mode 100644
index 0000000..6b0ad4e
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/.idea/runConfigurations.xml b/Week_06_Data_persistence/MySharedPreferences/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/.gitignore b/Week_06_Data_persistence/MySharedPreferences/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/build.gradle b/Week_06_Data_persistence/MySharedPreferences/app/build.gradle
new file mode 100644
index 0000000..a5c4d8d
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.0"
+ defaultConfig {
+ applicationId "com.example.jianhuayang.mysharedpreferences"
+ minSdkVersion 15
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:26.+'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
+ testCompile 'junit:junit:4.12'
+}
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/proguard-rules.pro b/Week_06_Data_persistence/MySharedPreferences/app/proguard-rules.pro
new file mode 100644
index 0000000..6d3585e
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/jianhuayang/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/androidTest/java/com/example/jianhuayang/mysharedpreferences/ExampleInstrumentedTest.java b/Week_06_Data_persistence/MySharedPreferences/app/src/androidTest/java/com/example/jianhuayang/mysharedpreferences/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..21c4bd3
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/androidTest/java/com/example/jianhuayang/mysharedpreferences/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.jianhuayang.mysharedpreferences;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.jianhuayang.mysharedpreferences", appContext.getPackageName());
+ }
+}
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/AndroidManifest.xml b/Week_06_Data_persistence/MySharedPreferences/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..622ec85
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/java/com/example/jianhuayang/mysharedpreferences/MainActivity.java b/Week_06_Data_persistence/MySharedPreferences/app/src/main/java/com/example/jianhuayang/mysharedpreferences/MainActivity.java
new file mode 100644
index 0000000..616cdab
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/main/java/com/example/jianhuayang/mysharedpreferences/MainActivity.java
@@ -0,0 +1,44 @@
+package com.example.jianhuayang.mysharedpreferences;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+public class MainActivity extends AppCompatActivity {
+
+ private EditText editTextName;
+ private EditText editTextPhone;
+ public static final String NAME_KEY = "NAME_KEY";
+ public static final String PHONE_KEY = "PHONE_KEY";
+ private SharedPreferences sharedPreferences;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ editTextName = (EditText) findViewById(R.id.nameText);
+ editTextPhone = (EditText) findViewById(R.id.phoneText);
+ sharedPreferences = getSharedPreferences("MySharedPreMain", Context.MODE_PRIVATE);
+
+ if (sharedPreferences.contains(NAME_KEY)) {
+ editTextName.setText(sharedPreferences.getString(NAME_KEY, ""));
+ }
+
+ if (sharedPreferences.contains(PHONE_KEY)) {
+ editTextPhone.setText(sharedPreferences.getString(PHONE_KEY, ""));
+ }
+ }
+
+ public void save(View v){
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString(NAME_KEY, editTextName.getText().toString());
+ editor.putString(PHONE_KEY, editTextPhone.getText().toString());
+ editor.commit();
+ Toast.makeText(v.getContext(),"data saved",Toast.LENGTH_SHORT).show();
+ }
+}
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/layout/activity_main.xml b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..21a4dd0
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/colors.xml b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/strings.xml b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f8d13eb
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ My SharedPreferences
+
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/styles.xml b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/Week_06_Data_persistence/MySharedPreferences/app/src/test/java/com/example/jianhuayang/mysharedpreferences/ExampleUnitTest.java b/Week_06_Data_persistence/MySharedPreferences/app/src/test/java/com/example/jianhuayang/mysharedpreferences/ExampleUnitTest.java
new file mode 100644
index 0000000..ad48032
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/app/src/test/java/com/example/jianhuayang/mysharedpreferences/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jianhuayang.mysharedpreferences;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/Week_06_Data_persistence/MySharedPreferences/build.gradle b/Week_06_Data_persistence/MySharedPreferences/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_06_Data_persistence/MySharedPreferences/gradle.properties b/Week_06_Data_persistence/MySharedPreferences/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_06_Data_persistence/MySharedPreferences/gradle/wrapper/gradle-wrapper.jar b/Week_06_Data_persistence/MySharedPreferences/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_06_Data_persistence/MySharedPreferences/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_06_Data_persistence/MySharedPreferences/gradle/wrapper/gradle-wrapper.properties b/Week_06_Data_persistence/MySharedPreferences/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..96ab613
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Nov 07 07:04:21 GMT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_06_Data_persistence/MySharedPreferences/gradlew b/Week_06_Data_persistence/MySharedPreferences/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_06_Data_persistence/MySharedPreferences/gradlew.bat b/Week_06_Data_persistence/MySharedPreferences/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_06_Data_persistence/MySharedPreferences/settings.gradle b/Week_06_Data_persistence/MySharedPreferences/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_06_Data_persistence/MySharedPreferences/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_06_Data_persistence/README.md b/Week_06_Data_persistence/README.md
new file mode 100644
index 0000000..17c69e8
--- /dev/null
+++ b/Week_06_Data_persistence/README.md
@@ -0,0 +1,597 @@
+# Data persistence
+
+Data persistence refers to the fact that data need to persist through app life cycle changes. In other words, even if you close the app completely the data need to be restored when the user navigates back to the app.
+
+> The most common mistake people make when demonstrating data persistence is that they press the Home button when they finish saving data and then tap the app icon again to bring the app back. NO! That's NOT how you demonstrate data persistence! The proper way of doing it is, after saving your data, you close the app completely using app switcher e.g. the square button and then start your app again by tapping the icon. To understand why this is the case you need to remind yourselves about Activity Lifecycle.
+
+## Lab 1 SharedPreferences and files
+
+### SharedPreferences
+
+SharedPreferences is a way to save simple key-value pairs. In fact, the file produced by SharedPreferences API is a plain xml file similar to the resource files you provide for the system.
+
+Follow steps below to prepare the layout xml file:
+
+1. Start a new Android Studio project and name it 'My SharedPreferences'. In activity_main.xml, change the default layout to LinearLayout, add `android:orientation="vertical"`.
+2. In the Design view, drag and drop the following items onto the layout, below the automatically generated 'Hello World' TextView, in the order of Plain Text, TextView, and Phone. All these three go below the 'Hello World' TextView that was by the system. Rearrange the XML so it looks like below:
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+
+
+Next, let's need to use SharedPreferences API to save some simple data.
+
+1. Open MainActivity.java file and insert the following declarations immediately after the class declaration:
+
+ ```java
+ private EditText editTextName;
+ private EditText editTextPhone;
+ public static final String NAME_KEY = "NAME_KEY";
+ public static final String PHONE_KEY = "PHONE_KEY";
+ private SharedPreferences sharedPreferences;
+ ```
+
+ Code above initializes two EditText objects that hold the user inputs and two static strings which are going to be used as keys in the key-value pairs.
+
+2. Modify the `onCreate()` method to match the following:
+
+ ```java
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ editTextName = (EditText) findViewById(R.id.nameText);
+ editTextPhone = (EditText) findViewById(R.id.phoneText);
+ sharedPreferences = getSharedPreferences("MySharedPreMain", Context.MODE_PRIVATE);
+
+ if (sharedPreferences.contains(NAME_KEY)) {
+ editTextName.setText(sharedPreferences.getString(NAME_KEY, ""));
+ }
+
+ if (sharedPreferences.contains(PHONE_KEY)) {
+ editTextPhone.setText(sharedPreferences.getString(PHONE_KEY, ""));
+ }
+ }
+ ```
+
+ There're several methods offered by the SharedPreferences class, here `contains()` and `getString()` methods are to test if the SharedPreferenes object contains specific keys. If it does, it will get the data out.
+
+3. Create a call-back method that responds to the click event of the only button in the XML. Don't forget the `commit()` method, which is similar to `commit()` in FragmentTransaction. You also need to update the xml file to associate the button with this method by inserting `android:onClick="save"` line.
+
+ ```java
+ public void save(View v){
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString(NAME_KEY, editTextName.getText().toString());
+ editor.putString(PHONE_KEY, editTextPhone.getText().toString());
+ editor.commit();
+ Toast.makeText(v.getContext(),"data saved",Toast.LENGTH_SHORT).show();
+ }
+ ```
+
+4. Run the app and type in something, then click the 'Save' button. Close the app properly (i.e. through app switcher) and then re-open you'll the data is still there.
+
+ 
+
+ 
+
+5. To actually see the file created, you'll need to run the app using an AVD and NOT your device (unless you root it). If in previous steps you use a real device, now switch to an AVD based on API 23 and save some data in the app. Click Tools ==> Android ==> Android Device Monitor to bring up the Android Device Monitor
+
+ > It seems that latest Android APIs (24 and above) do not integrate well with [DDMS](https://developer.android.com/studio/profile/ddms.html), you will have to use an AVD that is based on Android 6.0 (API 23) or below. See [discussion on StackOverflow](https://stackoverflow.com/questions/34603355/android-device-monitor-data-folder-is-empty).
+
+ In the File Explorer tab, go to Data ==> Data ==> com.example.jianhuayang.mysharedpreferences ==> shared_prefs folder, you'll see an XML file named 'MySharedPreMain.xml', which is the name you give earlier in the `getSharedPreference()` method. This is where your data are saved. Single-click on that xml file to select it, then click the Get Device File icon (the left-most icon in the toolbar) to export the file to your hard drive.
+
+ 
+
+ If you open the file in a text editor, you'll see the contents. Note that key-value pairs are being stored as explicit texts in it. (Explicit texts cannot be used to save sensitive data).
+
+ 
+
+ > If you do it on a real device, you'll see that data folder is empty. That's because you don't have the admin a.k.a. root privileges to access contents in that folder. You can 'root' your device in a way similar to jailbreaking iPhones, but this is not recommended as it opens security holes. To see why you shouldn't root your device, read [the blog written by Srinivas](http://resources.infosecinstitute.com/android-hacking-security-part-9-insecure-local-storage-shared-preferences/), where SharedPreferences were used to manipulate game scores.
+
+### Writing and reading to files
+
+Instead of writing to an internal XML file using SharedPreferences API, you can also use the standard Java IO API to read/write files as if Android is a small PC.
+
+> In case you are new to Java I/O, have a look at [Java I/O Tutorials](https://docs.oracle.com/javase/tutorial/essential/io/) and [how to read data from InputStream into String in java](http://howtodoinjava.com/2013/10/06/how-to-read-data-from-inputstream-into-string-in-java/).
+
+Follow steps below to create a simple app that stores some data in a file.
+
+1. Locate the 'My SharedPreferences' project you created earlier on your hard drive, make a copy of it and rename the new folder to 'MyFiles'.
+2. Open 'MyFiles' project, in activity_main.xml, in the Design view drag and drop a LinearLayout (horizontal) before the Button. Make sure this LinearLayout has 'layout_width="match_parent"' and 'layout_height="wrap_content"'.
+3. Switch to the Text view, move the Button tag into this newly created LinearLayout.
+4. Switch back to the design view, drag and drop another button to the right of the Save button, and a Plain TextView to the left of the Save button. Make your layout look like this:
+
+ 
+
+5. Double click on the new button, change the text to Load, and id to load.
+6. Double click on the new TextView, delete the text so it becomes blank. Switch back to the text view and give this TextView a weight of 1, and width/height of '0dp'. The finished XML LinearLayout should look like below.
+
+ ```xml
+
+
+
+
+
+
+
+
+
+ ```
+
+ 
+
+7. Open MainActivity.java file, locate and delete the following lines of code
+
+ ```java
+ public static final String NAME_KEY = "NAME_KEY";
+ public static final String PHONE_KEY = "PHONE_KEY";
+ private SharedPreferences sharedPreferences;
+ ```
+
+ and
+
+ ```java
+ sharedPreferences = getSharedPreferences("MySharedPreMain", Context.MODE_PRIVATE);
+
+ if (sharedPreferences.contains(NAME_KEY)) {
+ editTextName.setText(sharedPreferences.getString(NAME_KEY, ""));
+ }
+
+ if (sharedPreferences.contains(PHONE_KEY)) {
+ editTextPhone.setText(sharedPreferences.getString(PHONE_KEY, ""));
+ }
+
+ ```
+
+ and finally
+
+ ```java
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString(NAME_KEY, editTextName.getText().toString());
+ editor.putString(PHONE_KEY, editTextPhone.getText().toString());
+ editor.commit();
+ ```
+
+8. In order to use file input/output, you need to declare some variables. The declaration goes together with EditeTexts' declaration
+
+ ```java
+ private EditText editTextName;
+ private EditText editTextPhone;
+ public static final String FILE_NAME = "contacts.txt";
+ private File file;
+ private FileOutputStream outputStream;
+ private FileInputStream inputStream;
+ ```
+
+9. Inside the `onCreate()` method insert a line to initialize the file object:
+
+ ```java
+ file = new File(this.getFilesDir(), FILE_NAME);
+ ```
+
+ This will create a new file at the system default location for your app with the given file name.
+
+10. Modify the `save()` method, so it looks like below
+
+ ```java
+ public void save(View v) {
+ String data = editTextName.getText().toString() + "|" + editTextPhone.getText().toString();
+ try {
+ outputStream = new FileOutputStream(file);
+ outputStream.write(data.getBytes());
+ outputStream.close();
+ Toast.makeText(this, "data saved", Toast.LENGTH_SHORT).show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ ```
+
+ What the code does here is to get texts in name and phone fields and join them using the character '|'. Which character to use is totally up to you, but you want some special characters i.e. those not often seen in names and phone numbers so that parsing data back is easier. Anything that concerns InputStream/OutputStream (FileInputStream/FileOutputStream are sub-classes) should be closed properly, and need to be enclosed within try/catch block.
+
+11. Create a new method called `load()`, using the following lines of codes:
+
+ ```java
+ public void load(View v) {
+ int length = (int) file.length();
+ byte[] bytes = new byte[length];
+ try {
+ inputStream = new FileInputStream(file);
+ inputStream.read(bytes);
+ inputStream.close();
+ String data = new String(bytes);
+ editTextName.setText(data.split("\\|")[0]);
+ editTextPhone.setText(data.split("\\|")[1]);
+ Toast.makeText(getBaseContext(), "data loaded", Toast.LENGTH_SHORT).show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ ```
+
+ From the file object created earlier in the `onCreate()` method, it gets the total number of bytes. Using this number, it then defines an array to hold all bytes. And then it reads every byte in one go and convert them into a String so that to assign these texts to different widgets.
+
+12. Open activity_main.xml file and associate this `load()` method with the Load button. Job done!
+
+Run this app in an AVD and type some info such as those in the screenshot below, and click save. Shut your app properly and re-open it, if you click the Load button your data will be retrieved. The same as in the Shared Preferences example, the file you saved can be found using the Device Monitor. You can pull the file onto your local hard drive to have a look at its contents.
+
+
+
+
+## Lab 2 SQLite Databases
+
+SharedPreferences and File storage are mainly used to store data of small quantity. If you have a large amount of data the chance is that you'll need to use SQLite database.
+
+> Exercises in this section roughly follow [the official guide](https://developer.android.com/training/data-storage/sqlite.html) and [an online tutorial written by Ravi Tamada](http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/). Be aware that Google recommends using [the Room persistence library](https://developer.android.com/training/data-storage/room/index.html) instead of SQLite.
+
+### SQL in 5 minutes
+
+For those of you who aren't familiar with SQL syntax, follow instructions below to finish a very simple exercise. If you 'are familiar with SQL, you can simply skip this section and move to the next one directly.
+
+1. Click on the following link to go to [SQL Fiddle](http://sqlfiddle.com). Paste the following into the Schema Panel (left panel) and then click the Build Schema button
+
+ ```sql
+ DROP TABLE IF EXISTS contacts;
+ CREATE TABLE contacts (
+ id INT PRIMARY KEY NOT NULL,
+ name TEXT NOT NULL,
+ age INT,
+ address CHAR(50)
+ );
+ ```
+
+ This will create a new table that has four columns, each of these columns has a pre-defined type. If you click the Browser button, and then click on the 'contacts (TABLE)' you'll see different columns and associated data types
+
+ 
+
+2. Click on DDL Editor button to go back to Schema Panel again. Insert the following SQL statements **below** (append, NOT replace) what's in there already and hit Build Schema button. This will insert some rows into the table.
+
+ ```sql
+ INSERT INTO contacts (id, name, age, address) VALUES (1, 'Paul', 22, 'Singer Hall');
+ INSERT INTO contacts (id, name, age, address) VALUES (2, 'John', 23, 'Singer Hall');
+ INSERT INTO contacts (id, name, age, address) VALUES (3, 'Ben', 23, 'Callice Court');
+ ```
+
+3. When you see texts 'Schema Ready' below the Schema panel, you can insert the following into the SQL panel (right panel), and then click Run SQL
+
+ ```sql
+ SELECT * FROM contacts;
+ ```
+
+ After completion, you will see the data rows you just inserted come back from the query. You can also run queries using the 'WHERE' clause such as `SELECT * FROM contacts WHERE id = 2;`
+
+ 
+
+
+
+Have a play around and make sure you understand everything, as these are important for the following exercise. In case you want to know more, go to [W3Schools](http://www.w3schools.com/sql/) and click links on the left to read.
+
+### The Contact class - the model
+
+In the following exercise, you are going to build a contact app to save some basic info of other people. First of all, let's create our data model.
+
+1. Start a new Android Studio project and name it 'My SQLite'.
+2. Right-click in the Project tool window to create a new class, and name it Contact.
+3. Modify your class to make it look like the following. You should automatically generate getters and setters instead of typing manually. You might need to 'Rearrange Code' after that.
+
+ ```java
+ public class Contact {
+ private int id;
+ private String name;
+ private String phone;
+
+ public Contact(int id, String name, String phone) {
+ this.id = id;
+ this.name = name;
+ this.phone = phone;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+ }
+ ```
+
+### The layout file - the view
+
+Next, you will need to create a layout to accommodate the data model. Open activity_main.xml, replace the default layout with LinearLayout and insert `android:orientation="vertical"`. Delete the default TextView and insert the following
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### The DB handler and activity - the controller
+
+Once you have the model and view, you will need to work on how to link both together (i.e. controller in MVC). This is probably the most challenging part in terms of app development. However, for SQLite databases, Android provides a helper class i.e. SQLiteOpenHelper that is very handy to use.
+
+1. Create a new class called DatabseHandler extending SQLiteOpenHelper
+
+ 
+
+ ```java
+ public class DatabaseHandler extends SQLiteOpenHelper{
+
+ }
+ ```
+
+2. If you move your mouse over the red highlighted class declaration you'll see that you need to implement some abstract methods in order to inherit. Insert the following codes into the class to implement the two abstract methods.
+
+ ```java
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ }
+ ```
+
+3. What you'll see now is that even though you have implemented the two abstract methods, there's still an error saying no constructor available. Click Code ==> Generate... ==> Constructor, in the window that pops up select the first option (the one with fewer inputs). This will generate a constructor for you.
+
+ ```java
+ public DatabaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
+ super(context, name, factory, version);
+ }
+ ```
+
+ There're four parameters that are passed on to super constructor. The first one is the current context and the second is the database name. The 3rd parameter is an SQLiteDatabase.CursorFactory. The last parameter is the database version, where most likely you'll want it to be 1. This auto-generated constructor is overwhelming as you don't need all those info for such a simple app. Replace it with the following simplified version:
+
+ ```java
+ public DatabaseHandler(Context context){
+ super(context, "testDB", null, 1);
+ }
+ ```
+
+4. By now all error messages (i.e. red underline highlights) should disappear, but still the `onCreate()` method is empty. Insert code into the method so it looks like the following:
+
+ ```java
+ public void onCreate(SQLiteDatabase db){
+ db.execSQL("CREATE TABLE contactTable (colID, colName, colPhone)");
+ }
+ ```
+
+ Here 'col' means column, but it can be anything as it's just a name. Note that this way of creating the table is very simple - just one line of code without declaring data type. However, there're many different ways to create tables in SQLite. Detailed instruction of this can be found on [the official SQLite documentation](https://www.sqlite.org/lang_createtable.html).
+
+5. In order to have a functional storage, you need to read/write to it. In terms of SQL database, this is commonly referred to as CRUD i.e. create, read, update, and delete. Insert the following method into the DatabaseHandler class
+
+ ```java
+ public void addContact(Contact contact) {
+ SQLiteDatabase sqLiteDatabase = getReadableDatabase();
+
+ ContentValues contentValues = new ContentValues();
+ contentValues.put("colID", contact.getId());
+ contentValues.put("colName", contact.getName());
+ contentValues.put("colPhone", contact.getPhone());
+
+ long result = sqLiteDatabase.insert("contactTable", null, contentValues);
+
+ if (result > 0) {
+ Log.d("dbhelper", "inserted successfully");
+ } else {
+ Log.d("dbhelper", "failed to insert");
+ }
+ sqLiteDatabase.close();
+ }
+ ```
+
+ The method above will insert data into the database. ContentValues is very similar to Bundle - both are used to store key-values pairs. But Bundle is associated with Intent and used to pass data in between activities. ContentValues is mainly for database insertion/updating etc. People are suggesting that ContentValues is a special case of Bundle, see [discussions on Stack Overflow](http://stackoverflow.com/questions/9334470/is-there-an-efficient-way-to-convert-from-bundle-to-contentvalues). Also note here what comes back from insertion is the row id if it's successful or '-1' if it failed.
+
+6. Now let's work on the MainActivity to link everything together. Open MainActivity.java file and declare these variables after class declaration.
+
+ ```java
+ private EditText idText;
+ private EditText nameText;
+ private EditText phoneText;
+ ```
+
+ Insert variable initializations in `onCreate()` method
+
+ ```java
+ idText = (EditText) findViewById(R.id.IDText);
+ nameText = (EditText) findViewById(R.id.nameText);
+ phoneText = (EditText) findViewById(R.id.phoneText);
+ ```
+
+ Next, create a `save()` method. You should also associate this method with the 'save' button in activity_main.xml.
+
+ ```java
+ public void save(View v){
+ int anID = Integer.parseInt(idText.getText().toString());
+ String aName = nameText.getText().toString();
+ String aPhone = phoneText.getText().toString();
+ DatabaseHandler db = new DatabaseHandler(this);
+ db.addContact(new Contact(anID, aName, aPhone));
+ }
+ ```
+
+If you run this app in an AVD and insert some texts and click save, what you'll see is that there's a log entry produced:
+
+
+
+`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'`'. .'(a beautiful divider)
+ ` ` ` ` ` ` ` ` ` `
+
+
+
+### Verify the results
+
+Open the Android Device Monitor, locate the SQLite database you just created. Export this file to your hard drive.
+
+
+
+Next, download and install a tool called [SQLiteStudio](https://sqlitestudio.pl). Once installed, load your database in it. What you'll see is that the data you typed are actually being saved.
+
+Now you have finished database insertion. The rest of the CRUD operation follow exactly the same routes. With the help of [the official documentation of SQLiteDatabase class](https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html), try to implement 'read', 'update' and 'delete'.
+
+
+
+
diff --git a/Week_07_Testing/.md_images/create.png b/Week_07_Testing/.md_images/create.png
new file mode 100644
index 0000000..9824592
Binary files /dev/null and b/Week_07_Testing/.md_images/create.png differ
diff --git a/Week_07_Testing/.md_images/export.png b/Week_07_Testing/.md_images/export.png
new file mode 100644
index 0000000..552174c
Binary files /dev/null and b/Week_07_Testing/.md_images/export.png differ
diff --git a/Week_07_Testing/.md_images/folder.png b/Week_07_Testing/.md_images/folder.png
new file mode 100644
index 0000000..4f72f53
Binary files /dev/null and b/Week_07_Testing/.md_images/folder.png differ
diff --git a/Week_07_Testing/.md_images/goto.png b/Week_07_Testing/.md_images/goto.png
new file mode 100644
index 0000000..1a7007a
Binary files /dev/null and b/Week_07_Testing/.md_images/goto.png differ
diff --git a/Week_07_Testing/.md_images/html.png b/Week_07_Testing/.md_images/html.png
new file mode 100644
index 0000000..7000424
Binary files /dev/null and b/Week_07_Testing/.md_images/html.png differ
diff --git a/Week_07_Testing/.md_images/instrumented.png b/Week_07_Testing/.md_images/instrumented.png
new file mode 100644
index 0000000..228e0dd
Binary files /dev/null and b/Week_07_Testing/.md_images/instrumented.png differ
diff --git a/Week_07_Testing/.md_images/log.png b/Week_07_Testing/.md_images/log.png
new file mode 100644
index 0000000..3fba9ee
Binary files /dev/null and b/Week_07_Testing/.md_images/log.png differ
diff --git a/Week_07_Testing/.md_images/new.png b/Week_07_Testing/.md_images/new.png
new file mode 100644
index 0000000..e2b4e67
Binary files /dev/null and b/Week_07_Testing/.md_images/new.png differ
diff --git a/Week_07_Testing/.md_images/runResults.png b/Week_07_Testing/.md_images/runResults.png
new file mode 100644
index 0000000..202a10a
Binary files /dev/null and b/Week_07_Testing/.md_images/runResults.png differ
diff --git a/Week_07_Testing/.md_images/sample.png b/Week_07_Testing/.md_images/sample.png
new file mode 100644
index 0000000..20817fe
Binary files /dev/null and b/Week_07_Testing/.md_images/sample.png differ
diff --git a/Week_07_Testing/.md_images/test-types_2x.png b/Week_07_Testing/.md_images/test-types_2x.png
new file mode 100644
index 0000000..0a374aa
Binary files /dev/null and b/Week_07_Testing/.md_images/test-types_2x.png differ
diff --git a/Week_07_Testing/.md_images/testclass.png b/Week_07_Testing/.md_images/testclass.png
new file mode 100644
index 0000000..c8a301e
Binary files /dev/null and b/Week_07_Testing/.md_images/testclass.png differ
diff --git a/Week_07_Testing/.md_images/toolbar.png b/Week_07_Testing/.md_images/toolbar.png
new file mode 100644
index 0000000..9fb5834
Binary files /dev/null and b/Week_07_Testing/.md_images/toolbar.png differ
diff --git a/Week_07_Testing/.md_images/unitresult.png b/Week_07_Testing/.md_images/unitresult.png
new file mode 100644
index 0000000..10a8753
Binary files /dev/null and b/Week_07_Testing/.md_images/unitresult.png differ
diff --git a/Week_07_Testing/MySQLiteTest/.gitignore b/Week_07_Testing/MySQLiteTest/.gitignore
new file mode 100644
index 0000000..39fb081
--- /dev/null
+++ b/Week_07_Testing/MySQLiteTest/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Week_07_Testing/MySQLiteTest/.idea/compiler.xml b/Week_07_Testing/MySQLiteTest/.idea/compiler.xml
new file mode 100644
index 0000000..32b8ce7
--- /dev/null
+++ b/Week_07_Testing/MySQLiteTest/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/MySQLiteTest/.idea/copyright/profiles_settings.xml b/Week_07_Testing/MySQLiteTest/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..7d61b5c
--- /dev/null
+++ b/Week_07_Testing/MySQLiteTest/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Week_07_Testing/MySQLiteTest/.idea/gradle.xml b/Week_07_Testing/MySQLiteTest/.idea/gradle.xml
new file mode 100644
index 0000000..c3b1da4
--- /dev/null
+++ b/Week_07_Testing/MySQLiteTest/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_07_Testing/NavigationDrawerTest/.idea/modules.xml b/Week_07_Testing/NavigationDrawerTest/.idea/modules.xml
new file mode 100644
index 0000000..9ed6641
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week_07_Testing/NavigationDrawerTest/.idea/runConfigurations.xml b/Week_07_Testing/NavigationDrawerTest/.idea/runConfigurations.xml
new file mode 100644
index 0000000..9b6e38d
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/.gitignore b/Week_07_Testing/NavigationDrawerTest/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Week_07_Testing/NavigationDrawerTest/app/build.gradle b/Week_07_Testing/NavigationDrawerTest/app/build.gradle
new file mode 100644
index 0000000..f007dcd
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/build.gradle
@@ -0,0 +1,42 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 24
+ buildToolsVersion '25.0.0'
+ defaultConfig {
+ applicationId "com.example.jianhuayang.navigationdrawer"
+ minSdkVersion 15
+ targetSdkVersion 24
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+
+ androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
+ exclude group: 'com.android.support'
+ }
+// http://stackoverflow.com/questions/36065027/appcompat-library-23-2-1-not-working-with-espresso-v2-2-2
+
+ compile 'com.android.support:appcompat-v7:24.2.1'
+ compile 'com.android.support:design:24.2.1'
+ compile 'com.android.support:support-v4:24.2.1'
+ testCompile 'junit:junit:4.12'
+
+ androidTestCompile 'com.android.support:support-annotations:24.2.1'
+ androidTestCompile 'com.android.support.test:runner:0.5'
+ androidTestCompile 'com.android.support.test:rules:0.5'
+ androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/proguard-rules.pro b/Week_07_Testing/NavigationDrawerTest/app/proguard-rules.pro
new file mode 100644
index 0000000..cce7213
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/jianhuayang/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/androidTest/java/com/example/jianhuayang/navigationdrawer/EspressoTest.java b/Week_07_Testing/NavigationDrawerTest/app/src/androidTest/java/com/example/jianhuayang/navigationdrawer/EspressoTest.java
new file mode 100644
index 0000000..873fd15
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/androidTest/java/com/example/jianhuayang/navigationdrawer/EspressoTest.java
@@ -0,0 +1,45 @@
+package com.example.jianhuayang.navigationdrawer;
+
+import android.support.test.espresso.contrib.DrawerActions;
+import android.support.test.filters.SmallTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+//import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Created by jianhuayang on 09/12/2016.
+ */
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class EspressoTest {
+
+ @Rule
+ public ActivityTestRule activityTestRule = new ActivityTestRule<>(
+ MainActivity.class);
+
+ @Test
+ public void clickButton() {
+ onView(withId(R.id.f1)).perform(click());
+ onView(withText("f2")).check(matches(isDisplayed()));
+ }
+
+ @Test
+ public void openDrawer() {
+ onView(withId(R.id.drawer_layout)).perform(DrawerActions.open());
+ onView(withText("Swap")).perform(click());
+ onView(withText("f2")).check(matches(isDisplayed()));
+ }
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/androidTest/java/com/example/jianhuayang/navigationdrawer/ExampleInstrumentedTest.java b/Week_07_Testing/NavigationDrawerTest/app/src/androidTest/java/com/example/jianhuayang/navigationdrawer/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..a547452
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/androidTest/java/com/example/jianhuayang/navigationdrawer/ExampleInstrumentedTest.java
@@ -0,0 +1,28 @@
+package com.example.jianhuayang.navigationdrawer;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.jianhuayang.navigationdrawer", appContext.getPackageName());
+ }
+
+
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/AndroidManifest.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..dbbecaa
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/Fragment1.java b/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/Fragment1.java
new file mode 100644
index 0000000..8e2a5bb
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/Fragment1.java
@@ -0,0 +1,39 @@
+package com.example.jianhuayang.navigationdrawer;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class Fragment1 extends Fragment {
+
+
+ public Fragment1() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_f1, container, false);
+ Button button = (Button) view.findViewById(R.id.f1);
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.frame, new
+ Fragment2()).commit();
+ }
+ });
+
+ // Inflate the layout for this fragment
+ return view;
+ }
+
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/Fragment2.java b/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/Fragment2.java
new file mode 100644
index 0000000..0d3e169
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/Fragment2.java
@@ -0,0 +1,29 @@
+package com.example.jianhuayang.navigationdrawer;
+
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+
+/**
+ * A simple {@link Fragment} subclass.
+ */
+public class Fragment2 extends Fragment {
+
+
+ public Fragment2() {
+ // Required empty public constructor
+ }
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_f2, container, false);
+ }
+
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/MainActivity.java b/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/MainActivity.java
new file mode 100644
index 0000000..1f38388
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/java/com/example/jianhuayang/navigationdrawer/MainActivity.java
@@ -0,0 +1,107 @@
+package com.example.jianhuayang.navigationdrawer;
+
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.Snackbar;
+import android.view.View;
+import android.support.design.widget.NavigationView;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class MainActivity extends AppCompatActivity
+ implements NavigationView.OnNavigationItemSelectedListener {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+ }
+ });
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+ drawer.setDrawerListener(toggle);
+ toggle.syncState();
+
+ NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+
+ getSupportFragmentManager().beginTransaction().replace(R.id.frame, new Fragment1()).commit();
+ }
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_settings) {
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+ // Handle navigation view item clicks here.
+ int id = item.getItemId();
+
+ if (id == R.id.nav_camera) {
+ // Handle the camera action
+ } else if (id == R.id.nav_gallery) {
+
+ } else if (id == R.id.nav_slideshow) {
+
+ } else if (id == R.id.nav_manage) {
+
+ } else if (id == R.id.nav_share) {
+
+ } else if (id == R.id.nav_send) {
+
+ } else if (id == R.id.swap) {
+ getSupportFragmentManager().beginTransaction().replace(R.id.frame, new Fragment2()).commit();
+
+
+ }
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+ return true;
+ }
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_camera.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_camera.xml
new file mode 100644
index 0000000..7d1c583
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_camera.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_gallery.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_gallery.xml
new file mode 100644
index 0000000..2f2ca2a
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_gallery.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_manage.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_manage.xml
new file mode 100644
index 0000000..fc1e13a
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_manage.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_send.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_send.xml
new file mode 100644
index 0000000..a554657
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_send.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_share.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_share.xml
new file mode 100644
index 0000000..8151b38
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_share.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_slideshow.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_slideshow.xml
new file mode 100644
index 0000000..e750991
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable-v21/ic_menu_slideshow.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable/side_nav_bar.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable/side_nav_bar.xml
new file mode 100644
index 0000000..327b7aa
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/drawable/side_nav_bar.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/activity_main.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..4951cf2
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/app_bar_main.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/app_bar_main.xml
new file mode 100644
index 0000000..983869e
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/app_bar_main.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/content_main.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/content_main.xml
new file mode 100644
index 0000000..9bf8df6
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/content_main.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/fragment_f1.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/fragment_f1.xml
new file mode 100644
index 0000000..e158578
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/fragment_f1.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/fragment_f2.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/fragment_f2.xml
new file mode 100644
index 0000000..f56d1a4
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/fragment_f2.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/nav_header_main.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/nav_header_main.xml
new file mode 100644
index 0000000..e3e3646
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/layout/nav_header_main.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/menu/activity_main_drawer.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/menu/activity_main_drawer.xml
new file mode 100644
index 0000000..424562d
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/menu/activity_main_drawer.xml
@@ -0,0 +1,39 @@
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/menu/main.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/menu/main.xml
new file mode 100644
index 0000000..b62455b
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/menu/main.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-hdpi/ic_launcher.png b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-mdpi/ic_launcher.png b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values-v21/styles.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..dbbdd40
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values-w820dp/dimens.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/colors.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/dimens.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..c2effc5
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 160dp
+
+ 16dp
+ 16dp
+ 16dp
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/drawables.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/drawables.xml
new file mode 100644
index 0000000..52c6a6c
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/drawables.xml
@@ -0,0 +1,8 @@
+
+ @android:drawable/ic_menu_camera
+ @android:drawable/ic_menu_gallery
+ @android:drawable/ic_menu_slideshow
+ @android:drawable/ic_menu_manage
+ @android:drawable/ic_menu_share
+ @android:drawable/ic_menu_send
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/strings.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..94cfac2
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+ Navigation Drawer
+
+ Open navigation drawer
+ Close navigation drawer
+
+ Settings
+
+
+ Hello blank fragment
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/styles.xml b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..177cefc
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week_07_Testing/NavigationDrawerTest/app/src/test/java/com/example/jianhuayang/navigationdrawer/ExampleUnitTest.java b/Week_07_Testing/NavigationDrawerTest/app/src/test/java/com/example/jianhuayang/navigationdrawer/ExampleUnitTest.java
new file mode 100644
index 0000000..b064350
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/app/src/test/java/com/example/jianhuayang/navigationdrawer/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jianhuayang.navigationdrawer;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/build.gradle b/Week_07_Testing/NavigationDrawerTest/build.gradle
new file mode 100644
index 0000000..c2eea8e
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/Week_07_Testing/NavigationDrawerTest/gradle.properties b/Week_07_Testing/NavigationDrawerTest/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/Week_07_Testing/NavigationDrawerTest/gradle/wrapper/gradle-wrapper.jar b/Week_07_Testing/NavigationDrawerTest/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/Week_07_Testing/NavigationDrawerTest/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Week_07_Testing/NavigationDrawerTest/gradle/wrapper/gradle-wrapper.properties b/Week_07_Testing/NavigationDrawerTest/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..7dffa4a
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Nov 13 23:49:25 GMT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/Week_07_Testing/NavigationDrawerTest/gradlew b/Week_07_Testing/NavigationDrawerTest/gradlew
new file mode 100644
index 0000000..9d82f78
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/Week_07_Testing/NavigationDrawerTest/gradlew.bat b/Week_07_Testing/NavigationDrawerTest/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Week_07_Testing/NavigationDrawerTest/settings.gradle b/Week_07_Testing/NavigationDrawerTest/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/Week_07_Testing/NavigationDrawerTest/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/Week_07_Testing/README.md b/Week_07_Testing/README.md
new file mode 100644
index 0000000..e088b01
--- /dev/null
+++ b/Week_07_Testing/README.md
@@ -0,0 +1,594 @@
+# Testing
+
+When you create your apps, you need to make sure it works as expected. You have used `Log.d()` to produce some results for inspection. What you can also do is to use the [Assert](http://developer.android.com/reference/junit/framework/Assert.html) class. But to test properly, you need to write testing classes.
+
+
+
+
+As a simple example, consider the following class (sourcecode from [JUnit introduction](https://github.com/junit-team/junit/wiki/Getting-started))
+
+```java
+public class Calculator {
+ public int evaluate(String expression) {
+ int sum = 0;
+ for (String summand: expression.split("\\+"))
+ sum += Integer.valueOf(summand);
+ return sum;
+ }
+}
+```
+
+To check if it works properly or not you will need to try it out. Put simply, you need to run the class with some string inputs such as `"1+2+3"` and see if the output is `6`. Put this in the context of JUnit testing, you have
+
+```java
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class CalculatorTest {
+ @Test
+ public void evaluatesExpression() {
+ Calculator calculator = new Calculator();
+ int sum = calculator.evaluate("1+2+3");
+ assertEquals(6, sum);
+ }
+}
+```
+
+This explains the idea of testing. Instead of JUnit, you can find other tools/packages available for Java. But JUnit is what you need for Android.
+
+> Android uses JUnit 4 (the latest version is 5), but some online tutorials still use JUnit 3. A lot of syntax between the two versions are the same. But the differences are also huge. The most noticeable difference is the use of annotations in JUnit 4 such as `@Before` and `@after` in replacement of `setup()` and `tearDown()` in JUnit 3. Click to read a nice blog on [JUnit 4 annotations](http://javarevisited.blogspot.co.uk/2012/06/junit4-annotations-test-examples-and.html). Some tutorials use `@Before setup()` in the code. Once you see this you know straightaway it's JUnit 4. Here `setup()` is just a name, not an overriding method anymore.
+
+## Lab 1 Unit testing
+
+There're two types of testing in Android depending on whether an Android device (physical or AVD) is needed or not:
+
+1. Local unit tests run on a local JVM on your development machine, and doesn't require Android devices;
+2. The other type of testing is called instrumented testing, which requires an Android device, as will be discussed later.
+
+At runtime, local unit tests will be executed against a modified version of android.jar where all final modifiers have been stripped off. For more info on this, read [the official Android user guide on testing](https://developer.android.com/studio/test/index.html).
+
+
+
+
+
+### Default app and default tests
+
+Let's have a look at the default tests generated by Android Studio
+
+1. Create a new project called 'My Tests' using all default options.
+2. In the Project tool window, click on app ==> java. You'll see there're three sub-folders (packages) and each has an auto-generated class
+
+ 
+
+ As you know already, Gradle uses conventions to build the system. The convention used here is:
+ * Your 'main' codes and resources are saved in a folder called 'app/src/main'.
+ * Your local unit tests are saved in a folder called 'app/src/test'.
+ * Your instrumentation tests are saved in a folder called 'app/src/androidTest'.
+
+ 
+
+3. Double-click to open ExampleUnitTests.java, what you'll see is the following
+
+ ```java
+ import org.junit.Test;
+ import static org.junit.Assert.*;
+
+ public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+ }
+ ```
+
+ Note the use of JUnit classes. Also, note here it uses `import static` statement to import static members.
+
+4. Right-click on ExampleUnitTest and select Run 'ExampleUnitTest'.
+
+5. Now your Run tool window will look similar to this
+
+ 
+
+ * The color of the status bar indicates whether the tests have passed successfully. Green for pass, red for fail.
+ * The left-hand pane shows the tree view of all tests within the current run/debug configuration.
+ * The toolbar provides controls that enable you to monitor the tests and analyze results. Notice the export icon (the one to the right of down-arrow), if you click it you'll be able to export the test results.
+
+ 
+
+
+
+Now you have just finished your first ever tests!
+
+### The 'Deadline' app
+
+To do some testing exercises, you will need to have a simple app. Here you create an app that calculates time left until 300CEM assignment deadline. The idea of the app is that given the current date in the format of dd/mm/yy, the app should
+
+* Display how many days left until coursework submission once you click 'Update'.
+* Save the current date to SharedPreferences once you click 'Save'.
+* Send current date to new activity once you click 'Send'.
+
+Follow steps below to create the app.
+
+1. Open activity_main.xml, replace the ConstraintLayout with a vertical LinearLayout. Delete the auto-generated TextView and insert the following:
+
+ ```xml
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+2. Create a new Deadline class, and insert the following into Deadline.java
+
+ ```java
+ import java.text.DateFormat;
+ import java.text.ParseException;
+ import java.text.SimpleDateFormat;
+ import java.util.Date;
+
+ public class Deadline {
+ private Date date;
+ private Context context;
+ private static DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
+ private static final String DATE_KEY = "dateKey";
+
+ public Deadline(String date, Context context) {
+ try {
+ this.date = dateFormat.parse(date);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ this.context = context;
+ }
+
+ public Deadline(String date) {
+ try {
+ this.date = dateFormat.parse(date);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public int calculate() {
+ Date submission;
+ try {
+ submission = dateFormat.parse("12/12/17");
+ return (int) ((submission.getTime() - date.getTime() )/ (1000 * 60 * 60 * 24));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }
+
+ public boolean save() {
+ SharedPreferences sharedPreferences = ((Activity)context).getPreferences(Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString(DATE_KEY, dateFormat.format(date));
+ return editor.commit();
+ }
+ }
+ ```
+
+ This class has two methods. The `calculate()` method calculates the time difference in days between the input and the submission deadline which is 12/12/17. The `save()` method save the date data in a SharedPreferences xml file.
+
+3. Open MainActivity.java, insert the following into the class:
+
+ ```java
+ private TextView textView;
+ private EditText editText;
+ private Deadline deadline;
+ public static final String DAYS_KEY = "DAYS_KEY";
+
+ public void onUpdateClick(View v){
+ deadline = new Deadline(editText.getText().toString(), this);
+ textView.setText(deadline.calculate() + " days to 300CEM deadline!");
+ }
+
+ public void onSaveClick(View v){
+ deadline = new Deadline(editText.getText().toString(), this);
+ deadline.save();
+ }
+
+ public void onSendClick(View v){
+ deadline = new Deadline(editText.getText().toString(), this);
+ Intent intent = new Intent(this, DisplayActivity.class);
+ intent.putExtra(DAYS_KEY, deadline.calculate());
+ startActivity(intent);
+ }
+ ```
+
+ Insert the following into `onCreate()` method:
+
+ ```java
+ editText = (EditText) findViewById(R.id.editText);
+ textView = (TextView) findViewById(R.id.textView);
+ ```
+
+4. Create a new empty Activity called DisplayActivity. Insert the following into the RelativeLayout in activity_display.xml
+
+ ```xml
+
+ ```
+
+5. Open DisplayActivity.java, insert the following code into the `onCreate()` method, just below `setContentView()`
+
+ ```java
+ TextView textView = (TextView) findViewById(R.id.textView);
+ Intent intent = getIntent();
+ int daysLeft = intent.getIntExtra(MainActivity.DAYS_KEY, 0);
+ textView.setText(Integer.toString(daysLeft + 19) + " days until 2018!" );
+ ```
+
+### Local unit tests
+
+The critical part of the app above is the capability to calculate time differences. Now let's design a test for this.
+
+1. Open Deadline.java, navigate your cursor to be within the class body, right-click and select Go To ==> Test.
+
+ 
+
+2. In the window that pops up, select Create New Test. Then in the Create Test window check the 'calculate()' checkbox, click OK.
+
+ 
+
+3. Choose the 'test' folder in the Directory Structure tab, and click OK. You just created a testing class for Deadline, and this new class appears in the test package.
+
+ 
+
+4. Insert the following into `calculate()`
+
+ ```java
+ Deadline deadline = new Deadline("11/12/17");
+ assertEquals(deadline.calculate(), 1);
+ ```
+
+ Now your DeadlineTest class looks like the following:
+
+ ```java
+ public class DeadlineTest {
+ @Test
+ public void calculate() throws Exception {
+ Deadline deadline = new Deadline("12/12/16");
+ assertEquals(deadline.calculate(), 1);
+ }
+ }
+ ```
+
+ The test itself is a public class. Here it uses an annotation to mark the actual test to run, which is a member method in that class. It then simply declares a new instance of the class that the calculation result is known already.
+
+5. If you right-click on the DeadlineTest in Project tool window and choose Run 'DeadlineTest', you'll see something similar to below:
+
+ 
+
+ The test runs on local JVMs and finishes without any error. If you change assertion to `assertEquals(deadline.calculate(), 2)` and run it, what happens?
+
+### Local mocked unit tests
+
+The test you did above used the Deadline constructor that doesn't require the Context input parameter. This is because Context is Android dependent you cannot run a test on local JVMs. The way to get around this, i.e. to test Android SDK dependent code, is to use a mocking framework called Mockito.
+
+1. Open build.gradle (Project: MyTests), make changes to `repositories` block so it becomes. See official document on [Support Library Setup](https://developer.android.com/topic/libraries/support-library/setup.html)
+
+ ```xml
+ allprojects {
+ repositories {
+ jcenter()
+ maven {
+ url "https://maven.google.com"
+ }
+ }
+ }
+ ```
+
+
+1. Open build.gradle (Module: app), insert Mockito and Hamcrest dependencies into the dependencies configuration block (after line `testCompile 'junit:junit:4.12'` if exists already)
+
+ ```xml
+ testCompile 'junit:junit:4.12'
+ testCompile 'com.android.support:support-annotations:26.1.0'
+ testCompile 'com.android.support.test:rules:0.5'
+ testCompile 'org.mockito:mockito-core:1.10.19'
+ testCompile 'org.hamcrest:hamcrest-library:1.3'
+ ```
+
+ Mockito is a mocking framework, and Hamcrest is a package to make testing more readable. You'll see both later. Click 'Sync Now' after making changes.
+
+2. Modify your DeadlineTest.java so it looks like the following
+
+ ```java
+ @SmallTest
+ @RunWith(MockitoJUnitRunner.class)
+ public class DeadlineTest {
+
+ @Mock
+ Context context;
+
+ @Mock
+ Activity activity;
+
+ @Mock
+ SharedPreferences sharedPreferences;
+
+ @Mock
+ SharedPreferences.Editor editor;
+
+ private Deadline deadline;
+
+ @Test
+ public void testCalculate() throws Exception {
+ Deadline localDeadline = new Deadline("11/12/17");
+ assertEquals(localDeadline.calculate(), 1);
+
+ }
+
+ @Test
+ public void testCalculate2() throws Exception {
+ Deadline anotherDeadline = new Deadline("10/12/17", context);
+ assertThat("check if time interval is calculated properly", anotherDeadline.calculate(), is(equalTo(2)));
+
+ }
+
+ @Before
+ public void initTests() {
+ deadline = new Deadline("10/12/17", activity);
+ }
+
+ @Test
+ public void testSave() throws Exception {
+
+ when(activity.getPreferences(Context.MODE_PRIVATE)).thenReturn(sharedPreferences);
+ when(sharedPreferences.edit()).thenReturn(editor);
+ when(editor.commit()).thenReturn(true);
+ assertThat(deadline.save(), is(true));
+ }
+ }
+ ```
+
+ There're quite a lot going on here:
+ * `@SmallTest` is a way to classify different tests, as you might have guessed, so later on tests can be grouped using filters for example SmallTests only. However, unfortunately, it's not very clear from Android Studio documentation how this can be done through GUI. Instructions using command line options can be found on [Test from the Command Line](https://developer.android.com/studio/test/command-line.html) manual page.
+
+
+ * `@RunWith` line specifies the Runner of the current testing class. A Runner is merely another class that is designed to perform some specific functions. The default runner in the current project is configured in 'build.gradle(Module:app)' file using the following line. However, for this current class, MockitoJUnitRunner will mock our dependencies in Android system.
+
+ ```xml
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ ```
+
+
+
+ * `@Mock` line indicates a variable is being mocked. When being mocked, all methods of the class throw exceptions. This is because the android.jar file that is used to run unit tests does not contain any actual code.
+
+ * `@Before` line indicates the code block will be invoked before each test. You should use this annotation to specify a block of code with test setup operations. Strictly speaking, you should use `@BeforeClass` here to initialize a static variable, but since it's a small test after all it won't make much difference.
+
+ * In `testSave()` method there is `when().thenReturn()` to mock the behavior of mocked classes. This is because context/activity etc. are all mocked objects, which don't contain any actual methods. You'll need to supply some results once these methods are called. The purpose of this test is to demo `when().thenReturn()` method. However, because of the way the test is designed, this is guaranteed to pass.
+ * Note in line `assertThat("check if time interval is calculated properly", deadline.calculate(), is(equalTo(2)))` we used `assertThat`, `is` and `equalTo` from Hamcrest to increase readability. But this is essentially the same as `assertEquals(deadline.calculate(), 2)`. Here `is` and `equalTo` are both matchers.
+
+3. Right-click and run DeadlineTest, then export the results to HTML. Locate and open that HTML file, you'll see something similar to below:
+
+ 
+
+## Lab 2 Instrumented testing
+
+Tests you've done so far run on local JVM and don't require Android devices, neither real nor virtual. If you need to access Android system resources such as Context you need to test your app on an actual device or AVD. This type of tests is called Instrumented tests.
+
+### Instrumented unit tests
+
+Follow steps below to create an instrumented unit test:
+
+1. Duplicate the MyTests project created earlier and name the new project MyTests2, and open this new project in Android Studio. By default, the system generates an instrumented test class already called ExampleInstrumentedTest. In the Project tool window, locate this ExampleInstrumentedTest class and right-click on it, select Run 'ExampleInstrumentedT...' you'll see in the Run tool window it shows you a message saying 'All Tests Passed'.
+
+ 
+
+2. open build.gradle (Module: app) file, insert following androidTestCompile dependencies into the dependencies block
+
+ ```xml
+ androidTestCompile 'com.android.support:support-annotations:26.1.0'
+ androidTestCompile 'com.android.support.test:runner:0.5'
+ androidTestCompile 'com.android.support.test:rules:0.5'
+ androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
+ ```
+
+ Note in the above the version number of `'com.android.support:support-annotations:26.1.0'` i.e. 26.1.0 must match that of your support library i.e. `compile 'com.android.support:appcompat-v7:26.1.0'`.
+
+ In previous exercises on 'unit test' you inserted dependency configurations for testCompile. So what are the differences between testCompile and androidTestCompile? Simply testCompile is the configuration for unit tests (those located in src/test) and androidTestCompile is used for the test API (that located in src/androidTest).
+
+
+
+3. Double check that you have the following line in the defaultConfig block
+
+ ```xml
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ ```
+
+3. Right-click on the androidTest package and create a new class called InstrumentedDeadlineTest
+
+ 
+
+4. Open InstrumentedDeadlineTest.java, replace contents with the following
+
+ ```java
+ @RunWith(AndroidJUnit4.class)
+ @SmallTest
+ public class InstrumentedDeadlineTest {
+
+ private Deadline deadline;
+
+ @Before
+ public void initTests() {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ deadline = new Deadline("04/12/17", context);
+ }
+
+ @Test
+ public void testCalculate() {
+ Log.d("actual_results", Integer.toString(deadline.calculate()));
+ assertThat(deadline.calculate(), is(equalTo(8)));
+ }
+
+ }
+ ```
+
+ As you can see you don't need to mock anything anymore. You can use system resources such as `InstrumentationRegistry` and `Log`. Basically, Android instrumentation is a set of control methods or 'hooks' in the Android system. With Android instrumentation, you can invoke for example activity callback methods in your test code. This gives you fine control of everything. For more details on instrumentation, read this [Android docs backed up by MIT](https://stuff.mit.edu/afs/sipb/project/android/docs/tools/testing/testing_android.html#Instrumentation).
+
+ However, remember instrumented tests are still unit tests, which means the system doesn't start the actual app and so it doesn't have access to things like activity methods such as `findViewById()`. Another thing to note here is that AndroidJUnit4.class is an [aliase of the current default Android JUnit 4 class runner for future-proofing](https://developer.android.com/reference/android/support/test/runner/AndroidJUnit4.html). That means at this moment (until the adaption of JUnit 5 in Android) you can safely delete line `@RunWith(AndroidJUnit4.class)` and your code will still run.
+
+5. If you right-click the class and run, you'll see that all tests are passed. In addition, in the logcat tool window, you'll see the actual log message.
+
+ 
+
+ You've probably noticed that instrumented tests run slower than local JUnit tests that run on JVM. This is one of the advantages of local unit tests.
+
+### UI testing using Espresso
+
+The Espresso testing framework, provided by the Android Testing Support Library, provides APIs for writing UI tests to simulate user interactions within a single target app. One advantage of Espresso is that it detects when the main thread is idle, so it is able to run your test commands at the appropriate time, improving the reliability of your tests. In addition, with the help of tools such as Espresso , developer rarely has to use the instrumentation API directly.
+
+
+Follow steps below to create a UI test:
+
+1. Create a new class in the androidTest package and name it EspressoTest.
+2. Replace the class body in EspressoTest.java with the following:
+
+ ```java
+ @RunWith(AndroidJUnit4.class)
+ @SmallTest
+ public class EspressoTest {
+
+ @Rule
+ public ActivityTestRule activityTestRule = new ActivityTestRule<>(
+ MainActivity.class);
+
+ @Test
+ public void changeText_sameActivity() {
+ onView(withId(R.id.editText)).perform(typeText("11/12/17"), closeSoftKeyboard());
+ onView(withId(R.id.buttonUpdate)).perform(click());
+ onView(withId(R.id.textView)).check(matches(withText("1 days to 300CEM deadline!")));
+ }
+
+ @Test
+ public void changeText_newActivity() {
+ onView(withId(R.id.editText)).perform(typeText("12/12/17"), closeSoftKeyboard());
+ onView(withId(R.id.buttonSend)).perform(click());
+ onView(withId(R.id.textView)).check(matches(withText("18 days until 2017!")));
+ }
+ }
+ ```
+
+ `@Rule` defines a customized set of actions to take. `@Rule` is similar to `@Before` but more powerful. In our case, ActivityTestRule enables the start of MainActivity class. This essentially starts the app when you run the test class.
+
+ Typical uses of espresso is `onView(withId(R.id.my_view)).perform(click()).check(matches(isDisplayed()))`. Here in `changeText_sameActivity()` we perform text inputs and check calculation results; in `changeText_newActivity()` we check if data is passed between activities and displayed correctly.
+
+3. If you run this test class you'll see that your device briefly shows up the app as if someone is using it. When the test finishes it'll reverse to the previous state.
+
+
+
+
+
+
+